황동준님의 윈도우 32비트 프로그래밍 46~50

  윈도우 32비트 프로그래밍 46

안녕하세요……….돌팔이 황동준입니다……………….

이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어
보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가
앞에서 배운 win.ini 파일에도 다양한 정보가 저장되어 있는데 사실 이것은 윈도우즈 3.1때와의 호환 때문에 존재하는 것이고 실제로 우리가
다루어야 할 것은 바로 이 레지스트리입니다. 음.. 예를들어서 win.ini 파일에 프로그램이 설치되어 있는 디렉토리 정보가 들어 있었죠? 아마
인스톨 쉴드라는 인스톨 툴로 인스톨 프로그램을 만들면 인스톨시에 win.ini 파일에 디렉토리 정보 저장 기능은 없을 겁니다.

그러나 레지스트리에 설치된 디렉토리를 저장할 수 있는 기능은 있죠. 바로 레지스트리에도
설치된 디렉토리 정보가 들어 있다는 말과도 같습니다. 그것 뿐만 아닙니다. PNP 하드웨어의 정보도 다 들어 있죠. 모뎀 포트를 자동으로
찾는다거나 하는 작업을 바로 이 레지스트리를 검색해서 할수 있는 것입니다. 여러분들 넷스케이프 사용해 봤습니까? 거기에 보면 홈 디렉토리를
지정할 수 있는 메뉴 아이템이 있을겁니다. MS 익스플로어의 요즘 버전은 제가 사용해 보지 않았지만 예전에 사용할 때에는 이 기능이 없더군요.
그래서 항상 홈 디렉토리가 마이크로 소프트사였습니다. 그런데 이 홈 디렉토리 정보가 레지스트리에 등록되어 있다는 것을 우연히 알게 되었습니다.
물론 그것을 바꿔서 홈 디렉토리를 바꾸었죠.

너무 서론이 길었죠? 그렇다면 이러한 레지스트리를 어떻게 원하는데로 바꿀 수 있을까요?
윈도우즈가 설치되어 있는 디렉토리에 보면 regedit.exe 파일이 있을 겁니다. 이 실행 파일을 실행시켜서 레지스트리 정보를 볼 수도 있고
또 수정할 수도 있습니다. 이 프로그램을 레지스트리 편집기라고도 하죠.

한번 실행해 보세요.

어때요? 크게 6개의 폴더가 보이죠? 각 커다란 폴더에는 의미가 있습니다.

HKEY_CLASSES_ROOT

이 하위에 있는 정보들은 문서의 형태, 파일연관상태에 대한 정보가 들어 있습니다. 실제로
하위 폴더를 보면 아래아 한글 문서의 확장자, 압축 파일 확장자들의 정보가 들어 있음을 확인할 수 있습니다.

HKEY_CURRENT_USER

각각 사용자에 따른 사용자 정보를 가지고 있습니다.

HKEY_LOCAL_MACHINE

하드웨어, 네트워크, 소프트웨어 정보가 이곳에 있습니다. 실제로 프로그램이 설치되어 있는
디렉토리, PNP 하드웨어 등록 정보들이 이곳에 있는 거죠.

HKEY_USERS

각각 사용자에 대한 시스템 정보를 가지고 있습니다.

HKEY_CURRENT_CONFIG

하드웨어 설정에 대한 정보값이 들어 있습니다.

HKEY_DYN_DATA

역시 하드웨어적인 정보값이 들어 있습니다.

자 각각에 대해 알아 보았으니 각 서브 폴더를 확인해 보시기 바랍니다. 폴더 옆에 보면
플러스 기호가 있는데 여기에 마우스의 왼쪽 버튼으로 클릭하면 마이너스 기호로 바뀌고 그곳에 속해 있는 서브 폴더를 보여주게 됩니다. 다시
클릭하면 감춰지죠. 서브 폴더를 보다보면 폴더 왼쪽에 아무 기호도 없는 폴더들이 있을 겁니다. 그것은 서브 폴더를 가지지 않음을 의미하는
것입니다. 그렇다면 서브 폴더를 가지지 않은 폴더에 클릭한 후에 오른쪽에 있는 창을 보십시요.

