340 likes | 563 Views
Windows API. 26 장 . 레지스트리. 26-1 INI 파일 26-2 레지스트리. 26-1 INI 파일. 정보의 저장. 함수. BOOL WritePrivateProfileString ( LPCTSTR lpAppName // 기록할 섹선이름 , LPCTSTR lpKeyName // 기록할 키이름 NULL- 섹션삭제 ,LPCTSTR lpString // 키값을 정의하는 문자열 , LPCSTR lpFileName //ini 파일명 ).
E N D
Windows API 26장. 레지스트리 26-1 INI파일 26-2 레지스트리
26-1 INI 파일 • 정보의 저장
함수 BOOL WritePrivateProfileString ( LPCTSTR lpAppName //기록할 섹선이름 , LPCTSTR lpKeyName//기록할 키이름 NULL-섹션삭제 ,LPCTSTR lpString //키값을 정의하는 문자열 , LPCSTR lpFileName //ini파일명 )
UINT GetPrivateProfileInt ( LPCTSTR lpAppName,//기록할 섹선이름 LPCTSTR lpKeyName,//기록할 키이름 NULL-섹션삭제 INT nDefault, //디폴트 값 LPCTSTR lpFileName //ini파일명 )
DWORD GetPrivateProfileString ( LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPTSTR lpReturnedString, //문자열을대입받을버퍼 DWORD nSize, //버퍼의크기 LPCSTR lpFileName, )
26-2 레지스트리 • 가.INI 파일의 단점 • 텍스트파일 포맷으로 저장-사용자임의조작가능->오작동 가능성. • 디스크공간 낭비 • 복수사용자 지원하지 않음. • 손상시 복구 불가. • 느리다.
LONG RegCreateKeyEx( HKEY hKey, // 새로 만들어 지는 키의 부모키 LPCTSTR lpSubKey, // "Software\\KanamSoft\\RegiTest\\Position", DWORD Reserved, //예약된 인수 LPTSTR lpClass, //생성된 키의 클래스 지정 DWORD dwOption, //생성하는 키의 옵션 REGSAM samDesired, //키의 보안속성 LPSECURITY_ATTRIBUTES lpSecurityAttributes, //생성된 키값이 차일드로 상속될것인가 ? NULL-상속안됨 PHKEY phkResult, //키값이 대입되는 변수 포인터 LPDWORD lpdwDisposition //생성되었는지 오픈되었는지 출력용변수 )
LONG RegSetValueEx( HKEY hKey, LPCTSTR lpvalueName, //값의 이름지정 DWORD Reserved, DWORD dwType, CONST BYTE *lpData, //저장하고자하는 데이터 DWORD cbData )
LONG RegQueryValueEx( HKEY hKey, LPTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, //읽을값의 타입받을변수포인터 LPBYTE lpData, LPDWORD lpcbData //lpData의 크기 )
LONG RegCloseKey(HKEY hKey) • LONG RegOpenKeyEx( HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, PHKEY phkResult )
Regi LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam) { RECT rt; HKEY key; DWORD dwDisp; DWORD Size; switch(iMessage) { case WM_CREATE: RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\KanamSoft\\RegiTest\\Position",0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,NULL,&key,&dwDisp); Size=sizeof(LONG); if (RegQueryValueEx(key, "Left", 0, NULL,(LPBYTE)&rt.left, &Size) !=ERROR_SUCCESS) rt.left=0; Size=sizeof(LONG); if (RegQueryValueEx(key, "Top", 0, NULL,(LPBYTE)&rt.top, &Size) !=ERROR_SUCCESS) rt.top=0;
Size=sizeof(LONG); if (RegQueryValueEx(key, "Right", 0, NULL,(LPBYTE)&rt.right, &Size)!=ERROR_SUCCESS) rt.right=100; Size=sizeof(LONG); if (RegQueryValueEx(key, "Bottom", 0, NULL,(LPBYTE)&rt.bottom, &Size) !=ERROR_SUCCESS) rt.bottom=100;; RegCloseKey(key); MoveWindow(hWnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, TRUE); return 0;
case WM_DESTROY: RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\KanamSoft\\RegiTest\\Position",0,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,NULL,&key,&dwDisp); GetWindowRect(hWnd, &rt); RegSetValueEx(key, "Left",0,REG_DWORD,(LPBYTE)&rt.left, sizeof(LONG)); RegSetValueEx(key, "Top",0,REG_DWORD,(LPBYTE)&rt.top, sizeof(LONG)); RegSetValueEx(key, "Right",0,REG_DWORD,(LPBYTE)&rt.right, sizeof(LONG)); RegSetValueEx(key, "Bottom",0,REG_DWORD, (LPBYTE)&rt.bottom,sizeof(LONG)); RegCloseKey(key); PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd,iMessage,wParam,lParam)); }
26-3 레지스트리 관리 • 가. 미리정의된 키 • HKEY_USER • HKEY_LOCAL_MACHINE • HKEY_CURRENT_USER • HKEY_CLASSES_ROOT • HKEY_CURRENT_CONFIG
나. 비우기 LONG RegFlushKey( HKEY hKey ) • 다. 삭제 LONG RegDeleteKey(HKEY hKey, LPCTSTR lpValueName )
라.정보조사 LONG RegQueryInfoKey( HKEY hKey, // 조사하고자하는 키의 핸들 LPTSTR lpClass, // 클래스 스트링 LPDWORD lpcbClass, // 클래스 스트링의 버퍼크기 LPDWORD lpReserved, // 예약 LPDWORD lpcSubKeys, // 서브키의 개수 LPDWORD lpcbMaxSubKeyLen, // 가장긴이름의 서브키의 길이 LPDWORD lpcbMaxClassLen, // 가장 긴 이름의 클래스길이 LPDWORD lpcValues, //값의 개수 LPDWORD lpcbMaxValueNameLen, // 가장긴 이름의 값길이 LPDWORD lpcbMaxValueLen, // 가장 긴 데이터길이 LPDWORD lpcbSecurityDescriptor, // 보안속성의 길이 PFILETIME lpftLastWriteTime //최후수정시간);
마. 열거 LONG RegEnumKeyEx( HKEY hKey, // handle to key to enumerate DWORD dwIndex, // index of subkey to enumerate LPTSTR lpName, // address of buffer for subkey name LPDWORD lpcbName, // address for size of subkey buffer LPDWORD lpReserved, // reserved LPTSTR lpClass, // address of buffer for class string LPDWORD lpcbClass, // address for size of class buffer PFILETIME lpftLastWriteTime // address for time key last written to );
LONG RegEnumValue( HKEY hKey, // handle to key to query DWORD dwIndex, // index of value to query LPTSTR lpValueName, // address of buffer for value string LPDWORD lpcbValueName, // address for size of value buffer LPDWORD lpReserved, // reserved LPDWORD lpType, // address of buffer for type code LPBYTE lpData, // address of buffer for value data LPDWORD lpcbData // address for size of data buffer );
RegEnum void RegEnum(HKEY); void DblClk(void); void SelChange(void); // 차일드 컨트롤들 #define ID_LISTBOX 100 #define ID_EDIT 101 #define ID_BUTTON 102 HWND hList; HWND hEdit; HWND hButton; HWND hStatic; LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam) { HKEY key; char str[MAX_PATH]; switch(iMessage) {
// 차일드 윈도우를 만든다. case WM_CREATE: hList=CreateWindow("listbox",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER |LBS_NOTIFY | WS_VSCROLL, 10,50,200,400,hWnd,(HMENU)ID_LISTBOX,g_hInst,NULL); hEdit=CreateWindow("edit","software",WS_CHILD | WS_VISIBLE | WS_BORDER |ES_AUTOHSCROLL, 10,10,400,25, hWnd,(HMENU)ID_EDIT,g_hInst,NULL); hButton=CreateWindow("button","Enumerate",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,420,10,100,25, hWnd,(HMENU)ID_BUTTON,g_hInst,NULL); hStatic=CreateWindow("static","표시할 내용이 없습니다.", WS_CHILD | WS_VISIBLE, ,0,0,0,0,hWnd,(HMENU)-1,g_hInst,NULL); // 프로그램 시작 직후에 software 아래의 키를 조사한다. SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(ID_BUTTO N,BN_CLICKED),(LPARAM)hButton); return 0;
case WM_COMMAND: switch (LOWORD(wParam)) { // 버튼 누름:에디트의 키값으로 순회한다. case ID_BUTTON: GetWindowText(hEdit,str,MAX_PATH); if (RegOpenKeyEx(HKEY_CURRENT_USER, str,0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS) { RegEnum(key); RegCloseKey(key); } else { MessageBox(hWnd,"지정한 키를 열 수 없습 니다","에러",MB_OK); } break; // 리스트 박스의 클릭과 더블 클릭 처리 case ID_LISTBOX: switch (HIWORD(wParam)) { case LBN_DBLCLK: DblClk(); break;
case LBN_SELCHANGE: SelChange(); break; } break; } return 0; case WM_SIZE: MoveWindow(hEdit,10,10,LOWORD(lParam)-130,25,TRUE); MoveWindow(hButton,LOWORD(lParam)-110,10,100,25,TRUE); MoveWindow(hList,10,50,LOWORD(lParam)-20,HIWORD(lParam)-80,TRUE); MoveWindow(hStatic,10,HIWORD(lParam)-30,LOWORD(lParam)-20,25,TRUE); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd,iMessage,wParam,lParam)); }
void RegEnum(HKEY key) { char lpSubKey[MAX_PATH]; char lpValue[MAX_PATH]; char lpBuffer[MAX_PATH]; DWORD i; LONG Result; DWORD Size; FILETIME FileTime; SendMessage(hList,LB_RESETCONTENT,0,0); SendMessage(hList,LB_ADDSTRING,0,(LPARAM)" ^^^ 한 단계 위로 ^^^ "); // 서브키의 목록의 조사해 리스트 박스에 채워 넣는다. Result=ERROR_SUCCESS; for (i=0;Result==ERROR_SUCCESS;i++) { Size=MAX_PATH;
Result=RegEnumKeyEx(key,i,lpSubKey,&Size,NULL,NULL,NULL,&FileTime); Result=RegEnumKeyEx(key,i,lpSubKey,&Size,NULL,NULL,NULL,&FileTime); if (Result==ERROR_SUCCESS) { wsprintf(lpBuffer,"K : %s",lpSubKey); SendMessage(hList,LB_ADDSTRING,0,(LONG)lpBuffer); } } // 값의 목록을 조사해 리스트 박스에 채워 넣는다. Result=ERROR_SUCCESS; for (i=0;Result==ERROR_SUCCESS;i++) { Size=MAX_PATH; Result=RegEnumValue(key,i,lpValue,&Size,NULL,NULL,NULL,NULL); if (Result==ERROR_SUCCESS) { wsprintf(lpBuffer,"V : %s",lpValue); SendMessage(hList,LB_ADDSTRING,0,(LONG)lpBuffer); } } }
void DblClk(void) { int index; char buffer[MAX_PATH]; char Caption[MAX_PATH]; char Post[MAX_PATH]; char *backslash; index=SendMessage(hList,LB_GETCURSEL,0,0); // 한단계 위로 처리 if (index==0) { GetWindowText(hEdit,Caption,MAX_PATH); backslash=strrchr(Caption, '\\'); if (backslash==NULL) { MessageBox(g_hWndMain,"더 올라갈 곳이 없습니다요","잠깐!",MB_OK); return; } backslash[0]=0; SetWindowText(hEdit,Caption);
SendMessage(g_hWndMain,WM_COMMAND, MAKEWPARAM(ID_BUTTON,BN_CLICKED),(LPARAM)hButton); return; } // 키를 더클릭했을 경우 해당 키를 조사한다. SendMessage(hList,LB_GETTEXT,index,(LPARAM)buffer); strcpy(Post,buffer+4); if (buffer[0]=='K') { GetWindowText(hEdit,Caption,MAX_PATH); wsprintf(buffer,"%s\\%s",Caption,Post); SetWindowText(hEdit,buffer); SendMessage(g_hWndMain,WM_COMMAND,MAKEWPARAM (ID_BUTTON,BN_CLICKED), (LPARAM)hButton); } }
void SelChange(void) { int index; char buffer[MAX_PATH]; char Caption[MAX_PATH]; char Post[MAX_PATH]; HKEY key; DWORD cSubKeys, cValues; DWORD Type, Size; BYTE Data[MAX_PATH]; index=SendMessage(hList,LB_GETCURSEL,0,0); // 한단계 위로에 대해서는 전혀 반응하지 않는다. if (index==0) return; SendMessage(hList,LB_GETTEXT,index,(LPARAM)buffer); strcpy(Post,buffer+4);
// 키에 속한 서브키와 값의 개수 조사 if (buffer[0]=='K') { GetWindowText(hEdit,Caption,MAX_PATH); wsprintf(buffer,"%s\\%s",Caption,Post); if (RegOpenKeyEx(HKEY_CURRENT_USER, buffer,0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS) { RegQueryInfoKey(key,NULL,NULL,NULL,&cSubKeys,NULL ,NULL,&cValues,NULL,NULL,NULL,NULL); RegCloseKey(key); wsprintf(Caption,"서브키의 수:%d, 값의 수:%d",cSubKeys,cValues); SetWindowText(hStatic,Caption); } }
else if (buffer[0]=='V') { GetWindowText(hEdit,Caption,MAX_PATH); if (RegOpenKeyEx(HKEY_CURRENT_USER, Caption,0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS) { Size=MAX_PATH; RegQueryValueEx(key,Post,NULL,&Type,Data,&Size); RegCloseKey(key); switch (Type) { case REG_DWORD: wsprintf(Caption,"데이터 타입:정수형, 데이터:%d",*(LPDWORD)Data); break; case REG_SZ: wsprintf(Caption,"데이터 타입:문자열, 데이터:%s",Data); break; default: wsprintf(Caption,"데이터 타입:%d, 데이터:%s",Type,Data); break; } SetWindowText(hStatic,Caption); } } }