[Win32]创建模态窗口

Win32编程中,如果要显示一个模态窗口,一般是先创建对话框模板,然后使用DialogBox来显示对话框。这种做法很简单,但存在一个问题:对话框是以资源的形式保存在可执行文件中的,如果可执行文件没有进行加壳处理的话,任何人都可以通过ExeScope等资源修改工具修改对话框的内容,这对于含有版权信息的“关于”对话框来说是非常危险的,怀有不良目的的人只需进行简单的操作就可以将一个软件变成是自己的。

 

保护软件的版权信息不被修改有很多种方法,在这里我想说的一种方法是用代码来创建“关于”对话框的内容,在运行时才创建这个对话框,而不是通过对话框模板早早就创建好。既然不使用对话框模板,那就不能使用DialogBox函数来显示模态的对话框了,所以这种方法的一个难点就是如何不使用DialogBox来创建一个模态的窗口。本文的重点在于如何解决这个难点,而不在于如何在运行时创建窗口的内容。

 

通过查阅MSDN,可以知道DialogBox实际上是一个宏,它调用DialogBoxParam函数来创建对话框。而后者通过CreateWindowEx函数创建窗口,然后disables父窗口,并开启一个新的消息循环来处理对话框的消息。我们可以自己实现这个过程。

 

首先创建一个父窗口:

 1  #include  < windows.h >
 2  #include  " resource.h "
 3 
 4  LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
 5  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 6  void  DisplayModelDialog(HWND hParent);
 7 
 8  int  WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine,  int  iCmdShow) {
 9 
10      WNDCLASS wndclass;
11      wndclass.style  =  CS_HREDRAW  |  CS_VREDRAW;
12      wndclass.cbClsExtra  =   0 ;
13      wndclass.cbWndExtra  =   0 ;
14      wndclass.hInstance  =  hInstance;
15      wndclass.hIcon  =  LoadIcon(NULL, IDI_APPLICATION);
16      wndclass.hCursor  =  LoadCursor(NULL, IDC_ARROW);
17      wndclass.hbrBackground  =  (HBRUSH)GetStockObject(WHITE_BRUSH);
18      wndclass.lpfnWndProc  =  DialogProc;
19      wndclass.lpszMenuName  =  NULL;
20      wndclass.lpszClassName  =  TEXT( " Dialog " );
21 
22      RegisterClass( & wndclass);
23    
24      wndclass.lpfnWndProc  =  WndProc;
25      wndclass.lpszMenuName  =  TEXT( " Menu " );
26      wndclass.lpszClassName  =  TEXT( " Parent " );
27       
28      RegisterClass( & wndclass);
29      
30      HWND hwnd  =  CreateWindow(
31      TEXT( " Parent " ), 
32      TEXT( " Parent " ),
33          WS_OVERLAPPEDWINDOW,
34      CW_USEDEFAULT, 
35      CW_USEDEFAULT,
36      CW_USEDEFAULT,
37      CW_USEDEFAULT,
38      NULL, 
39      NULL, 
40      hInstance, 
41      NULL);
42      
43      ShowWindow(hwnd, iCmdShow);
44      UpdateWindow(hwnd);
45      
46      MSG msg;
47       while (GetMessage( & msg, NULL,  0 0 )) {
48      
49           TranslateMessage( & msg);
50           DispatchMessage( & msg);
51      }
52       return  msg.wParam;
53  }
54 
55 
56  LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
57 
58       switch  (message) {
59 
60       case  WM_COMMAND:
61           if  (LOWORD(wParam)  ==  ID_FILE_DIALOG) {
62          DisplayModelDialog(hwnd);
63          }
64           return   0 ;
65 
66       case  WM_DESTROY:
67          PostQuitMessage( 0 );
68           return   0 ;
69      }
70 
71       return  DefWindowProc(hwnd, message, wParam, lParam);
72  }
73 

 

WinMain函数的开头注册了两个窗口类,第一个“Dialog”窗口类是供模态窗口使用的,它使用DialogProc窗口过程;第二个“Parent”窗口是供父窗口使用的,它使用WndProc窗口过程。

 

父窗口含有一个名为“Menu”的菜单,该菜单有一个“Dialog”菜单项,点击这个菜单项之后调用DisplayModelDialog函数来显示模态的窗口。

 

DisplayModelDialog函数是显示模态窗口的关键,下面是它的实现代码:

 1  void  DisplayModelDialog(HWND hParent) {
 2 
 3      EnableWindow(hParent, FALSE);
 4 
 5      HWND hDlg  =  CreateWindow(
 6      TEXT( " Dialog " ),
 7      TEXT( " Dialog " ),
 8      WS_OVERLAPPEDWINDOW  |  WS_VISIBLE,
 9      CW_USEDEFAULT,
10      CW_USEDEFAULT,
11      CW_USEDEFAULT,
12      CW_USEDEFAULT,
13      hParent,
14      NULL,
15      (HINSTANCE)GetWindowLong(hParent, GWL_HINSTANCE),
16      NULL);
17 
18      ShowWindow(hDlg, SW_SHOW);
19      UpdateWindow(hDlg);
20 
21      MSG msg;
22 
23       while  (GetMessage( & msg, NULL,  0 0 )) {
24 
25      TranslateMessage( & msg);
26          DispatchMessage( & msg);
27      }
28 
29      EnableWindow(hParent, TRUE);
30      SetForegroundWindow(hParent);
31  }
32 
33  LRESULT CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
34 
35       switch  (message) {
36 
37       case  WM_DESTROY:
38          PostQuitMessage( 0 );
39           return   0 ;
40      }
41 
42       return  DefWindowProc(hwnd, message, wParam, lParam);
43  }
44 

 

上面的代码看上去几乎就是一个新的Windows应用程序,不同的地方在于,函数的开头和结尾增加了对EnableWindowSetForegroundWindow的调用。如果没有对SetForegroundWindow的调用,在关闭模态窗口之后父窗口会最小化。

 

运行程序,点击菜单上的Dialog项,就可以弹出一个模态窗口,点击父窗口任意位置,模态窗口会闪烁,就像模态对话框的行为一样。现在,可以修改模态窗口的样式,并处理WM_CREATE消息在窗口中增加内容了。

转载于:https://www.cnblogs.com/zplutor/archive/2011/02/20/1958973.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值