어때요? 네임에 어떤 이름이 있고 데이터에 값이 들어 있죠? 물론 아무 값도 가지지 않는
경우도 있습니다. 서브 풀더를 가지고 있는 것도 마찬가지입니다. 왼쪽에 있는 기호에 클릭하지 않고 바로 그 폴더를 클릭하면 네임과 데이터에 값이
표시될 것입니다.

자 새로운 용어를 알아 봅시다. 우리가 앞에서 언급한 폴더를 키라고 합니다. 각 키는 물론
서브 키를 가질 수 있고 각 키에는 네임과 데이터를 가집니다. 물론 하나의 키는 여러개의 네임과 데이터를 가질 수 있습니다. 이해가
가죠?

자 이제부터 우리는 기존에 등록되어 있는 키, 네임, 데이터를 읽는 것을 프로그램 상으로
어떻게 구현하는지 알아 볼 것입니다. 물론 등록하는 방법도 알아 볼 거구요.

그러면 시작해 봅시다.

먼저 등록되어 있는 정보를 읽어오는 방법부터 알아 봅시다. 처음에 정보를 가져올 키가 어떤
것인지 지정해서 열어 주어야 합니다.

LONG RegOpenKeyEx(
    HKEY
 hkey,
    LPCTSTR  lpszSubKey,
    DWORD  dwReserved,
    REGSAM
 samDesired,
    PHKEY  phkResult
   );   

위 함수를 이용해서 레지스트리에 설정되어 있는 키를 열 수 있습니다. 첫번째 파라미터에 제일
상단에 있는 루트키를 지정하면 되는데 이 키는 레지스트리 편지기를 실행했을 때 볼 수 있는 값을 지정하면 되는 겁니다. 아래 값들 중 하나가
되겠군요.

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA

두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른
서브키가 있으면 서브 디렉토리를 표시하던 식인 식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된
예약어를 지정해주면 됩니다.

KEY_ALL_ACCESS              아래 모든 예약어를
만족합니다.
KEY_CREATE_LINK             다른 키로부터의 링크를 허락합니다.
KEY_CREATE_SUB_KEY
         서브키의 생성을 허락합니다.
KEY_ENUMERATE_SUB_KEYS      서브키의 보여줌을
허락합니다.
KEY_EXECUTE                 서브키의 데이터를 가져오는 것을
허락합니다.
KEY_QUERY_VALUE             서브키의 데이터를 가져오는 것을 허락합니다.
KEY_READ
                   서브키의 데이터를 가져오는 것을 허락합니다.
KEY_SET_VALUE               서브키의
데이터를 지정하는 것을 허락합니다.
KEY_WRITE                   서브키의 데이터를 지정하는 것을 허락합니다.

마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면
됩니다.

자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다.

LONG RegQueryValueEx(
    HKEY
 hkey,
    LPTSTR  lpszValueName,
    LPDWORD
 lpdwReserved,
    LPDWORD  lpdwType,
    LPBYTE  lpbData,
    LPDWORD
 lpcbData
   );

위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위
RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이
Default로 되어 있으면 그냥 “”식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의
저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다.

그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막
파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다.

데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야
합니다.

LONG RegCloseKey(
    HKEY  hkey
   );

위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서
닫아주면 되죠.

그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저
새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다.

LONG RegCreateKeyEx(
    HKEY
 hkey,
    LPCTSTR  lpszSubKey,
    DWORD  dwReserved,
    LPTSTR
 lpszClass,
    DWORD  fdwOptions,
    REGSAM
 samDesired,
    LPSECURITY_ATTRIBUTES  lpSecurityAttributes,
    PHKEY
 phkResult,
    LPDWORD  lpdwDisposition
   );

첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미
RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면
되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데
이때 지정될 수 있는 예약어는 다음과 같습니다.

REG_OPTION_VOLATILE         메모리에만
저장됩니다.
REG_OPTION_NON_VOLATILE     파일에 저장됩니다.

첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째
예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠?

여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면
됩니다.

KEY_ALL_ACCESS              아래 모든 예약어를
만족합니다.
KEY_CREATE_LINK             다른 키로부터의 링크를 허락합니다.
KEY_CREATE_SUB_KEY
         서브키의 생성을 허락합니다.
