Admin | Write | GuestBook
[공지] 해당 블로그에 용건이 있으신 분께서는 http://blog.fore.kr/ 의 방명록(Guestbook)으로 부탁드립니다.
CreateDialogBoxIndirectParam, DialogBoxIndirectParam 구현.
Category : Programming/Programming Talk | URL : | Written by 포레 ( 2013. 5. 17. 03:03 ) | 신고

 

[힐끗]

 

CreateDialogBoxIndirectParam, DialogBoxIndirectParam 이놈들에 대해 이야기 해보자.

 

이녀석들을 쓰면 좋은 점이라면, 사용자로 하여금 리소스로 설정된 다이어로그를

 

리소스 수정 프로그램으로 수정시킬 수 없게 만든다는 점 외에는 장점이 없다.

( 그래봐야, 리버싱하면 리소스 수정 프로그램도 무력화된다. )

 

리소스 수정 프로그램은 이에 관련해 무지한 사람이더라도

 

인터페이스를 사용자가 손쉽게 수정 가능하니, 이를 방지하기 위해 한번 손으로 코드를 구현해보았다.

 

 

 HWND WINAPI CreateDialogIndirectParam(
  _In_opt_  HINSTANCE hInstance,
  _In_      LPCDLGTEMPLATE lpTemplate,
  _In_opt_  HWND hWndParent,
  _In_opt_  DLGPROC lpDialogFunc,
  _In_      LPARAM lParamInit
 );

 INT_PTR WINAPI DialogBoxIndirectParam(
  _In_opt_  HINSTANCE hInstance,
  _In_      LPCDLGTEMPLATE hDialogTemplate,
  _In_opt_  HWND hWndParent,
  _In_opt_  DLGPROC lpDialogFunc,
  _In_      LPARAM dwInitParam
 );

 

 < 출처 >

 http://msdn.microsoft.com/en-us/library/windows/desktop/ms645441(v=vs.85).aspx 

 http://msdn.microsoft.com/en-us/library/windows/desktop/ms645461(v=vs.85).aspx

 

 

일단 함수들은 이렇게 생기셨다.

 

근데 이녀석들의 웃긴점은

 

두번째 인자가 LPCDLGTEMPLATE 되어 있지만, 실제 DLGTEMPLATE 값만 넘기면 실행되지 않는다.

 

왜냐하면, DLGTEMPLATE 은 하나의 헤더일 뿐, 내용이 들어가지 않기 때문이다.

 

구현은 이렇게 . . .

 

 

#include <windows.h>
#include <tchar.h>

 

// 유저 윈도우 이름 정의
#define USER_WINDOW_NAMEW   L"TestWindow"
#define USER_WINDOW_NAMEA    "TestWindow"

#ifdef UNICODE
 #define USER_WINDOW_NAME USER_WINDOW_NAMEW
#else
 #define USER_WINDOW_NAME USER_WINDOW_NAMEA
#endif //  UNICODE

 

// 다이어로그 기본 템플릿 재정의
// DLGTEMPLATE : http://msdn.microsoft.com/en-us/library/windows/desktop/ms645394(v=vs.85).aspx
// 추가 옵션 : http://msdn.microsoft.com/en-us/library/windows/desktop/ms644996(v=vs.85).aspx
typedef struct _USERDLGTEMPLATE{
 DLGTEMPLATE   Template;
 WORD    wMenu;
 WORD    wDialogBoxClass;
 WCHAR    tDialogBoxTitle[1];
 // 이 아래부터는 다이어로그에 관련된 아이템이 있지만 귀찮으므로 생략한다.
}USERDLGTEMPLATE, *PUSERDLGTEMPLATE;

 

// 다이어로그 메시지 처리
int CALLBACK DlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
 switch(uMsg){
  case WM_CLOSE:
   DestroyWindow(hDlg);
  break;
  case WM_DESTROY:
   EndDialog(hDlg,0);
  break;
 }
 return FALSE;
}

 

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
 // 유저 템플릿을 생성한다.
 // 윈도우 이름을 동적으로 할당하기 위해 포인터로 생성함.
 PUSERDLGTEMPLATE   pTemplate;

 // 위 구조체 크기를 계산하기 위해 임시변수 할당함.
 int       nLength;

 // 기존 템플릿 크기 + 윈도우 이름(유니코드) 사이즈 + 여분 공간(1) 을 할당할 준비함.
 // 윈도우 이름은 ANSI 함수를 사용해도 IndirectParam 함수에선 윈도우 이름에 대해서 유니코드로 인식한다.
 nLength = (sizeof(USERDLGTEMPLATE)+(lstrlenW(USER_WINDOW_NAMEW)+1)*sizeof(WCHAR));

 // 메모리 할당
 pTemplate = (PUSERDLGTEMPLATE)malloc(nLength);

 // 메모리를 죄다 0으로 초기화.
 memset(pTemplate,0,nLength);

 // 윈도우 이름을 복사함.
 // ANSI를 사용해도 IndirectParam 함수에선 유니코드로 인식한다.
 lstrcpyW((LPWSTR)&pTemplate->tDialogBoxTitle,USER_WINDOW_NAMEW);

 // 템플릿 옵션 설정함.
 pTemplate->Template.style = WS_VISIBLE | WS_SYSMENU;
 pTemplate->Template.cx = 100;
 pTemplate->Template.cy = 100;

 // 다이어로그 생성
 DialogBoxIndirectParam(NULL,(LPDLGTEMPLATE)pTemplate,NULL,DlgProc,NULL);

 // 메모리 해제
 free(pTemplate);

 return 0;
}

 

 

그냥 귀찮아서 간략하게 구현했는데

 

자세한건 http://msdn.microsoft.com/en-us/library/windows/desktop/ms644996(v=vs.85).aspx 을 보면

 

다이어로그 안에 생성되는 윈도우를 좀 더 자세히 구현할 수 있지만

 

차라리 저렇게 구현할 바에야 CreateWindowEx 나 그냥 리소스로 구현해버리고 말겠다.

 

Category
분류 전체보기 (605)
Notice (6)
Programming (79)
DISKER (1)
FSCH (7)
Caption (0)
Rest Time ! (443)
Hobby (64)
Tour (5)
Blind Post (0)
Recent Post
Recent Comment
Link
Calender
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Total :
Today :
Yesterday :