WM_CREATE ,WM_NCCREATE,WM_DESTROY,WM_NCDESTROY详解

通常我们理解在窗口创建时发出消息WM_CREATE,但是在这个消息之前还有一个消息是被发出的WM_NCCREATE。
即:
WM_NCCREATE
WM_CREATE
对应的,在窗口被关闭时发出消息WM_DESTROY,WM_NCDESTROY。
顺序:
WM_DESTROY
WM_NCDESTROY
这里要注意的是,在一个窗口被关闭时,如果这个窗口存在子窗口,那么会先发送子窗口的WM_DESTROY和WM_NCDESTROY消息,接着发送父窗口的WM_DESTROY和WM_NCDESTROY消息。
顺序:
WM_DESTROY    //CHILD,子窗口消息
WM_NCDESTROY  //CHILD,子窗口消息
WM_DESTROY    //Parent,父窗口消息   
WM_NCDESTROY  //Parent,父窗口消息
下面通过例子来验证这个执行顺序:
1.新建立一个MFC工程,工程名TestCreate,这时已经有一个默认的窗体TestCreate,设置如下:

2.接下来添加子窗体TestChild,不做设置。
3.添加打开子窗体事件响应:
  1. #include "TestChild.h"
  2. void CTestCreateDlg::OnButton2() //打开子窗体
  3. {
  4.     if (!frm.GetSafeHwnd())
  5.     {
  6.         frm.Create(IDD_TESTCHILD_DIALOG,this);
  7.     }
  8.     frm.ShowWindow(SW_SHOW);
  9. }
4.为父窗体添加消息处理函数
  1. LRESULT CTestCreateDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  2. {
  3.     // TODO: Add your specialized code here and/or call the base class
  4.     switch(message)
  5.     {
  6.     case WM_CREATE:
  7.         TRACE0("----------------------WM_CREATE/n");
  8.         break;
  9.     case WM_NCCREATE:
  10.         TRACE0("----------------------WM_NCCREATE/n");
  11.         break;
  12.     case WM_DESTROY:
  13.         TRACE0("----------------------WM_DESTROY/n");
  14.         break;
  15.     case WM_NCDESTROY:
  16.         TRACE0("----------------------WM_NCDESTROY/n");
  17.         break;
  18.     default:
  19.         break;
  20.     }
  21.     return CDialog::DefWindowProc(message, wParam, lParam);
  22. }
5.为子窗体添加消息处理函数
  1. LRESULT CTestChild::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  2. {
  3.     // TODO: Add your specialized code here and/or call the base class
  4.     switch(message)
  5.     {
  6.     case WM_CREATE:
  7.         TRACE0("----------------------WM_CREATE_CHILD/n");
  8.         break;
  9.     case WM_NCCREATE:
  10.         TRACE0("----------------------WM_NCCREATE_CHILD/n");
  11.         break;
  12.     case WM_DESTROY:
  13.         TRACE0("----------------------WM_DESTROY_CHILD/n");
  14.         break;
  15.     case WM_NCDESTROY:
  16.         TRACE0("----------------------WM_NCDESTROY_CHILD/n");
  17.         break;
  18.     default:
  19.         break;
  20.     }
  21.     return CDialog::DefWindowProc(message, wParam, lParam);
  22. }
到此,一个测试例程就做好了,Alt+2打开Output窗口,运行。
点击按钮打开子窗体,然后切换到父窗体,并点击关闭按钮,可以看到输出结果:
----------------------WM_NCCREATE
Loaded 'C:/WINDOWS/system32/version.dll', no matching symbolic information found.
Loaded 'C:/WINDOWS/system32/MSCTFIME.IME', no matching symbolic information found.
----------------------WM_CREATE
----------------------WM_NCCREATE_CHILD
----------------------WM_CREATE_CHILD
----------------------WM_DESTROY_CHILD
----------------------WM_NCDESTROY_CHILD
----------------------WM_DESTROY
----------------------WM_NCDESTROY


WM_NCCREATE 是一个窗口消息,用于在创建非客户区(Non-Client Area)时调用窗口过程。它有两个参数: 1. wParam:保留参数,未使用。 2. lParam:一个指向 CREATESTRUCT 结构的指针,其中包含创建窗口时的附加信息。 CREATESTRUCT 结构包含以下成员: 1. lpCreateParams:创建窗口时指定的附加参数。 2. hInstance:包含窗口所属模块的实例句柄。 3. hMenu:窗口的菜单句柄。 4. hwndParent:父窗口的句柄。 5. cy:窗口的高度(以像素为单位)。 6. cx:窗口的宽度(以像素为单位)。 7. y:窗口的初始垂直位置(以屏幕坐标为单位)。 8. x:窗口的初始水平位置(以屏幕坐标为单位)。 9. style:窗口的样式。 10. lpszName:窗口的标题。 11. lpszClass:窗口类名。 如果你想去除默认的UI样式,可以在创建窗口之前修改窗口的样式。在.NET中,你可以使用 Control 类的 CreateParams 属性来设置样式。例如,如果你想去除窗口边框和标题栏,可以将样式设置为 WS_POPUP 并且没有 WS_CAPTION 和 WS_SYSMENU 样式。具体的代码示例如下: ```csharp protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.Style &= ~WS_BORDER; // 去除边框样式 cp.Style &= ~WS_CAPTION; // 去除标题栏样式 cp.Style &= ~WS_SYSMENU; // 去除系统菜单样式 return cp; } } ``` 请注意,上述的代码示例是针对.NET桌面应用程序的。如果你是在其他平台或使用其他编程语言开发应用程序,请查阅相关文档以获取相应的方法和属性。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

满衣兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值