KEY_ENUMERATE_SUB_KEYS      서브키의 보여줌을
허락합니다.
KEY_EXECUTE                 서브키의 데이터를 가져오는 것을
허락합니다.
KEY_QUERY_VALUE             서브키의 데이터를 가져오는 것을 허락합니다.
KEY_READ
                   서브키의 데이터를 가져오는 것을 허락합니다.
KEY_SET_VALUE               서브키의
데이터를 지정하는 것을 허락합니다.
KEY_WRITE                   서브키의 데이터를 지정하는 것을 허락합니다.

앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는
NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한
결과가 저장될 변수의 주소를 지정해 주면 됩니다.

이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아
봅시다.

LONG RegSetValueEx(
    HKEY
 hkey,
    LPCTSTR  lpszValueName,
    DWORD  dwReserved,
    DWORD
 fdwType,
    CONST BYTE *  lpbData,
    DWORD  cbData
   );

위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아
봅시다.

첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고
두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면
됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다.

REG_BINARY      바이너리 형태입니다.
REG_DWORD       더블워드
형태입니다.
REG_LINK        심볼릭 링크 형태입니다.
REG_NONE        아무 형태도
아닙니다.
REG_SZ          문자열의 형태입니다.

다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해
주면 되구요.

자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다.

먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다.
그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠.

원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다.

LONG RegDeleteValue(
    HKEY
 hkey,
    LPTSTR  lpszValue
   );

첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째
파라미터에는 지울 데이터의 네임을 지정해 주면 되구요.

이번에는 키 자체를 없애는 함수입니다.

LONG RegDeleteKey(
    HKEY
 hkey,
    LPCTSTR  lpszSubKey
   );

첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에
포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠.

자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다.

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 47

안녕하세요……..돌팔이 황동준입니다……………..

이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다.

아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그
데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다.

MyMenu MENU
BEGIN
    POPUP
“&Registry”
    BEGIN
        MENUITEM “&Set Registry”,
100
        MENUITEM “&Get Registry”, 200
        MENUITEM
“&Delete Registry”, 300
    END
END

#include <windows.h>
#include
<string.h>
#include <stdio.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
BOOL SetRegistry(void);
char* GetRegistry(void);
void
DeleteRegistry(void);

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “Registry 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 char
szBuff[80];

        switch(message)
        {
            case
WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        if(!SetRegistry())
                            MessageBox(hWnd,
“Create Fail”, “Error”, MB_OK);
                        break;

                    case 200 :

                        strcpy(szBuff,
GetRegistry());
                        if(strcmp(szBuff,
“ERROR”))
                            MessageBox(hWnd, szBuff, “”,
MB_OK);
                        else
                            MessageBox(hWnd,
“Value not found!!”, “”, MB_OK);
                        break;

                    case 300 :

                        DeleteRegistry();
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

BOOL SetRegistry(void)
{
    HKEY
hKey;
    DWORD dwState;
    LONG lRet;

    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, NULL,
        NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Install”, NULL, REG_SZ,
        (unsigned char *)”c:doran20″,
strlen(“c:doran20”));
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    RegCloseKey(hKey);
    return TRUE;
}

char* GetRegistry(void)
{
    HKEY
hKey;
    LONG lRet;
    DWORD dwByte, dwType;
    static char
szBuff[80];

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
        KEY_ALL_ACCESS, &hKey);
    if(lRet
!= ERROR_SUCCESS)
        return “ERROR”;
    lRet = RegQueryValueEx(hKey,
“Install”, 0, &dwType,
        (unsigned char *)szBuff,
&dwByte);
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
“ERROR”;
    }
    RegCloseKey(hKey);
    return szBuff;
}

void DeleteRegistry(void)
{
    HKEY
hKey;

    RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
KEY_ALL_ACCESS,
        &hKey);
    RegDeleteValue(hKey,
“Install”);
    RegDeleteKey(HKEY_LOCAL_MACHINE, “SoftwareDORAN
20”);
    RegCloseKey(hKey);
}

자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고
진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록
합시다.

제가 만든 세개의 함수 루틴만 보면 되겠네요.

