• WM_CLOSE WM_DESTROY WM_QUIT


    以下说明程序是如何退出的:
    使用者选按【File/Close】,于是发出 WM_CLOSE
    CMyFrameWnd 并没有设置WM_CLOSE 处理常式,于是交给预设之处理常式。
    预设函数对于WM_CLOSE 的处理方式是呼叫 ::DestroyWindow, 并因而发出WM_DESTROY
    预设之WM_DESTROY 处理方式是呼叫::PostQuitMessage,因此发出WM_QUIT
    CWinApp::Run 收到WM_QUIT 后会结束其内部之讯息回路, 然后呼叫
    ExitInstance,这是CWinApp ㆒个虚拟函数。
    如果CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所呼叫的就是CMyWinApp::ExitInstance,否则就是 CWinApp::ExitInstance
    最后回到 AfxWinMain,执行 AfxWinTerm,结束程序。

    WM_CLOSE,调用DestroyWindow()
    DestroyWindow()又发送WM_DESTROY
    响应WM_DESTROY,调用WM_QUIT
    GetMessage()发现WM_QUIT,退出程序

    特别注意:如果想手动发送WM_QUIT只能使用postmessage函数,而不能使用sendmessage函数

    ---

    //主函数中进入消息循环的代码片断
    while(GetMessage(&msg,NULL,0,0))
    {
    TranslateMessage(&msg); //将消息进行处理一下
    DispatchMessage(&msg); //再将消息变量msg传给windows,windows来调用消息处理函数
    }

    //消息处理函数
    LRESULT CALLBACK MyProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
    switch(uMsg)
    {

          case WM_CLOSE:

                    if(IDOK==MessageBox(hwnd,"真的想退出程序吗?","退出程序就没机会了",MB_YESNO))

                    {

                            DestroyWindow(hwnd); //WM_CLOSE默认是调用这个处理函数

                    }

                    break;

                   case WM_DESTROY:
    PostQuitMessage(0);
    break;
    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }

    ---


    WM_CLOSE消息:在系统菜单里选择了关闭或者点击了窗口右上角的“X”按钮时产生,它的默认响应函数是直接调用DestroyWindow(hwnd); 
    DestroyWindow(hwnd); 是销毁窗口(但没有不是退出消息循环),然后销毁过程中会产生WM_DESTROY消息放入消息队列,

    (当调用DestroyWindow函数后,操作系统就会进行一系列的删除动作,先发送WM_DESTROY消息,接着发送WM_NCDESTROY消息。如果这个窗口还有子窗口或者是其它窗口的所有者,就需要给所有子窗口发送删除消息。)

     

    WM_DESTROY消息:默认是调用PostQuitMessage(0),ostQuitMessage(0)作用是产生WM_QUIT并放入消息队列,

    WM_QUIT消息:GetMessage(&msg,NULL,0,0)拿到WM_QUIT后返回假,导致消息循环退出.WM_QUIT是唯一可以使GetMessage(&msg,NULL,0,0)返回假值的消息.

     

     

     

    -------------------------------------------------------------------------------------------------------

     

    WM_CLOSE:

      在系统菜单里选择了关闭或者点击了窗口右上角的“X”按钮,你的窗口过程就会收到WM_CLOSEDefWindowProc对 WM_CLOSE的处理是调用DestroyWindow。当然,你可以不让DefWindowProc处理,而是自己处理,例如询问用户是否保存更改 等。如果用户选择取消,你忽略此消息,那么程序照常运行;如果用户确认要退出,你就调用DestroyWindow


    WM_DESTROY:

      接下来,DestroyWindow完成窗口的清理工作,最后像窗口过程发送WM_DESTROY。对于 WM_DESTROYDefWindowProc不会处理。也就是说,你如果不处理这个消息,虽然你的窗口已经销毁,但进程并不会结束。一般处理 WM_DESTROY时都是释放资源(例如申请的内存等),然后调用PostQuitMessage

    WM_QUIT:

      PostQuitMessage会发送WM_QUIT给消息队列。注意,WM_QUIT永远不会到达窗口过程,因为GetMessage得到WM_QUIT后就会返回FALSE,从而结束消息循环,最后进程结束,程序退出。

    假设使用者执行HELLOWIN,并且使用者最终单击了 Close按钮,或者假设用键盘或鼠标从系统菜单中选择了 Close, DefWindowProc处理这一键盘或者鼠标输入,在检测到使用者选择了Close选 项之后,它给窗口消息处理程序发送一条WM_SYSCOMMAND消息。WndProc将这个消息传给DefWindowProc。 DefWindowProc给窗口消息处理程序发送一条WM_CLOSE消息来响应之。WndProc再次将它传给DefWindowProc。 DestroyWindow呼叫DestroyWindow来响应这条WM_CLOSE消息。DestroyWindow导致Windows给窗口消息处 理程序发送一条WM_DESTROY消息。WndProc再呼叫PostQuitMessage,将一条WM_QUIT消息放入消息队列中,以此来响应此 消息。这个消息导致WinMain中的消息循环终止,然后程序结束。

    转载地址:http://appdev.189works.com/?action-viewnews-itemid-2590

    ***********************************************

    WM_CLOSE消息与DefWindowProc收到WM_SYSCOMMAND消息,且wParam等于SC_COLSE时发送给窗口过程的消息相同。

      如果在一个Windows程序的系统菜单图标上双击一下,那么程序将会终止。双击产生一系列的WM_NCHITTEST消息。由于鼠标定位在系统菜单图标上,因此DefWindowProc将返回HTSYSMENU的值,并且WindowswParam等于HTSYSMENUWM_NCLBUTTONDBLCLK消息放在消息队列中。

      当DefWindowProc接收到wParam参数等于HTSYSMENUWM_NCLBUTTONDBLCLK消息时,它就把wParam参数等于SC_CLOSEWM_SYSCOMMAND消息放入消息队列中(这个WM_SYSCOMMAND消息是在用户从系统菜单中选择Close时产生的)。同样,窗口过程也把这个消息传给DefWindowProcDefWindowProc通过给窗口过程发送WM_CLOSE消息来处理该消息。

      如果一个程序在终止之前要求来自用户的确认,那么窗口过程就需要捕获WM_CLOSE,否则DefWindowProc调用DestroyWindow函数来处理WM_CLOSE。除了其他处理,DestroyWindow还给窗口过程发送一个WM_DESTROY消息。窗口过程通常用下列代码来处理WM_DESTROY消息:

      case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

      PostQuitMessage使WindowsWM_QUIT消息放入消息队列中,此消息永远不会到达窗口过程,因为它使GetMessage返回0,终止消息循环,从而也终止了程序。

      AskConfirmation(HWND hwnd)

      {

        return MessageBox(hwnd, TEXT("Really want to close PopPad2?"), szAppName, MB_YESNO | MB_ICONQUESTION);

      }

      case WM_CLOSE:

        if(IDYES == AskConfirmation(hwnd))

          DestroyWindow(hwnd);

        return 0;

     

  • 相关阅读:
    Qt double转换成Qstring
    QT 控件ComboBox
    前端web项目打包(二)
    前端Web打包成可执行程序
    div中下拉框无法点击展开跟选中
    div下多个table并排排列
    VS将数据保存在excel表格中
    关于windows下任务栏应用程序标签消失问题的解决办法
    Java8中map()和flatMap()的区别
    Java对象的深拷贝
  • 原文地址:https://www.cnblogs.com/tianlangshu/p/2004100.html
Copyright © 2020-2023  润新知