Detailed explanation of messages when creating and destroying windows


Usually we understand that the message WM_CREATE is issued when the window is created, but there is a message WM_NCCREATE that is issued before this message.
Namely:
WM_NCCREATE Corresponding to
WM_CREATE
, the message WM_DESTROY, WM_NCDESTROY is issued when the window is closed.
Sequence:
WM_DESTROY
WM_NCDESTROY
It should be noted here that when a window is closed, if there is a child window in this window, the WM_DESTROY and WM_NCDESTROY messages of the child window will be sent first, and then the WM_DESTROY and WM_NCDESTROY messages of the parent window will be sent.
Sequence:
WM_DESTROY //CHILD, child window message
WM_NCDESTROY //CHILD, child window message
WM_DESTROY //Parent, parent window message     
WM_NCDESTROY //Parent, parent window message
The following is an example to verify the execution sequence:
1. Create a new MFC project , the project name is TestCreate, then there is already a default form TestCreate, and the settings are as follows:

2. Next, add the subform TestChild without setting it.
3. Add the open subform event response:
  1. #include "TestChild.h"
  2. void  CTestCreateDlg::OnButton2() //Open the subform
  3. {
  4.     if (!frm.GetSafeHwnd())
  5.     {
  6.         frm.Create(IDD_TESTCHILD_DIALOG,this);
  7.     }
  8.     frm.ShowWindow(SW_SHOW);
  9. }
4. Add a message handler to the parent form
  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. Add a message handler to the subform
  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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326134066&siteId=291194637