BOOL SetRegistry(void)
{

이 함수는 새로운 키를 생성하는 역할을 합니다.

    HKEY hKey;
    DWORD dwState;
    LONG
lRet;

    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, NULL,
        NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);

HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를
생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다.

    if(lRet != ERROR_SUCCESS)
        return
FALSE;

성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로
짐작할 수 있을 겁니다.

    lRet = RegSetValueEx(hKey, “Install”, NULL,
REG_SZ,
        (unsigned char *)”c:doran20″, strlen(“c:doran20”));

Install이라는 네임에 c:doran20이라는 데이터를 저장하는 구문입니다.

    if(lRet != ERROR_SUCCESS)
    {

역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요.

        RegCloseKey(hKey);
        return
FALSE;
    }
    RegCloseKey(hKey);

생성한 키를 닫는 구문입니다.

    return TRUE;
}

char* GetRegistry(void)
{

이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다.

    HKEY hKey;
    LONG lRet;
    DWORD
dwByte, dwType;
    static char szBuff[80];

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
        KEY_ALL_ACCESS, &hKey);

데이터를 가져올 서브키를 열고 있습니다.

    if(lRet != ERROR_SUCCESS)
        return
“ERROR”;
    lRet = RegQueryValueEx(hKey, “Install”, 0,
&dwType,
        (unsigned char *)szBuff, &dwByte);

Install이라는 네임에 해당하는 데이터를 가져오고 있습니다.

    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
“ERROR”;
    }
    RegCloseKey(hKey);
    return szBuff;
}

void DeleteRegistry(void)
{

이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다.

    HKEY hKey;

    RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0, KEY_ALL_ACCESS,
        &hKey);

지울 키를 얻고 있습니다.

    RegDeleteValue(hKey, “Install”);

Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다.

    RegDeleteKey(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”);

서브 키를 없애는 구문입니다.

    RegCloseKey(hKey);
}

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 48

안녕하세요…………돌팔이 황동준입니다……………

이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는
서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는
서브키에 속해 있는 네임에 해당하는 데이터를 얻는 방법은 압니다. 그러나 문제가
있죠. 바로 이 키에 어떤 서브키가 있는지 모른다면 할 수가 없습니다. 그렇죠? 그렇기 때문에 이 방법을 알아야 합니다. 좀더 들어간다면 어떤
서브키에 어떤 네임들이 있는지도 아는 방법이 있습니다. 그것도 우리가 지금 알아 볼 방법을 응용하면 됩니다. 자 그러면 시작해 봅시다.

먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지
개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다.

자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를
알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를
이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다.

LONG RegQueryInfoKey (
    HKEY
 hkey,
    LPTSTR  lpszClass,
    LPDWORD  lpcchClass,
    LPDWORD
 lpdwReserved,
    LPDWORD  lpcSubKeys,
    LPDWORD
 lpcchMaxSubkey,
    LPDWORD  lpcchMaxClass,
    LPDWORD
 lpcValues,
    LPDWORD  lpcchMaxValueName,
    LPDWORD
 lpcbMaxValueData,
    LPDWORD  lpcbSecurityDescriptor,
    PFILETIME
 lpftLastWriteTime
   );

첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째
파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면
됩니다.

네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의
개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의
주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의
주소를 지정해주면 됩니다.

여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의
주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는
이 값을 이용할테니 그 의미를 알아 두시기 바랍니다.

아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고
열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막
파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게
다루었는지도 알아 보았을 겁니다.

자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가
무엇인지 알아내는 함수를 알아 봅시다.

LONG RegEnumKeyEx(
    HKEY  hkey,
    DWORD
 iSubkey,
    LPTSTR  lpszName,
    LPDWORD  lpcchName,
    LPDWORD
 lpdwReserved,
    LPTSTR  lpszClass,
    LPDWORD
 lpcchClass,
    PFILETIME  lpftLastWrite
   );

바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는
루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어
우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로
지정해주면 되겠죠.

세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째
파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다.

다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될
버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다.

마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의
마지막 파라미터와 의미가 같습니다.

자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운
키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다.

MyMenu MENU
BEGIN
    POPUP
