관리 메뉴

ㄴrㅎnㅂrㄹrㄱi

[강좌 19] 초기화 파일 본문

API 관련/API 강좌모음

[강좌 19] 초기화 파일

님투 2007. 10. 26. 03:43
반응형

[API]강좌(19)<--초기화 파일





초기화 파일에 대해 알아 보겠습니다. 윈도우즈에서 예기하는 초기화
파일은 win.ini, system.ini 파일을 의미하는데 한번 여러분들의 win.ini 파일을
보도록 하십시요. 보통 이 win.ini 파일에 프로그램이 설치된 디렉토리명이 지정
되어 있는 경우가 많습니다. 제 win.ini 파일의 내용중 일부를 보도록 할까요?
[DORAN 20]
PROGRAM=c:\win-app\doran20
[HNC]
HNC=D:\WIN-APP\HNC\
HNCUSER=D:\WIN-APP\HNC\USER\
[BCW4.0 INSTALL]
Reserved1=D:\language\BC45
보면 알겠지만 프로그램이 설치되어 있는 디렉토리 정보가 있음을 확인할수 있습
니다. 여기서 용어 한가지 알아 봅시다. 우선 []로 묶여있는 "DORAN 20"을 섹션
이라고 말을 합니다. 그리고 그 밑에 있는 PROGRAM을 키라고 하죠. 위에서 볼
수 있듯이 하나의 섹션에는 여러개의 키를 가질수 있습니다. 각 키옆에 있는 문
자열을 키값이라고 합니다. 우리는 이제 프로그램상에서 섹션을 만들고 키를
만들고 또 값도 부여할것입니다. 물론 원하는 섹션의 키에서 값도 읽어오는 것
도 구현해 볼것입니다. 그런데 왜 이 win.ini 파일에 프로그램이 설치되어 있는
정보를 기록해 놓을까요? 그것은 간단합니다. 도스에서 프로그램을 실행하면 그
실행시킨 디렉토리가 현재 디렉토리이기 때문에 프로그램에서 요구하는 데이터
파일을 그냥 열어서 정보를 가지고 와 실행이 되지만 윈도우즈는 다릅니다.
윈도우즈 프로그램을 처음 설치하게 되면 아마 폴더를 생성하고 그 폴더안에 아
이콘이 등록될것입니다. 그렇죠? 아주 간단한 프로그램이 아니라면 대부분 이
과정을 거칩니다. 그런데 만약에 이 아이콘을 데스크탑 밖으로 꺼내 놓으면 어떻
게됩니까? 꺼내는 방식도 두가지가 있습니다. 단축 아이콘으로 만드는 경우도 있
고 또는 그냥 복사해서 꺼내 놓는 경우도 있습니다. 저 같은 경우는 주로 복사해
서 꺼내 놓은데 꺼내 놓은 상태에서 프로그램을 실행하면 현재 디렉토리가 프로그
램이 설치되어 있는 디렉토리가 아닙니다. 다른 디렉토리죠. 만약에 프로그램이
설치되어 있는 디렉토리에 있는 다른 데이터 파일을 프로그램에서 요구한다면
그 파일을 어떻게 열까요? 바로 프로그램이 설치되어 있는 곳이 어딘지 알아야
열수가 있습니다. 이때 프로그램이 설치되어 있는 디렉토리가 win.ini 파일에
저장되어 있다면 그 파일에서 설치된 디렉토리를 얻어와 데이터 파일을 열면 해결
이 됩니다. 이런 이유때문에 win.ini 파일에 주로 프로그램이 설치되어 있는
디렉토리 정보를 기록하는 과정을 하는 것입니다. 물론 프로그램이 설치과정에
서 이 과정을 해 주면 됩니다.
자 그러면 win.ini 파일에 정보를 기록하고 가져오는 것을 어떻게 구현하는지
알아 보도록 합시다.
DWORD GetProfileString(
LPCTSTR lpszSection,
LPCTSTR lpszKey,
LPCTSTR lpszDefault,
LPTSTR lpszReturnBuffer,
DWORD cchReturnBuffer
);
위 함수를 이용해서 원하는 섹션의 원하는 키의 값을 가져올수 있습니다. 첫번째
파라미터에 원하는 섹션이름을 지정하면 되고 두번째 파라미터에 키를 지정하면
됩니다. 세번째 파라미터인 lpszDefault는 보통 기본값을 지정해 주면 되는데
위 함수를 이용해서 키값을 가져오는데 실패하면 이 값이 기본적으로 반환됩니다.
네번째 파라미터인 lpszReturnBuffer는 가져온 값을 저장할 버퍼를 의미하고 마
지막 파라미터는 버퍼의 크기를 의미합니다.
자 그러면 다른 함수 하나 더 알아 보죠. 예를들어 키값이 숫자라고 가정합시다.
물론 저장할때에는 문자열로 저장하지만 우리가 이 값을 가지고 와 처리할때에는
숫자가 필요하다면 키값을 가지고 와 다시 숫자 형태로 자료를 변환시켜야 할겁니
다. 이런한 불편을 없애고자 윈도우즈에서는 아래의 함수를 제공합니다.
UINT GetProfileInt(
LPCTSTR lpszSection,
LPCTSTR lpszKey,
INT dwDefault
);
바로 리턴되는 값이 숫자가 되죠. 첫번째 파라미터에는 섹션 이름을 지정해 주면
되고 두번째 파라미터에는 키를 세번째 파라미터에는 기본값을 지정해 주면 됩니
다. 이 기본값이 무엇을 의미하는지는 알고 있겠죠?
정보를 가져오는 함수를 알아 보았으니 기록하는 함수를 알아 봅시다. 먼저 섹
션과 키를 기록하는 함수입니다.
BOOL WriteProfileSection(
LPCTSTR lpszSection,
LPCTSTR lpszKeysAndValues
);
첫번째 파라미터에 섹션을 지정해 주고 두번째 파라미터에 키를 지정해 주면 됩니
다.
이번에는 값을 지정해 주는 함수입니다.
BOOL WriteProfileString(
LPCTSTR lpszSection,
LPCTSTR lpszKey,
LPCTSTR lpszString
);
첫번째 파라미터는 섹션을 지정하면 되고 두번째 파라미터에는 키를 지정해 주면 됩
니다. 마지막 파라미터에 값을 지정하면 되구요.
자 그러면 위에서 알아본 네개의 함수를 이용해서 프로그램을 만들어 봅시다.
MyMenu MENU
BEGIN
POPUP "&Init File"
BEGIN
MENUITEM "&Get String", 100
MENUITEM "&Get Interger", 200
MENUITEM SEPARATOR
MENUITEM "&Set Init File", 300
MENUITEM"Get &Init File", 400
END
END
#include <windows.h>
#include <string.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain
(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
static char szAppName[] = "File & Directory Example";
HWND hWnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = "MyMenu";
WndClass.lpszClassName = szAppName;
if(!RegisterClass(&WndClass))
return FALSE;
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int nBuff;
char szBuff[80], szBuffer[256];
switch(message)
{
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
GetProfileString("mci extensions", "wav",
"ERROR", szBuff, 80);
sprintf(szBuffer,
"mci extensions SECTION wav KEY : %s", szBuff);
MessageBox(hWnd, szBuffer, "", MB_OK);
break;
case 200 :
nBuff = GetProfileInt("Intl", "iCountry", nBuff);
sprintf(szBuffer, "Intl SECTION iCountry KEY : %d",
nBuff);
MessageBox(hWnd, szBuffer, "", MB_OK);
break;
case 300 :
WriteProfileSection("TEST", "STR=\nINT=");
WriteProfileString("TEST", "STR", "This is Test");
WriteProfileString("TEST", "INT", "92");
break;
case 400 :
GetProfileString("TEST", "STR", "ERROR", szBuff, 80);
nBuff = GetProfileInt("TEST", "INT", nBuff);
sprintf(szBuffer, "%s : %d", szBuff, nBuff);
MessageBox(hWnd, szBuffer, "", MB_OK);
break;
}
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
위 프로그램이 어떤 역할을 하는지 알겠습니까? 메뉴 아이템중 Get String을 선택하
면 "mci extensions" 섹션의 "wav"키값을 가져와 메시지로 출력해 주고 Get
Interger를 선택하면 "Intl" 섹션의 "iCountry"키값을 가져와 메시지로 출력합니
다. 여기까지가 이미 정의 되어 있는 값을 가져오는 기능이고 Set Init File 메뉴
아이템이 선택되면 지정해준 섹션과 키값을 win.ini 파일에 기록하게 되는 것입
니다. 그리고 Get Init File 메뉴 아이템이 선택되면 그 기록한 섹션의 키값을 가
져오게 되는 거구요. 굳이 설명 드리지 않아도 이미 소스를 다 이해하셨을 것으로
믿습니다.
한가지만 설명 드리죠. 섹션과 키를 만들때 아래 처럼 사용했다는 것입니다.
WriteProfileSection("TEST", "STR=\nINT=");
키가 하나가 아닐때에는 '\n'을 사용한다는 것입니다.
 
역시 초기화 파일에 대해 알아 볼것인데 이것은 위에서 알아본 win.ini 파일
을 이용하는게 아닙니다.
바로 유저가 정의한 초기화 파일을 이용하는 거죠. 예를들어 뭐 test.ini 파일 같
은것이 되겠군요. 이러한 유저가 정의한 초기화 파일은 어디에 많이 사용할까요?
바로 인스톨 프로그램을 만들때 사용합니다. 보통 윈도우즈용 프로그램을 보면
setup.exe 파일이 존재할겁니다. 또 set.ini 파일도 존재하는 경우도 있죠. 이럴때
사용합니다. 인스톨되는 파일이 굉장히 많다면 프로그램에서 이 파일들을 직접
코딩해서 인스톨되게 하는 경우는 없습니다. 아주 무식한 방법이죠. 바로 초기화
파일에 인스톨될 파일들을 저장하고 나서 이 파일을 읽어 파일을 복사하는 과정을
취합니다. 그러면 이 유저가 정의한 초기화 파일을 어떻게 다루는지 알아 봅시다.
BOOL WritePrivateProfileSection(
LPCTSTR lpszSection,
LPCTSTR lpszKeysAndValues,
LPCTSTR lpszFile
);
앞에서 배운 WriteProfileSection() 함수와 의미가 같습니다. 단 마지막 파라미터
에 못보던것이 있군요. 이곳에 유저가 정의한 파일이름을 지정해 주면 됩니다.
BOOL WritePrivateProfileString(
LPCTSTR lpszSection,
LPCTSTR lpszKey,
LPCTSTR lpszString,
LPCTSTR lpszFile
);
앞에서 배운 WriteProfileString() 함수와 의미가 같습니다. 역시 마지막 파라미터
에 유저가 정의한 파일이름을 지정해 주면 됩니다.
DWORD GetPrivateProfileString(
LPCTSTR lpszSection,
LPCTSTR lpszKey,
LPCTSTR lpszDefault,
LPTSTR lpszReturnBuffer,
DWORD cchReturnBuffer,
LPCTSTR lpszFile
);
앞에서 배운 GetProfileString() 함수와 의미가 같습니다. 마지막 파라미터에 유저
가 정의한 파일이름을 지정해 주면 됩니다.
UINT GetPrivateProfileInt(
LPCTSTR lpszSection,
LPCTSTR lpszKey,
INT dwDefault,
LPCTSTR lpszFile
);
앞에서 배운 GetProfileInt() 함수와 의미가 같습니다. 마지막 파라미터에 유저가
정의한 파일이름을 지정해 주면 됩니다.
자 그러면 위 네개의 함수를 이용해서 프로그램을 만들어 봅시다.
MyMenu MENU
BEGIN
POPUP "&Private Init File"
BEGIN
MENUITEM "&Set Init File", 100
MENUITEM "&Get Init File", 200
END
END
#include <windows.h>
#include <string.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain
(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
static char szAppName[] = "File & Directory Example";
HWND hWnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = "MyMenu";
WndClass.lpszClassName = szAppName;
if(!RegisterClass(&WndClass))
return FALSE;
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int nBuff;
char szBuff[80], szBuffer[256];
switch(message)
{
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
WritePrivateProfileSection("TEST", "STR=\nINT=",
"e:\\test.ini");
WritePrivateProfileString("TEST", "STR",
"This is Test", "e:\\test.ini");
WritePrivateProfileString("TEST", "INT", "92",
"e:\\test.ini");
break;
case 200 :
GetPrivateProfileString("TEST", "STR","ERROR",
szBuff, 80, "e:\\test.ini");
nBuff = GetPrivateProfileInt("TEST", "INT", nBuff,
"e:\\test.ini");
sprintf(szBuffer, "%s : %d", szBuff, nBuff);
MessageBox(hWnd, szBuffer, "", MB_OK);
break;
}
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
간단하죠? 앞에서 만들어본 프로그램을 잘 이해하신분은 크게 어려운 점은 없을 겁
니다.
 
반응형

'API 관련 > API 강좌모음' 카테고리의 다른 글

[강좌 21] 그래프나 수치를 나타내는 기호  (0) 2007.10.26
[강좌 20] 메모리  (0) 2007.10.26
[강좌 18] 파일과 디렉토리  (0) 2007.10.26
[강좌 17] 폰트  (0) 2007.10.26
[강좌 16] 멀티미디어4  (0) 2007.10.26
Comments