CString – > char* 로…케스팅
CString strPP;
char * chNN = (LPSTR)(LPCSTR)strPP;
이렇게 해서 chNN을 CString의 포인터로 가져 옵니다.
(LPSTR)(LPCSTR)strPP 이 부분 에서 이유는 MSDN을 찾아보시면 아시겠지만 CString은 const char * 으로 만 받을수 있답니다.
그래서 (LPCTSTR)strPP 이런 형식으로도 사용합니다. 물론 const char *으로 return되겠죠.. 다시 char *을 필요하신다면
char * chNN = (char *)(LPCTSTR)strPP;
이런 식으로도 사용합니다.
===>(LPSTR)(LPCTSTR)str은 위험한듯..
1) 유니코드를 고려하지 않았을뿐 아니라
2) 위험하게 내부데이터를 접근합니다.
char *pstr = (LPSTR)(LPCTSTR)str;
이 줄은 UNICODE인경우..
char *pstr = (char *) (const wchar_t *) str;
입니다.
특히 wchar_t를 본래데이터형으로 보지 않을 경우
char *pstr = (char *)(const unsigned short *)str;
입니다..
뭐 일단 유니코드를 고려하지 않는다고 하더라도, CString이 제공하는 것은 const 가 붙은 형변환 밖에 없는데,
이걸 const 를 억지로 빼버리고는 마치 접근해서 고쳐도 되는 것처럼 보이게 되므로 .. 잘못사용하면 오류를 일으키며. 프로그램이 뻑.. 뻗을수도 있쬬 ^^ (const 변환은 받는 쪽에서 안고친다고 보고 CString이 자기 내부 데이터 주소를 살짝 보여주는 건데.. 그걸 char로 바꾸고 쓰려고 하면.. -.-;)
보통 이런 문제는 char[50] 에서 처럼 .. 특정 위치의 글자를 바로 접근할 수 있냐..란 의문에서 생기는데 이 문제는 CString만으로도 충분합니다. CString이 operator[] 를 제공하므로..
str[23] 이렇게 마치 char[] 처럼 사용하실수 있습니다. 물론 이때도 길이를 넘어서는 접근은 피해야 겠죠.. C/C++의 배열이 제공못하는 길이를 CString읜 GetLength()형태로 제공하니 얼마나 편합니까 ^^;;;
그래도 기존 라이브러리(void f(char *)가 있어서 변환이 필요하다면.. 추천하는 방법은
1) char data[50]; strcpy(data, str); f(data); ///////// 유니코드에선 TCHAR data[50]; _tcscpy(data, str)
2) f(str.GetBuffer(50)); str.ReleaseBuffer();
CString => char* 변환
char * ch;
CString *str;
1) ch = (LPSTR)(LPCSTR)str;
2) ch = str.GetBuffer(str.GetLength());
3) wsprintf( ch, “%s”, str);
char* => CString 변환
1) str = (LPCSTR)(LPSTR)ch;
2) str = ch;
참고)
LPSTR 은 char* 입니다.
LPSTR : char stirng의 32비트 포인터, char* 와 같다.
LPCTSTR : Constant character String의 32비트 포인터
UINT : 32비트 unsigned형 정수
DWORD : unsigned long int형
BYTE : 8비트 unsigned 정수
참고 : CString을 const char* 형태로 변경 -> (LPTSTR)(LPCTSTR)CString
taskmanager에서 프로세스를 죽이지 않고 커맨드 라인으로 죽이기
taskkill /IM 죽일프로세스명
char*, LPCTSTR, TCHAR 의 차이
어떠한 문자열을 처리하는 자료형은 보통 char, wchar, TCHAR 를 사용한다.
쉽게 보면,
char* => LPSTR 라고 생각하면 되고
const char* => LPCSTR 라고 할 수 있다.
가운데 'C' 는 const 의 의미다. 'LP' 는 long pointer 의 의미.
끝에 STR 이라는 의미는 NULL 포인터로 끝난다는 의미. 즉, 마지막 인덱스에는 항상 NULL 이 채워져 있어야 한다는 것.
그래야만 str 관련 함수들이 동작을 하는 것이다. strlen, strcpy, strcmp 등등.. 이것들이 src param 의 끝에 NULL 이 없으면 무지 당황하게 된다.
가운데 'T' 가 들어간다는 것은 TCHAR 이라는 의미.
그렇다면 왜 T를 쓸까??
영문은 1바이트.
그런데, 우리나라 말이나, 중국어 등 영문권이 아닌 제 3세계 언어를 표현하기 위해서는
2바이트가 필요하다.. 이를 위해서 MultiByte 를 사용하기도 하지만 MultiByte 는
어떤 글씨는 1바이트 이고 어떤 글씨는 2바이트여서 메모리 관리가 어렵다.
그래서 나온 것이 wchar 인데,
wchar 는 모든 글씨(영문 포함)가 2바이트로 구성이 된다.
당연히 wchar 는 일반 ascii 타입의 char 보다 메모리 공간이 2배 필요하다.
그런데 본론인 TCHAR 는 무엇이냐?
바로 ACSCII 타입의 일반 char 또는 wchar 라는 의미다.
TCHAR 을 사용하면 char 인지 wchar 인지 구별하지 않고 그냥 코딩을 하면 된다.
TCHAR tch = _T('A'); <=> char ch = 'A';
TCHAR tch = _T('A'); <=> wchar wch = 'A';
배열도 역시.. 그냥 숫자 인덱스로 원하는 글씨의 위치를 추적할 수 있다.
그럼 무엇으로 현재 프로젝트의 TCHAR가 char 인지 wchar 인지를 구별할까?
UNICODE 라는 precompile 상수.
해당 프로젝트 project -> settings 에 _DEBUG 등등 선언되어 있는데, 끝에다
UNICODE 라고 쓰고 컴파일 하면 앞으로 나오는 모든 TCHAR 타입은 wchar 으로 변환해서
컴파일을 시도하게 된다.
가운데 C 다음의 T 는 TCHAR 이라는 의미
당연히 상수로 변환을 했으므로 변수에 값을 대입할 수 없겠다.
( b[3] = _T('A'); <- syntax error <=> const char str = "ABCD"; str[3] = 'E' ; <- 이때 에러와 같은 이치)
(TCHAR 을 나타는 매크로가 _T 이다. (한문자 _T(' '), 문장 _T(" ") )
LPSTR, LPCSTR, LPCTSTR…
LPSTR : A 32-bit pointer to a character string.
이 데이터 형같은 경우 예전에 우리가 사용하던 방식으로 선언하면
char *
와 같은 경우이죠. 유니코드를 지원하지 않기 때문에 각각의
문자는 1바이트를 가집니다.
LPCSTR : A 32-bit pointer to a constant character string.
이 데이터 형같은 경우 예전에 우리가 사용하던 방식으로 선언하면
const char *
와 같은 경우이죠. const 형이 어떤건지는 아시죠? 이것역시
유니코드를 지원하지 않기 때문에 각각의 문자는 1바이트를 가집니다.
LPTSTR : A 32-bit pointer to a character string that is
portable for Unicode and DBCS
이 데이터 형같은 경우, 윈도우즈가 유니코드를 지원하면서 새로
생긴형식으로 풀어쓰면 다음과 같습니다.
TCHAR *
이 형은 유니코드를 지원하기 때문에 각 문자가 2바이트를 가지게
됩니다. 실제로 유니코드를 지원하는 프로그램을 작성하지 않는
이상 거의 사용하지 않습니다.
LPCTSTR : A 32-bit pointer to a constant character string that
is portable for Unicode and DBCS.
이것 역시 윈도우즈가 유니코드를 지원하면서 새로 생긴형식으로
풀어쓰면 다음과 같습니다.
const TCHAR *
마찬가지로 유니코드를 지원하기 때문에 한문자가 2바이트 크기를
가지게 됩니다.
함수뒤에 const 를 붙이는건 클래스 멤버함수내에서 this 사용을 제한하기 위해서 사용합니다.
일반적으로 멤버 함수내에서 사용되는 this는 해당 클래스가 MyClass 인 경우에,
MyClass * const this;
와 같이 내부적으로 선언되어서 사용되는데, 함수의 뒤에 const를 붙이면
const MyClass * const this;
와 같이 속성이 바뀌어져서 사용됩니다. 즉 내부에 사용되는 데이터 멤버가 이 함수에서는 모조리
읽기 전용으로 바뀌어져 버리는거죠…
this 변수가 가리키는 멤버들이 모두 쓰기 불능으로 되어버리기 때문에… 즉, this는 우리가 직접
변경할수 없기 때문에 함수뒤에 const를 붙여 간접적으로 this를 const형으로 변경하는 기능을
구현한겁니다.
Registry
|
이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어 보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가 앞에서 배운 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_CLASSES_ROOT 두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른 서브키가 있으면 서브 디렉토리를 표시하던 식인 \\식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된 예약어를 지정해주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면 됩니다. 자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다. LONG RegQueryValueEx( 위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위 RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이 Default로 되어 있으면 그냥 ""식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의 저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다. 그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막 파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다. 데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야 합니다. LONG RegCloseKey( 위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서 닫아주면 되죠. 그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저 새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다. LONG RegCreateKeyEx( 첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미 RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면 되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데 이때 지정될 수 있는 예약어는 다음과 같습니다. REG_OPTION_VOLATILE 메모리에만 저장됩니다. 첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째 예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠? 여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는 NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한 결과가 저장될 변수의 주소를 지정해 주면 됩니다. 이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아 봅시다. LONG RegSetValueEx( 위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아 봅시다. 첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고 두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면 됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다. REG_BINARY 바이너리 형태입니다. 다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해 주면 되구요. 자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다. 먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다. 그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠. 원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다. LONG RegDeleteValue( 첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째 파라미터에는 지울 데이터의 네임을 지정해 주면 되구요. 이번에는 키 자체를 없애는 함수입니다. LONG RegDeleteKey( 첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에 포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠. 자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 47 |
|
안녕하세요……..돌팔이 황동준입니다…………….. 이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다. 아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그 데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : strcpy(szBuff, GetRegistry()); case 300 : DeleteRegistry(); case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, char* GetRegistry(void) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, void DeleteRegistry(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고 진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록 합시다. 제가 만든 세개의 함수 루틴만 보면 되겠네요. BOOL SetRegistry(void) 이 함수는 새로운 키를 생성하는 역할을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를 생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다. if(lRet != ERROR_SUCCESS) 성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로 짐작할 수 있을 겁니다. lRet = RegSetValueEx(hKey, "Install", NULL, REG_SZ, Install이라는 네임에 c:\doran20이라는 데이터를 저장하는 구문입니다. if(lRet != ERROR_SUCCESS) 역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요. RegCloseKey(hKey); 생성한 키를 닫는 구문입니다. return TRUE; char* GetRegistry(void) 이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다. HKEY hKey; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 데이터를 가져올 서브키를 열고 있습니다. if(lRet != ERROR_SUCCESS) Install이라는 네임에 해당하는 데이터를 가져오고 있습니다. if(lRet != ERROR_SUCCESS) void DeleteRegistry(void) 이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다. HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 지울 키를 얻고 있습니다. RegDeleteValue(hKey, "Install"); Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다. RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\DORAN 20"); 서브 키를 없애는 구문입니다. RegCloseKey(hKey); 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 48 |
|
안녕하세요…………돌팔이 황동준입니다…………… 이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는 서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는 먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지 개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다. 자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를 알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를 이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다. LONG RegQueryInfoKey ( 첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째 파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면 됩니다. 네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의 개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의 주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의 주소를 지정해주면 됩니다. 여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의 주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는 이 값을 이용할테니 그 의미를 알아 두시기 바랍니다. 아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고 열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막 파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게 다루었는지도 알아 보았을 겁니다. 자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가 무엇인지 알아내는 함수를 알아 봅시다. LONG RegEnumKeyEx( 바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는 루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어 우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로 지정해주면 되겠죠. 세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째 파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될 버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의 마지막 파라미터와 의미가 같습니다. 자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운 키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, ; 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 49 |
|
안녕하세요………….돌팔이 황동준입니다………………… 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 제가 만든 두개의 함수만 알아 보면 되겠죠? BOOL SetRegistry(void) 이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", 어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고 Install이라는 네임에 c:\doran20이라는 데이터를 저장하고 있는 구문입니다. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Version", if(lRet != ERROR_SUCCESS) 앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에 Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다. } 앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN 20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다. BOOL PrintSubRegistry(HWND hWnd) 이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을 합니다. HDC hDC; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, if(lRet != ERROR_SUCCESS) 알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, 이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을 지정하였습니다. if(lRet != ERROR_SUCCESS) 서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다. do 인덱스에 해당하는 서브키를 얻고 있는 구문입니다. dwSubKeySize = 80; 위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시 초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠. hDC = GetDC(hWnd); 얻은 서브키를 화면에 출력해 주는 구문입니다. dwCount++; 인덱스를 증가하고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문을 돌고 있습니다. RegCloseKey(hKey); 자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이 아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, } 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 50 |
|
안녕하세요…………..돌팔이 황동준입니다…………. 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 이번에는 함수 하나만 알아보면 되겠네요. BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 정보를 알아볼 서브키의 루크키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, if(lRet != ERROR_SUCCESS) 서브키의 개수를 알아내고 있습니다. dwCount = 0; 서브키를 알아내고 있는 구문입니다. dwSubKeySize = 80; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0, KEY_ALL_ACCESS, 알아낸 서브키를 열고 있는 구문입니다. lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, 그 서브키가 가지는 데이터의 개수를 얻고 있습니다. dwValueCount = 0; 데이터의 개수만큼 루프문을 반복하고 있습니다. RegEnumValue(hSubKey, dwValueCount, szName, &dwNameSize, NULL, 위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해 설명드리지 않았군요. LONG RegEnumValue( 첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째 파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의 타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에 저장되겠군요. REG_BINARY 그 의미는 이미 앞에서 설명드렸을 겁니다. 일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다. dwNameSize = dwValueSize = 80; 역시 길이를 초기화 해주고 있습니다. sprintf(szPrint, "%s : %s", szName, szValue); 얻은 네임과 데이터를 화면에 출력해 주고 있습니다. dwValueCount++; 네임에 대한 인덱스를 증가해주고 있습니다. } 서브키에 대한 인덱스를 증가해주고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문이 돌고 있습니다. RegCloseKey(hKey); |
Registry
|
이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어 보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가 앞에서 배운 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_CLASSES_ROOT 두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른 서브키가 있으면 서브 디렉토리를 표시하던 식인 \\식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된 예약어를 지정해주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면 됩니다. 자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다. LONG RegQueryValueEx( 위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위 RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이 Default로 되어 있으면 그냥 ""식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의 저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다. 그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막 파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다. 데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야 합니다. LONG RegCloseKey( 위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서 닫아주면 되죠. 그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저 새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다. LONG RegCreateKeyEx( 첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미 RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면 되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데 이때 지정될 수 있는 예약어는 다음과 같습니다. REG_OPTION_VOLATILE 메모리에만 저장됩니다. 첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째 예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠? 여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는 NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한 결과가 저장될 변수의 주소를 지정해 주면 됩니다. 이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아 봅시다. LONG RegSetValueEx( 위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아 봅시다. 첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고 두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면 됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다. REG_BINARY 바이너리 형태입니다. 다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해 주면 되구요. 자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다. 먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다. 그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠. 원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다. LONG RegDeleteValue( 첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째 파라미터에는 지울 데이터의 네임을 지정해 주면 되구요. 이번에는 키 자체를 없애는 함수입니다. LONG RegDeleteKey( 첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에 포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠. 자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 47 |
|
안녕하세요……..돌팔이 황동준입니다…………….. 이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다. 아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그 데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : strcpy(szBuff, GetRegistry()); case 300 : DeleteRegistry(); case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, char* GetRegistry(void) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, void DeleteRegistry(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고 진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록 합시다. 제가 만든 세개의 함수 루틴만 보면 되겠네요. BOOL SetRegistry(void) 이 함수는 새로운 키를 생성하는 역할을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를 생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다. if(lRet != ERROR_SUCCESS) 성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로 짐작할 수 있을 겁니다. lRet = RegSetValueEx(hKey, "Install", NULL, REG_SZ, Install이라는 네임에 c:\doran20이라는 데이터를 저장하는 구문입니다. if(lRet != ERROR_SUCCESS) 역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요. RegCloseKey(hKey); 생성한 키를 닫는 구문입니다. return TRUE; char* GetRegistry(void) 이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다. HKEY hKey; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 데이터를 가져올 서브키를 열고 있습니다. if(lRet != ERROR_SUCCESS) Install이라는 네임에 해당하는 데이터를 가져오고 있습니다. if(lRet != ERROR_SUCCESS) void DeleteRegistry(void) 이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다. HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 지울 키를 얻고 있습니다. RegDeleteValue(hKey, "Install"); Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다. RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\DORAN 20"); 서브 키를 없애는 구문입니다. RegCloseKey(hKey); 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 48 |
|
안녕하세요…………돌팔이 황동준입니다…………… 이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는 서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는 먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지 개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다. 자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를 알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를 이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다. LONG RegQueryInfoKey ( 첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째 파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면 됩니다. 네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의 개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의 주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의 주소를 지정해주면 됩니다. 여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의 주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는 이 값을 이용할테니 그 의미를 알아 두시기 바랍니다. 아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고 열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막 파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게 다루었는지도 알아 보았을 겁니다. 자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가 무엇인지 알아내는 함수를 알아 봅시다. LONG RegEnumKeyEx( 바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는 루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어 우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로 지정해주면 되겠죠. 세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째 파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될 버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의 마지막 파라미터와 의미가 같습니다. 자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운 키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, ; 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 49 |
|
안녕하세요………….돌팔이 황동준입니다………………… 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 제가 만든 두개의 함수만 알아 보면 되겠죠? BOOL SetRegistry(void) 이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", 어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고 Install이라는 네임에 c:\doran20이라는 데이터를 저장하고 있는 구문입니다. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Version", if(lRet != ERROR_SUCCESS) 앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에 Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다. } 앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN 20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다. BOOL PrintSubRegistry(HWND hWnd) 이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을 합니다. HDC hDC; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, if(lRet != ERROR_SUCCESS) 알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, 이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을 지정하였습니다. if(lRet != ERROR_SUCCESS) 서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다. do 인덱스에 해당하는 서브키를 얻고 있는 구문입니다. dwSubKeySize = 80; 위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시 초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠. hDC = GetDC(hWnd); 얻은 서브키를 화면에 출력해 주는 구문입니다. dwCount++; 인덱스를 증가하고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문을 돌고 있습니다. RegCloseKey(hKey); 자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이 아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, } 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 50 |
|
안녕하세요…………..돌팔이 황동준입니다…………. 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 이번에는 함수 하나만 알아보면 되겠네요. BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 정보를 알아볼 서브키의 루크키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, if(lRet != ERROR_SUCCESS) 서브키의 개수를 알아내고 있습니다. dwCount = 0; 서브키를 알아내고 있는 구문입니다. dwSubKeySize = 80; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0, KEY_ALL_ACCESS, 알아낸 서브키를 열고 있는 구문입니다. lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, 그 서브키가 가지는 데이터의 개수를 얻고 있습니다. dwValueCount = 0; 데이터의 개수만큼 루프문을 반복하고 있습니다. RegEnumValue(hSubKey, dwValueCount, szName, &dwNameSize, NULL, 위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해 설명드리지 않았군요. LONG RegEnumValue( 첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째 파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의 타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에 저장되겠군요. REG_BINARY 그 의미는 이미 앞에서 설명드렸을 겁니다. 일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다. dwNameSize = dwValueSize = 80; 역시 길이를 초기화 해주고 있습니다. sprintf(szPrint, "%s : %s", szName, szValue); 얻은 네임과 데이터를 화면에 출력해 주고 있습니다. dwValueCount++; 네임에 대한 인덱스를 증가해주고 있습니다. } 서브키에 대한 인덱스를 증가해주고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문이 돌고 있습니다. RegCloseKey(hKey); |
Registry
|
이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어 보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가 앞에서 배운 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_CLASSES_ROOT 두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른 서브키가 있으면 서브 디렉토리를 표시하던 식인 \\식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된 예약어를 지정해주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면 됩니다. 자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다. LONG RegQueryValueEx( 위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위 RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이 Default로 되어 있으면 그냥 ""식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의 저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다. 그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막 파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다. 데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야 합니다. LONG RegCloseKey( 위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서 닫아주면 되죠. 그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저 새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다. LONG RegCreateKeyEx( 첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미 RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면 되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데 이때 지정될 수 있는 예약어는 다음과 같습니다. REG_OPTION_VOLATILE 메모리에만 저장됩니다. 첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째 예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠? 여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는 NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한 결과가 저장될 변수의 주소를 지정해 주면 됩니다. 이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아 봅시다. LONG RegSetValueEx( 위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아 봅시다. 첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고 두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면 됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다. REG_BINARY 바이너리 형태입니다. 다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해 주면 되구요. 자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다. 먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다. 그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠. 원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다. LONG RegDeleteValue( 첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째 파라미터에는 지울 데이터의 네임을 지정해 주면 되구요. 이번에는 키 자체를 없애는 함수입니다. LONG RegDeleteKey( 첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에 포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠. 자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 47 |
|
안녕하세요……..돌팔이 황동준입니다…………….. 이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다. 아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그 데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : strcpy(szBuff, GetRegistry()); case 300 : DeleteRegistry(); case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, char* GetRegistry(void) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, void DeleteRegistry(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고 진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록 합시다. 제가 만든 세개의 함수 루틴만 보면 되겠네요. BOOL SetRegistry(void) 이 함수는 새로운 키를 생성하는 역할을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를 생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다. if(lRet != ERROR_SUCCESS) 성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로 짐작할 수 있을 겁니다. lRet = RegSetValueEx(hKey, "Install", NULL, REG_SZ, Install이라는 네임에 c:\doran20이라는 데이터를 저장하는 구문입니다. if(lRet != ERROR_SUCCESS) 역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요. RegCloseKey(hKey); 생성한 키를 닫는 구문입니다. return TRUE; char* GetRegistry(void) 이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다. HKEY hKey; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 데이터를 가져올 서브키를 열고 있습니다. if(lRet != ERROR_SUCCESS) Install이라는 네임에 해당하는 데이터를 가져오고 있습니다. if(lRet != ERROR_SUCCESS) void DeleteRegistry(void) 이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다. HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 지울 키를 얻고 있습니다. RegDeleteValue(hKey, "Install"); Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다. RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\DORAN 20"); 서브 키를 없애는 구문입니다. RegCloseKey(hKey); 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 48 |
|
안녕하세요…………돌팔이 황동준입니다…………… 이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는 서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는 먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지 개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다. 자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를 알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를 이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다. LONG RegQueryInfoKey ( 첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째 파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면 됩니다. 네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의 개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의 주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의 주소를 지정해주면 됩니다. 여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의 주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는 이 값을 이용할테니 그 의미를 알아 두시기 바랍니다. 아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고 열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막 파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게 다루었는지도 알아 보았을 겁니다. 자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가 무엇인지 알아내는 함수를 알아 봅시다. LONG RegEnumKeyEx( 바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는 루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어 우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로 지정해주면 되겠죠. 세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째 파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될 버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의 마지막 파라미터와 의미가 같습니다. 자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운 키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, ; 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 49 |
|
안녕하세요………….돌팔이 황동준입니다………………… 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 제가 만든 두개의 함수만 알아 보면 되겠죠? BOOL SetRegistry(void) 이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", 어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고 Install이라는 네임에 c:\doran20이라는 데이터를 저장하고 있는 구문입니다. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Version", if(lRet != ERROR_SUCCESS) 앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에 Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다. } 앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN 20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다. BOOL PrintSubRegistry(HWND hWnd) 이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을 합니다. HDC hDC; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, if(lRet != ERROR_SUCCESS) 알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, 이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을 지정하였습니다. if(lRet != ERROR_SUCCESS) 서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다. do 인덱스에 해당하는 서브키를 얻고 있는 구문입니다. dwSubKeySize = 80; 위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시 초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠. hDC = GetDC(hWnd); 얻은 서브키를 화면에 출력해 주는 구문입니다. dwCount++; 인덱스를 증가하고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문을 돌고 있습니다. RegCloseKey(hKey); 자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이 아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, } 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 50 |
|
안녕하세요…………..돌팔이 황동준입니다…………. 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 이번에는 함수 하나만 알아보면 되겠네요. BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 정보를 알아볼 서브키의 루크키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, if(lRet != ERROR_SUCCESS) 서브키의 개수를 알아내고 있습니다. dwCount = 0; 서브키를 알아내고 있는 구문입니다. dwSubKeySize = 80; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0, KEY_ALL_ACCESS, 알아낸 서브키를 열고 있는 구문입니다. lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, 그 서브키가 가지는 데이터의 개수를 얻고 있습니다. dwValueCount = 0; 데이터의 개수만큼 루프문을 반복하고 있습니다. RegEnumValue(hSubKey, dwValueCount, szName, &dwNameSize, NULL, 위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해 설명드리지 않았군요. LONG RegEnumValue( 첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째 파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의 타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에 저장되겠군요. REG_BINARY 그 의미는 이미 앞에서 설명드렸을 겁니다. 일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다. dwNameSize = dwValueSize = 80; 역시 길이를 초기화 해주고 있습니다. sprintf(szPrint, "%s : %s", szName, szValue); 얻은 네임과 데이터를 화면에 출력해 주고 있습니다. dwValueCount++; 네임에 대한 인덱스를 증가해주고 있습니다. } 서브키에 대한 인덱스를 증가해주고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문이 돌고 있습니다. RegCloseKey(hKey); |
Registry
|
이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어 보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가 앞에서 배운 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_CLASSES_ROOT 두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른 서브키가 있으면 서브 디렉토리를 표시하던 식인 \\식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된 예약어를 지정해주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면 됩니다. 자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다. LONG RegQueryValueEx( 위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위 RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이 Default로 되어 있으면 그냥 ""식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의 저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다. 그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막 파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다. 데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야 합니다. LONG RegCloseKey( 위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서 닫아주면 되죠. 그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저 새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다. LONG RegCreateKeyEx( 첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미 RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면 되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데 이때 지정될 수 있는 예약어는 다음과 같습니다. REG_OPTION_VOLATILE 메모리에만 저장됩니다. 첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째 예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠? 여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는 NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한 결과가 저장될 변수의 주소를 지정해 주면 됩니다. 이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아 봅시다. LONG RegSetValueEx( 위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아 봅시다. 첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고 두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면 됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다. REG_BINARY 바이너리 형태입니다. 다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해 주면 되구요. 자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다. 먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다. 그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠. 원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다. LONG RegDeleteValue( 첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째 파라미터에는 지울 데이터의 네임을 지정해 주면 되구요. 이번에는 키 자체를 없애는 함수입니다. LONG RegDeleteKey( 첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에 포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠. 자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 47 |
|
안녕하세요……..돌팔이 황동준입니다…………….. 이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다. 아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그 데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : strcpy(szBuff, GetRegistry()); case 300 : DeleteRegistry(); case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, char* GetRegistry(void) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, void DeleteRegistry(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고 진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록 합시다. 제가 만든 세개의 함수 루틴만 보면 되겠네요. BOOL SetRegistry(void) 이 함수는 새로운 키를 생성하는 역할을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를 생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다. if(lRet != ERROR_SUCCESS) 성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로 짐작할 수 있을 겁니다. lRet = RegSetValueEx(hKey, "Install", NULL, REG_SZ, Install이라는 네임에 c:\doran20이라는 데이터를 저장하는 구문입니다. if(lRet != ERROR_SUCCESS) 역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요. RegCloseKey(hKey); 생성한 키를 닫는 구문입니다. return TRUE; char* GetRegistry(void) 이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다. HKEY hKey; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 데이터를 가져올 서브키를 열고 있습니다. if(lRet != ERROR_SUCCESS) Install이라는 네임에 해당하는 데이터를 가져오고 있습니다. if(lRet != ERROR_SUCCESS) void DeleteRegistry(void) 이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다. HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 지울 키를 얻고 있습니다. RegDeleteValue(hKey, "Install"); Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다. RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\DORAN 20"); 서브 키를 없애는 구문입니다. RegCloseKey(hKey); 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 48 |
|
안녕하세요…………돌팔이 황동준입니다…………… 이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는 서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는 먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지 개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다. 자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를 알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를 이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다. LONG RegQueryInfoKey ( 첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째 파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면 됩니다. 네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의 개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의 주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의 주소를 지정해주면 됩니다. 여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의 주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는 이 값을 이용할테니 그 의미를 알아 두시기 바랍니다. 아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고 열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막 파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게 다루었는지도 알아 보았을 겁니다. 자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가 무엇인지 알아내는 함수를 알아 봅시다. LONG RegEnumKeyEx( 바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는 루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어 우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로 지정해주면 되겠죠. 세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째 파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될 버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의 마지막 파라미터와 의미가 같습니다. 자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운 키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, ; 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 49 |
|
안녕하세요………….돌팔이 황동준입니다………………… 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 제가 만든 두개의 함수만 알아 보면 되겠죠? BOOL SetRegistry(void) 이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", 어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고 Install이라는 네임에 c:\doran20이라는 데이터를 저장하고 있는 구문입니다. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Version", if(lRet != ERROR_SUCCESS) 앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에 Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다. } 앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN 20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다. BOOL PrintSubRegistry(HWND hWnd) 이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을 합니다. HDC hDC; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, if(lRet != ERROR_SUCCESS) 알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, 이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을 지정하였습니다. if(lRet != ERROR_SUCCESS) 서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다. do 인덱스에 해당하는 서브키를 얻고 있는 구문입니다. dwSubKeySize = 80; 위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시 초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠. hDC = GetDC(hWnd); 얻은 서브키를 화면에 출력해 주는 구문입니다. dwCount++; 인덱스를 증가하고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문을 돌고 있습니다. RegCloseKey(hKey); 자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이 아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, } 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 50 |
|
안녕하세요…………..돌팔이 황동준입니다…………. 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 이번에는 함수 하나만 알아보면 되겠네요. BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 정보를 알아볼 서브키의 루크키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, if(lRet != ERROR_SUCCESS) 서브키의 개수를 알아내고 있습니다. dwCount = 0; 서브키를 알아내고 있는 구문입니다. dwSubKeySize = 80; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0, KEY_ALL_ACCESS, 알아낸 서브키를 열고 있는 구문입니다. lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, 그 서브키가 가지는 데이터의 개수를 얻고 있습니다. dwValueCount = 0; 데이터의 개수만큼 루프문을 반복하고 있습니다. RegEnumValue(hSubKey, dwValueCount, szName, &dwNameSize, NULL, 위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해 설명드리지 않았군요. LONG RegEnumValue( 첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째 파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의 타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에 저장되겠군요. REG_BINARY 그 의미는 이미 앞에서 설명드렸을 겁니다. 일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다. dwNameSize = dwValueSize = 80; 역시 길이를 초기화 해주고 있습니다. sprintf(szPrint, "%s : %s", szName, szValue); 얻은 네임과 데이터를 화면에 출력해 주고 있습니다. dwValueCount++; 네임에 대한 인덱스를 증가해주고 있습니다. } 서브키에 대한 인덱스를 증가해주고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문이 돌고 있습니다. RegCloseKey(hKey); |
Registry
|
이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어 보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가 앞에서 배운 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_CLASSES_ROOT 두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른 서브키가 있으면 서브 디렉토리를 표시하던 식인 \\식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된 예약어를 지정해주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면 됩니다. 자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다. LONG RegQueryValueEx( 위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위 RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이 Default로 되어 있으면 그냥 ""식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의 저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다. 그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막 파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다. 데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야 합니다. LONG RegCloseKey( 위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서 닫아주면 되죠. 그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저 새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다. LONG RegCreateKeyEx( 첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미 RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면 되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데 이때 지정될 수 있는 예약어는 다음과 같습니다. REG_OPTION_VOLATILE 메모리에만 저장됩니다. 첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째 예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠? 여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는 NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한 결과가 저장될 변수의 주소를 지정해 주면 됩니다. 이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아 봅시다. LONG RegSetValueEx( 위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아 봅시다. 첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고 두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면 됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다. REG_BINARY 바이너리 형태입니다. 다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해 주면 되구요. 자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다. 먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다. 그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠. 원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다. LONG RegDeleteValue( 첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째 파라미터에는 지울 데이터의 네임을 지정해 주면 되구요. 이번에는 키 자체를 없애는 함수입니다. LONG RegDeleteKey( 첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에 포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠. 자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 47 |
|
안녕하세요……..돌팔이 황동준입니다…………….. 이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다. 아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그 데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : strcpy(szBuff, GetRegistry()); case 300 : DeleteRegistry(); case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, char* GetRegistry(void) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, void DeleteRegistry(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고 진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록 합시다. 제가 만든 세개의 함수 루틴만 보면 되겠네요. BOOL SetRegistry(void) 이 함수는 새로운 키를 생성하는 역할을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를 생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다. if(lRet != ERROR_SUCCESS) 성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로 짐작할 수 있을 겁니다. lRet = RegSetValueEx(hKey, "Install", NULL, REG_SZ, Install이라는 네임에 c:\doran20이라는 데이터를 저장하는 구문입니다. if(lRet != ERROR_SUCCESS) 역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요. RegCloseKey(hKey); 생성한 키를 닫는 구문입니다. return TRUE; char* GetRegistry(void) 이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다. HKEY hKey; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 데이터를 가져올 서브키를 열고 있습니다. if(lRet != ERROR_SUCCESS) Install이라는 네임에 해당하는 데이터를 가져오고 있습니다. if(lRet != ERROR_SUCCESS) void DeleteRegistry(void) 이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다. HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 지울 키를 얻고 있습니다. RegDeleteValue(hKey, "Install"); Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다. RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\DORAN 20"); 서브 키를 없애는 구문입니다. RegCloseKey(hKey); 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 48 |
|
안녕하세요…………돌팔이 황동준입니다…………… 이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는 서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는 먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지 개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다. 자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를 알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를 이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다. LONG RegQueryInfoKey ( 첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째 파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면 됩니다. 네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의 개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의 주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의 주소를 지정해주면 됩니다. 여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의 주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는 이 값을 이용할테니 그 의미를 알아 두시기 바랍니다. 아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고 열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막 파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게 다루었는지도 알아 보았을 겁니다. 자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가 무엇인지 알아내는 함수를 알아 봅시다. LONG RegEnumKeyEx( 바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는 루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어 우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로 지정해주면 되겠죠. 세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째 파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될 버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의 마지막 파라미터와 의미가 같습니다. 자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운 키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, ; 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 49 |
|
안녕하세요………….돌팔이 황동준입니다………………… 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 제가 만든 두개의 함수만 알아 보면 되겠죠? BOOL SetRegistry(void) 이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", 어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고 Install이라는 네임에 c:\doran20이라는 데이터를 저장하고 있는 구문입니다. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Version", if(lRet != ERROR_SUCCESS) 앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에 Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다. } 앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN 20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다. BOOL PrintSubRegistry(HWND hWnd) 이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을 합니다. HDC hDC; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, if(lRet != ERROR_SUCCESS) 알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, 이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을 지정하였습니다. if(lRet != ERROR_SUCCESS) 서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다. do 인덱스에 해당하는 서브키를 얻고 있는 구문입니다. dwSubKeySize = 80; 위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시 초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠. hDC = GetDC(hWnd); 얻은 서브키를 화면에 출력해 주는 구문입니다. dwCount++; 인덱스를 증가하고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문을 돌고 있습니다. RegCloseKey(hKey); 자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이 아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, } 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 50 |
|
안녕하세요…………..돌팔이 황동준입니다…………. 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 이번에는 함수 하나만 알아보면 되겠네요. BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 정보를 알아볼 서브키의 루크키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, if(lRet != ERROR_SUCCESS) 서브키의 개수를 알아내고 있습니다. dwCount = 0; 서브키를 알아내고 있는 구문입니다. dwSubKeySize = 80; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0, KEY_ALL_ACCESS, 알아낸 서브키를 열고 있는 구문입니다. lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, 그 서브키가 가지는 데이터의 개수를 얻고 있습니다. dwValueCount = 0; 데이터의 개수만큼 루프문을 반복하고 있습니다. RegEnumValue(hSubKey, dwValueCount, szName, &dwNameSize, NULL, 위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해 설명드리지 않았군요. LONG RegEnumValue( 첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째 파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의 타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에 저장되겠군요. REG_BINARY 그 의미는 이미 앞에서 설명드렸을 겁니다. 일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다. dwNameSize = dwValueSize = 80; 역시 길이를 초기화 해주고 있습니다. sprintf(szPrint, "%s : %s", szName, szValue); 얻은 네임과 데이터를 화면에 출력해 주고 있습니다. dwValueCount++; 네임에 대한 인덱스를 증가해주고 있습니다. } 서브키에 대한 인덱스를 증가해주고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문이 돌고 있습니다. RegCloseKey(hKey); |
Registry
|
이번시간 부터는 레지스트리에 대한 것에 대해 알아 보겠습니다. 혹시 레지스트리라는것을 들어 보았습니까? 윈도우즈에서는 레지스트리라는 것이 존재하는데 이것은 일종의 하드웨어적, 소프트웨어적인 정보를 저장하고 있는 매체입니다. 우리가 앞에서 배운 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_CLASSES_ROOT 두번째 파라미터에는 우리가 정보를 가져올 서브키를 지정해 주면 됩니다. 서브키 내에 또다른 서브키가 있으면 서브 디렉토리를 표시하던 식인 \\식으로 표시해 주면 됩니다. 세번째 파라미터에는 0을 지정하면 되고 네번째 파라미터에는 지정된 예약어를 지정해주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 마지막 파라미터에는 서브키를 열었을때 얻어진 키 핸들을 저장할 변수의 주소를 지정해 주면 됩니다. 자 이제 서브키를 열었으니 그 키가 가지는 데이터를 가져오기만 하면 될 겁니다. LONG RegQueryValueEx( 위 함수를 이용해서 데이터를 가져올 수 있습니다. 첫번째 파라미터에는 위 RegOpenKeyEx() 함수에서 얻은 키 핸들을 지정하면 되고 두번째 파라미터에는 가져올 데이터가 가지는 네임을 지정해 주면 됩니다. 네임이 Default로 되어 있으면 그냥 ""식으로 지정해 주면 됩니다. 세번째 파라미터에는 0을 지정해 주면되고 네번째 파라미터에는 데이터의 저장형태가 저장될 변수의 주소를 지정해주면 됩니다. 이 저장형태는 뒤에 가서 레지스트리에 정보를 기록할때 다시 설명드리겠습니다. 그리고 다섯번째 파라미터에는 읽어온 데이터가 저장될 주소를 지정하면 됩니다. 마지막 파라미터에는 이 읽어온 데이터의 크기가 저장될 변수의 주소를 지정하면 됩니다. 데이터를 읽어오는 과정이 어렵지 않죠? 키를 열어서 작업을 다 했으면 그 키를 닫아 주어야 합니다. LONG RegCloseKey( 위 함수를 이용해서 연 키를 닫을수 있습니다. 물론 새로 생성한 키도 위 함수를 이용해서 닫아주면 되죠. 그러면 이번에는 정보를 기록하는 방법에 대해 알아 봅시다. 마찬가지로 어렵지 않습니다. 먼저 새로운 키를 생성하는 과정이 필요한데 그것은 아래 함수를 이용해서 하면 됩니다. LONG RegCreateKeyEx( 첫번째 파라미터에는 제일 상단에 있는 루트키를 지정해 주면 되는데 이 루트키는 이미 RegOpenKeyEx() 함수때 설명드렸을 겁니다. 두번째 파라미터에는 서브키를 지정해 주면 됩니다. 세번째 파라미터에는 NULL을 지정하면 되고 네번째 파라미터에는 클래스 이름을 지정해 주면 됩니다. 보통 NULL을 지정하죠. 다섯번째 파라미터에는 지정된 예약어를 지정해 주면 되는데 이때 지정될 수 있는 예약어는 다음과 같습니다. REG_OPTION_VOLATILE 메모리에만 저장됩니다. 첫번째 예약어를 사용하게 되면 메모리에만 저장되므로 시스템이 재시작되면 무효가 되나 두번째 예약어를 사용하게 되면 파일에 저장되므로 그 값이 계속 유효하게 됩니다. 어떤 차이인지 알겠죠? 여섯번째 파라미터에는 어세스 옵션을 지정해 주면 되는데 다음과 같은 예약어를 지정해 주면 됩니다. KEY_ALL_ACCESS 아래 모든 예약어를 만족합니다. 앞에서 알아본 RegOpenKeyEx()함수의 예약어와 같죠? 일곱번째 파라미터에는 NULL을 지정하면 되고 여덟번째 파라미터에는 이 키에 대한 핸들을 기억할 키 변수의 핸들을 지정해 주면 됩니다. 마지막 파라미터에는 키에 대한 결과가 저장될 변수의 주소를 지정해 주면 됩니다. 이제 키를 생성하는 함수를 알아보았으니 원하는 네임에 데이터를 지정하는 함수를 알아 봅시다. LONG RegSetValueEx( 위 함수를 이용해서 원하는 네임과 데이터를 지정해줄수 있는데 각 파라미터의 의미를 알아 봅시다. 첫번째 파라미터에는 RegCreateKeyEx()함수로 얻은 키 핸들을 지정해주면 되고 두번째 파라미터에는 네임을 지정해 주면됩니다. 세번째 파라미터에는 NULL을 지정해주면 되고 네번째 파라미터에는 데이터의 타입을 지정해주면 됩니다. 데이터의 타입은 아래의 예약어를 이용하면 됩니다. REG_BINARY 바이너리 형태입니다. 다섯번째 파라미터에는 데이터를 지정해주면 됩니다. 마지막 파라미터에는 데이터의 길이를 지정해 주면 되구요. 자 그러면 이번에는 키를 삭제하는 방법을 알아 봅시다. 먼저 지울 키를 RegOpenKeyEx()함수를 이용해서 핸들 형태로 반환을 받아야 합니다. 그래서 그 핸들을 이용해서 원하는 네임의 데이터를 삭제하면 되죠. 원하는 네임의 데이터를 지울 때에는 아래 함수를 사용하면 됩니다. LONG RegDeleteValue( 첫번째 파라미터에 지울 네임이 속해 있는 키의 핸들을 지정해 주면 됩니다. 두번째 파라미터에는 지울 데이터의 네임을 지정해 주면 되구요. 이번에는 키 자체를 없애는 함수입니다. LONG RegDeleteKey( 첫번째 파라미터에는 최상위 루트 키의 이름을 지정해주면 되고 두번째 파라미터에는 그 안에 포함된 지울 서브키의 이름을 지정해 주면 됩니다. 사용방법이 간단하죠. 자 그러면 위에서 배운 함수들을 이용해서 실제로 프로그램을 만들어 봅시다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 47 |
|
안녕하세요……..돌팔이 황동준입니다…………….. 이번시간에는 저번시간에 알아 본 함수들을 이용해서 프로그램을 만들어 보겠습니다. 아래 프로그램은 레지스트리에 원하는 키를 생성해서 거기에 데이터를 기록한 뒤 실제로 그 데이터를 가져오고 하는 기능을 가졌습니다. 물론 지우는 기능도 있구요. 앞부분에서 함수를 잘 이해한 분들은 그렇게 어렵지 않을 겁니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : strcpy(szBuff, GetRegistry()); case 300 : DeleteRegistry(); case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, char* GetRegistry(void) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, void DeleteRegistry(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 자 프로그램을 실행시켜 첫번째 메뉴 아이템인 Set Registry를 선택해 보세요. 그리고 진짜로 그 키가 생성되었는지 레지스트리 편집기로 확인해 보시기 바랍니다. 어때요? 정말로 생성되어 있죠? 자 그러면 소스를 보도록 합시다. 제가 만든 세개의 함수 루틴만 보면 되겠네요. BOOL SetRegistry(void) 이 함수는 새로운 키를 생성하는 역할을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", NULL, HKEY_LOCAL_MACHINE 부분에 있는 Software내에 DORAN 20이라는 키를 생성하고 있는 구문입니다. 물론 Software라는 서브키가 존재하지 않으면 새로 생성합니다. if(lRet != ERROR_SUCCESS) 성공적으로 함수가 수행되면 ERROR_SUCESS라는 리터값이 발생된다는 것을 위 구문으로 짐작할 수 있을 겁니다. lRet = RegSetValueEx(hKey, "Install", NULL, REG_SZ, Install이라는 네임에 c:\doran20이라는 데이터를 저장하는 구문입니다. if(lRet != ERROR_SUCCESS) 역시 함수가 성공적으로 수행되면 ERROR_SUCCESS라는 리턴값이 발생되는군요. RegCloseKey(hKey); 생성한 키를 닫는 구문입니다. return TRUE; char* GetRegistry(void) 이 함수는 원하는 서브키의 데이터를 가져오는 역할을 합니다. HKEY hKey; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 데이터를 가져올 서브키를 열고 있습니다. if(lRet != ERROR_SUCCESS) Install이라는 네임에 해당하는 데이터를 가져오고 있습니다. if(lRet != ERROR_SUCCESS) void DeleteRegistry(void) 이 함수는 첫번째 메뉴 아이템에 의해 생성된 키와 데이터를 삭제하는 역할을 합니다. HKEY hKey; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, KEY_ALL_ACCESS, 지울 키를 얻고 있습니다. RegDeleteValue(hKey, "Install"); Install 네임을 가지고 있는 데이터를 삭제하는 구문입니다. RegDeleteKey(HKEY_LOCAL_MACHINE, "Software\\DORAN 20"); 서브 키를 없애는 구문입니다. RegCloseKey(hKey); 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 48 |
|
안녕하세요…………돌팔이 황동준입니다…………… 이번시간에도 레지스트리에 대해 더 알아 보겠습니다. 이번에 알아 볼 것은 어떤 키에 속해있는 서브키를 어떻게 얻을 수 있는지 입니다. 물론 우리는 먼저 크게 두단계로 나누어서 합니다. 첫번째 단계는 바로 원하는 키에 서브키가 몇개 있는지 개수를 알아내는 것입니다. 두번째 단계는 이 개수를 가지고 차례로 키 포인터를 이동시켜 서브키를 얻는 것입니다. 자 그러면 실제로 어떤 식으로 구현하는지 필요한 함수를 보도록 합시다. 먼저 서브키의 개수를 알아야 하는데 이때 필요한 함수의 첫번째 파라미터에 키 핸들을 지정해야 하는데 이 키 핸들은 앞에서 배운 RegOpenKeyEx()함수를 이용하면 됩니다. 그러면 키의 개수를 얻을 수 있는 함수를 보도록 합시다. LONG RegQueryInfoKey ( 첫번째 파라미터로 RegOpenKeyEx()함수에서 얻은 키 핸들을 지정하면 됩니다. 두번째 파라미터에는 클래스 이름이 저장될 버퍼의 주소를 세번째 파라미터에는 그 클래스 버퍼의 크기를 가지고 있는 변수의 주소를 지정해 주면 됩니다. 네번째 파라미터에는 0을 지정하면되고 다섯번째 파라미터인 lpcSubKeys에는 서브키의 개수가 저장될 변수의 주소를 지정해 주면 됩니다. 여섯번째 파라미터에는 서브키의 이름중 가장 긴 이름을 가진 서브키의 길이가 저장될 변수의 주소를 지정해주면 됩니다. 사실 이 값은 잘 쓰이지 않죠. 역시 일곱번째 파라미터도 서브키에 대한 클래스이름이 가장 긴 길이가 저장될 변수의 주소를 지정해주면 됩니다. 여덟번째 파라미터인 lpcValues에는 지정해준 키에 대한 데이터의 개수가 저장 될 변수의 주소를 지정해주면 되는데 우리가 지금 만들어볼 프로그램은 단지 서브키의 개수만 알아볼거니 사실 이 값이 필요없습니다. 그러나 다음 프로그램에서는 이 값을 이용할테니 그 의미를 알아 두시기 바랍니다. 아홉번째 파라미터에는 가장 긴 네임에 대한 길이가 저장될 변수의 주소를 지정해주면 되고 열번째 파라미터에는 가장긴 데이터의 길이가 저장될 변수의 주소를 지정해 주면 됩니다. 열한번째 파라미터에는 NULL을 지정하면 되고 마지막 파라미터에는 주어진 키에대한 시간정보를 저장할 구조체 변수의 주소를 지정해 주면 됩니다. 이 구조체는 이미 앞에서 알아보았고 또 어떻게 다루었는지도 알아 보았을 겁니다. 자 서브키나 데이터의 개수를 위 함수로 알아 냈으니 이번에는 실제로 그 서브키나 데이터가 무엇인지 알아내는 함수를 알아 봅시다. LONG RegEnumKeyEx( 바로 위 함수를 이용해서 알아 낼 수 있습니다. 첫번째 파라미터에 알아낼 서브키가 속해있는 루트 키의 핸들을 지정해 주면 되고 두번째 파라미터에 서브키의 인덱스를 지정해주면 됩니다. 서브키의 인덱스는 0부터 시작합니다. 예를 들어 우리가 위의 RegQueryInfoKey() 함수로 서브키의 개수를 알아 내었다면 0부터 차례로 그 개수에서 1을 뺀값까지 이 파라미터로 지정해주면 되겠죠. 세번째 파라미터에는 해당하는 인텍스의 서브키가 들어갈 버퍼를 지정해 주면 되고 네번째 파라미터에는 그 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 다섯번째 파라미터에는 NULL을 지정해 주면 되고 여섯번째 파라미터에는 클래스 이름이 저장될 버퍼를 지정해주면 됩니다. 일곱번째 파라미터에는 클래스 이름이 저장 될 버퍼의 크기가 저장된 변수의 주소를 지정해 주면 됩니다. 마지막 파라미터는 설명 드릴필요는 없겠군요. 앞의 RegQueryInfoKey() 함수의 마지막 파라미터와 의미가 같습니다. 자 그러면 실제로 이것을 이용한 프로그램을 만들어 봅시다. 아래 프로그램은 새로운 키를 생성하고 그 키에 포함된 서브키가 어떤것들인지 화면에 출력해 주는 기능을 가졌습니다. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, ; 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 49 |
|
안녕하세요………….돌팔이 황동준입니다………………… 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 제가 만든 두개의 함수만 알아 보면 되겠죠? BOOL SetRegistry(void) 이 함수는 우리가 어떤 서브키가 있는지 테스트해보기 위해 임시로 서브키를 만드는 기능을 합니다. HKEY hKey; lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", 어떤 서브키를 만드는지 굳이 설명드릴 필요는 없죠? 바로 Install이라는 서브키를 만들고 Install이라는 네임에 c:\doran20이라는 데이터를 저장하고 있는 구문입니다. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Version", if(lRet != ERROR_SUCCESS) 앞에서 만든 DORAN 20이라는 서브키에 다시 Version이라는 서브키를 생성하고 네임에 Version을 그 네임에 해당하는 데이터는 2.0을 지정하는 구문입니다. } 앞에서 한부분이므로 이해가 안가는 부분은 없을 겁니다. 위 함수가 수행되면 DORAN 20이라는 서브키에 Install, Version이라는 서브키가 생성되어 있을 겁니다. BOOL PrintSubRegistry(HWND hWnd) 이 함수는 DORAN 20 서브키에 속해 있는 서브키를 찾아서 화면에 출력해주는 역할을 합니다. HDC hDC; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, if(lRet != ERROR_SUCCESS) 알아 볼 서브키가 포함되어 있는 부모 키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, 이번에 알아 볼것은 단지 서브키의 개수이므로 데이터의 개수가 저장될 파라미터에는 NULL을 지정하였습니다. if(lRet != ERROR_SUCCESS) 서브키의 개수만큼 인덱스를 증가하기 위해 위 dwCount라는 변수를 사용하였습니다. do 인덱스에 해당하는 서브키를 얻고 있는 구문입니다. dwSubKeySize = 80; 위 함수가 수행되면 dwSubKeySize에 실제 크기가 저장되므로 이 값을 다시 초기화해주고 있습니다. 왜냐하면 위 함수를 사용할 때 버퍼의 크기가 저장된 변수의 주소를 지정하기 때문이죠. hDC = GetDC(hWnd); 얻은 서브키를 화면에 출력해 주는 구문입니다. dwCount++; 인덱스를 증가하고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문을 돌고 있습니다. RegCloseKey(hKey); 자 그러면 이번에는 좀더 진보적인 프로그램을 만들어 봅시다. 바로 서브키만 알아내는 것이 아니라 그 안에 속해있는 네임과 데이터도 알아내는 거죠. MyMenu MENU #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain WndClass.style = CS_HREDRAW|CS_VREDRAW; hWnd = CreateWindow( ShowWindow(hWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) return msg.wParam; LRESULT CALLBACK switch(message) switch(LOWORD(wParam)) if(!SetRegistry()) case 200 : if(!PrintSubRegistry(hWnd)) case WM_DESTROY : PostQuitMessage(0); BOOL SetRegistry(void) lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20\\Install", if(lRet != ERROR_SUCCESS) BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, } 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 윈도우 32비트 프로그래밍 50 |
|
안녕하세요…………..돌팔이 황동준입니다…………. 이번시간에는 저번시간에 만든 프로그램을 분석해 보겠습니다. 이번에는 함수 하나만 알아보면 되겠네요. BOOL PrintSubRegistry(HWND hWnd) lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\DORAN 20", 0, 정보를 알아볼 서브키의 루크키를 여는 구문입니다. lRet = RegQueryInfoKey(hKey, NULL, 0, 0, &dwSubKeyNumber, NULL, NULL, if(lRet != ERROR_SUCCESS) 서브키의 개수를 알아내고 있습니다. dwCount = 0; 서브키를 알아내고 있는 구문입니다. dwSubKeySize = 80; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuff, 0, KEY_ALL_ACCESS, 알아낸 서브키를 열고 있는 구문입니다. lRet = RegQueryInfoKey(hSubKey, NULL, 0, 0, NULL, NULL, NULL, 그 서브키가 가지는 데이터의 개수를 얻고 있습니다. dwValueCount = 0; 데이터의 개수만큼 루프문을 반복하고 있습니다. RegEnumValue(hSubKey, dwValueCount, szName, &dwNameSize, NULL, 위 함수로 인덱스에 해당하는 네임과 데이터를 얻을 수 있는데 위에서 이 함수에 대해 설명드리지 않았군요. LONG RegEnumValue( 첫번째 파라미터에는 얻을 네임이 포함되어 있는 서브키의 핸들을 지정해 주면됩니다. 두번째 파라미터에는 네임의 인덱스를 지정해 주면 되는데 역시 0부터 지정해주면 됩니다. 세번째 파라미터에는 네임이 저장될 버퍼를 네번째 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 다섯 번째 파라미터에는 NULL을 지정하면 되고 여섯번째 파라미터에는 데이터의 타입이 저장될 변수의 주소를 지정해 주면 됩니다. 이 데이터 타입은 앞에서 이미 알아 본 것입니다. 아래와 같은 예약어들이 함수 사용한 후에 저장되겠군요. REG_BINARY 그 의미는 이미 앞에서 설명드렸을 겁니다. 일곱번째 파라미터에는 데이터가 저장될 버퍼를 지정하면 되고 마지막 파라미터에는 이 버퍼의 크기가 저장되어 있는 변수의 주소를 지정해 주면 됩니다. 함수 설명을 했으니 계속해서 해당 루틴을 알아 보도록 하겠습니다. dwNameSize = dwValueSize = 80; 역시 길이를 초기화 해주고 있습니다. sprintf(szPrint, "%s : %s", szName, szValue); 얻은 네임과 데이터를 화면에 출력해 주고 있습니다. dwValueCount++; 네임에 대한 인덱스를 증가해주고 있습니다. } 서브키에 대한 인덱스를 증가해주고 있습니다. } while(dwCount<dwSubKeyNumber); 서브키의 개수만큼 루프문이 돌고 있습니다. RegCloseKey(hKey); |