“&Registry”
    BEGIN
        MENUITEM “&Set Registry”,
100
        MENUITEM “&Print Registry”, 200
    END
END

#include <windows.h>
#include
<string.h>
#include <stdio.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
BOOL SetRegistry(void);
BOOL PrintSubRegistry(HWND hWnd);

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “Registry 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 char
szBuff[80];

        switch(message)
        {
            case
WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        if(!SetRegistry())
                            MessageBox(hWnd,
“Create Fail”, “Error”, MB_OK);
                        break;

                    case 200 :

                        if(!PrintSubRegistry(hWnd))
                            MessageBox(hWnd,
“Print Fail”, “Error”,
MB_OK);
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

BOOL SetRegistry(void)
{
    HKEY
hKey;
    DWORD dwState;
    LONG lRet;

    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20Install”,
        NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Install”, NULL, REG_SZ,
        (unsigned char *)”c:doran20″,
strlen(“c:doran20”));
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20Version”,
        NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Version”, NULL, REG_SZ,
        (unsigned char *)”2.0″,
strlen(“2.0”));

    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    RegCloseKey(hKey);
    return TRUE;
}

BOOL PrintSubRegistry(HWND hWnd)
{
    HDC
hDC;
    HKEY hKey;
    LONG lRet;
    DWORD dwSubKeyNumber, dwCount,
dwSubKeySize = 80;
    FILETIME FileTime;
    static char
szSubKey[80];

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
        KEY_ALL_ACCESS, &hKey);
    if(lRet
!= ERROR_SUCCESS)
        return FALSE;
    lRet = RegQueryInfoKey(hKey,
NULL, 0, 0, &dwSubKeyNumber, NULL, NULL,
        NULL, NULL, NULL, NULL,
&FileTime);
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    dwCount =
0;
    do
    {
        RegEnumKeyEx(hKey, dwCount, szSubKey,
&dwSubKeySize, NULL,
            NULL, 0,
&FileTime);
        dwSubKeySize = 80;
        hDC =
GetDC(hWnd);
        TextOut(hDC, 0, 20*dwCount, szSubKey,
strlen(szSubKey));
        ReleaseDC(hWnd,
hDC);
        dwCount++;
    }
while(dwCount<dwSubKeyNumber);
    RegCloseKey(hKey)

;
    return TRUE;
}

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 49

안녕하세요………….돌팔이
황동준입니다…………………

이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다.

제가 만든 두개의 함수만 알아 보면 되겠죠?

BOOL SetRegistry(void)
{

이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을
합니다.

    HKEY hKey;
    DWORD dwState;
    LONG
lRet;

    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20Install”,
        NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Install”, NULL, REG_SZ,
        (unsigned char *)”c:doran20″,
strlen(“c:doran20”));
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }

어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고
Install이라는 네임에 c:doran20이라는 데이터를 저장하고 있는 구문입니다.

    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20Version”,
        NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Version”, NULL, REG_SZ,
        (unsigned char *)”2.0″, strlen(“2.0”));

    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    RegCloseKey(hKey);
    return TRUE;

앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에
Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다.

}

앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN
20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다.

BOOL PrintSubRegistry(HWND hWnd)
{

이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을
합니다.

    HDC hDC;
    HKEY hKey;
    LONG
lRet;
    DWORD dwSubKeyNumber, dwCount, dwSubKeySize = 80;
    FILETIME
FileTime;
    static char szSubKey[80];

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
        KEY_ALL_ACCESS, &hKey);

    if(lRet != ERROR_SUCCESS)
        return
FALSE;

알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다.

    lRet = RegQueryInfoKey(hKey, NULL, 0, 0,
&dwSubKeyNumber, NULL, NULL,
        NULL, NULL, NULL, NULL,
&FileTime);

이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을
지정하였습니다.

    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    dwCount = 0;

서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다.

    do
    {
        RegEnumKeyEx(hKey,
dwCount, szSubKey, &dwSubKeySize, NULL,
            NULL, 0,
&FileTime);

인덱스에 해당하는 서브키를 얻고 있는 구문입니다.

        dwSubKeySize = 80;

위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시
초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠.

        hDC = GetDC(hWnd);
        TextOut(hDC,
0, 20*dwCount, szSubKey, strlen(szSubKey));
        ReleaseDC(hWnd, hDC);

얻은 서브키를 화면에 출력해 주는 구문입니다.

        dwCount++;

인덱스를 증가하고 있습니다.

    } while(dwCount<dwSubKeyNumber);

서브키의 개수만큼 루프문을 돌고 있습니다.

    RegCloseKey(hKey);
    return TRUE;
}

자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이
아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠.

MyMenu MENU
BEGIN
    POPUP
“&Registry”
    BEGIN
        MENUITEM “&Set Registry”,
100
        MENUITEM “&Print Registry”, 200
    END
END

#include <windows.h>
#include
<string.h>
#include <stdio.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
LPARAM);
BOOL SetRegistry(void);
BOOL PrintSubRegistry(HWND hWnd);

int WINAPI WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
        static
char szAppName[] = “Registry 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 char
szBuff[80];

        switch(message)
        {
            case
WM_COMMAND :

                switch(LOWORD(wParam))
                {
                    case
100 :

                        if(!SetRegistry())
                            MessageBox(hWnd,
“Create Fail”, “Error”, MB_OK);
                        break;

                    case 200 :

                        if(!PrintSubRegistry(hWnd))
                            MessageBox(hWnd,
“Print Fail”, “Error”,
MB_OK);
                        break;
                }
                return
0;

            case WM_DESTROY :

                PostQuitMessage(0);
                return
0;
        }
        return DefWindowProc(hWnd, message, wParam,
lParam);
}

BOOL SetRegistry(void)
{
    HKEY
hKey;
    DWORD dwState;
    LONG lRet;

    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20Install”,
        NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Install”, NULL, REG_SZ,
        (unsigned char *)”c:doran20″,
strlen(“c:doran20”));
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20Version”,
        NULL, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey,
            &dwState);
    if(lRet !=
ERROR_SUCCESS)
        return FALSE;
    lRet = RegSetValueEx(hKey,
“Version”, NULL, REG_SZ,
        (unsigned char *)”2.0″,
strlen(“2.0”));

    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    RegCloseKey(hKey);
    return TRUE;
}

BOOL PrintSubRegistry(HWND hWnd)
{
    HDC
hDC;
    HKEY hKey, hSubKey;
    LONG lRet;
    DWORD dwSubKeyNumber,
dwCount, dwValueNumber, dwValueCount,
        dwSubKeySize = 80;
    DWORD
dwNameSize = 80, dwValueSize = 80;
    FILETIME FileTime;
    int
n=0;
    static char szSubKey[80], szName[80], szValue[80];
    static
char szBuff[80], szPrint[256];

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
        KEY_ALL_ACCESS, &hKey);
    if(lRet
!= ERROR_SUCCESS)
        return FALSE;
    lRet = RegQueryInfoKey(hKey,
NULL, 0, 0, &dwSubKeyNumber, NULL, NULL,
        NULL, NULL, NULL, NULL,
&FileTime);
    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }
    dwCount =
0;
    do
    {
        RegEnumKeyEx(hKey, dwCount, szSubKey,
&dwSubKeySize, NULL,
            NULL, 0,
&FileTime);
        dwSubKeySize = 80;
        strcpy(szBuff,
“SoftwareDORAN 20”);
        strcat(szBuff,
“”);
        strcat(szBuff, szSubKey);
        lRet =
RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0,
KEY_ALL_ACCESS,
            &hSubKey);

        lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0,
NULL, NULL, NULL,
            &dwValueNumber, NULL, NULL, NULL,
&FileTime);
        dwValueCount = 0;
        while(dwValueNumber >
dwValueCount)
        {
            RegEnumValue(hSubKey, dwValueCount,
szName, &dwNameSize, NULL,
                NULL, (unsigned char
*)szValue, &dwValueSize);
            dwNameSize = dwValueSize =
80;
            sprintf(szPrint, “%s : %s”, szName,
szValue);
            hDC = GetDC(hWnd);
            TextOut(hDC, 0, 20*n,
szPrint, strlen(szPrint));
            ReleaseDC(hWnd,
hDC);
            n++;
            dwValueCount++;
        }
        RegCloseKey(hSubKey);
        dwCount++;
    }
while(dwCount<dwSubKeyNumber);
    RegCloseKey(hKey);
    return
TRUE;

}

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~

 

  윈도우 32비트 프로그래밍 50

안녕하세요…………..돌팔이 황동준입니다………….

이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다.

이번에는 함수 하나만 알아보면 되겠네요.

BOOL PrintSubRegistry(HWND hWnd)
{
    HDC
hDC;
    HKEY hKey, hSubKey;
    LONG lRet;
    DWORD dwSubKeyNumber,
dwCount, dwValueNumber, dwValueCount,
        dwSubKeySize = 80;
    DWORD
dwNameSize = 80, dwValueSize = 80;
    FILETIME FileTime;
    int
n=0;
    static char szSubKey[80], szName[80], szValue[80];
    static
char szBuff[80], szPrint[256];

    lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
“SoftwareDORAN 20”, 0,
        KEY_ALL_ACCESS, &hKey);
    if(lRet
!= ERROR_SUCCESS)
        return FALSE;

정보를 알아볼 서브키의 루크키를 여는 구문입니다.

    lRet = RegQueryInfoKey(hKey, NULL, 0, 0,
&dwSubKeyNumber, NULL, NULL,
        NULL, NULL, NULL, NULL,
&FileTime);

    if(lRet !=
ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        return
FALSE;
    }

서브키의 개수를 알아내고 있습니다.

    dwCount =
0;
    do
    {
        RegEnumKeyEx(hKey, dwCount, szSubKey,
&dwSubKeySize, NULL,
            NULL, 0, &FileTime);

서브키를 알아내고 있는 구문입니다.

        dwSubKeySize =
80;
        strcpy(szBuff, “SoftwareDORAN 20”);
        strcat(szBuff,
“”);
        strcat(szBuff, szSubKey);

        lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
szBuff, 0, KEY_ALL_ACCESS,
            &hSubKey);

알아낸 서브키를 열고 있는 구문입니다.

        lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0,
NULL, NULL, NULL,
            &dwValueNumber, NULL, NULL, NULL,
&FileTime);

그 서브키가 가지는 데이터의 개수를 얻고 있습니다.

        dwValueCount =
0;
        while(dwValueNumber > dwValueCount)
        {

데이터의 개수만큼 루프문을 반복하고 있습니다.

            RegEnumValue(hSubKey, dwValueCount,
szName, &dwNameSize, NULL,
                NULL, (unsigned char
*)szValue, &dwValueSize);

위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해
설명드리지 않았군요.

LONG RegEnumValue(
    HKEY  hkey,
    DWORD
 iValue,
    LPTSTR  lpszValue,
    LPDWORD  lpcchValue,
    LPDWORD
 lpdwReserved,
    LPDWORD  lpdwType,
    LPBYTE  lpbData,
    LPDWORD
 lpcbData
   );   

첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째
파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이
버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의
타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에
저장되겠군요.

REG_BINARY
REG_DWORD
REG_LINK
REG_NONE
REG_SZ

그 의미는 이미 앞에서 설명드렸을 겁니다.

일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의
크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다.

함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다.

            dwNameSize = dwValueSize = 80;

역시 길이를 초기화 해주고 있습니다.

            sprintf(szPrint, “%s : %s”, szName,
szValue);
            hDC = GetDC(hWnd);
            TextOut(hDC, 0, 20*n,
szPrint, strlen(szPrint));
            ReleaseDC(hWnd,
hDC);
            n++;

얻은 네임과 데이터를 화면에 출력해 주고 있습니다.

            dwValueCount++;

네임에 대한 인덱스를 증가해주고 있습니다.

        }
        RegCloseKey(hSubKey);
        dwCount++;

서브키에 대한 인덱스를 증가해주고 있습니다.

    } while(dwCount<dwSubKeyNumber);

서브키의 개수만큼 루프문이 돌고 있습니다.

    RegCloseKey(hKey);
    return TRUE;
}

오늘은 여기까지
끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

zemna

Programmer/Web/Mobile/Desktop

You may also like...

Leave a Reply