小科来啦 发表于 2014-7-10 10:30:30

E=MC2 发表于 2014-7-10 08:58
确实按2次小X即可关闭,那么是什么原因呢?

根据调试初步判断为:当点第一次时,程序运行至case WM_NCLBUTTONDOWN:产生一个对话框,点了确认后对话框消失,由于改为break;程序便到了return DefWindowProc(hwnd, message, wParam, lParam);继续处理WM_NCLBUTTONDOWN,,相当于一个WM_NCLBUTTONDOWN消息被处理了两次
由于系统计算出在X上按下了左键,系统在等待左键在X上松开了按键,因为这时在窗口上移动鼠标时,那些X、最小化、最大化按钮没有颜色变化,当你第二次点击并在X上松开左键时就完成了正常的关闭X的整个操作,
这时便产生WM_DESTROY消息,执行程序关闭过程

仰望天上的光 发表于 2014-7-15 21:15:40

常用的窗口关闭判断由三个消息构成:,WM_SYSCOMMAND,WM_CLOSE和WM_DESTROY以下代码模拟了它们出现的顺序.用非客户区点击判断也可以,但是不常用.
#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                  PSTR szCmdLine, int iCmdShow)
{
        static TCHAR szAppName[] = TEXT ("HelloWin") ;
        HWND         hwnd ;
        MSG          msg ;
        WNDCLASS   wndclass ;
       
        wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc   = WndProc ;
        wndclass.cbClsExtra    = 0 ;
        wndclass.cbWndExtra    = 0 ;
        wndclass.hInstance   = hInstance ;
        wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
        wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName= NULL ;
        wndclass.lpszClassName = szAppName ;
       
        if (!RegisterClass (&wndclass))
        {
                MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                        szAppName, MB_ICONERROR) ;
                return 0 ;
        }
       
        hwnd = CreateWindow (szAppName,                  // window class name
                TEXT ("The Hello Program"), // window caption
                WS_OVERLAPPEDWINDOW,      // window style
                CW_USEDEFAULT,            // initial x position
                CW_USEDEFAULT,            // initial y position
                CW_USEDEFAULT,            // initial x size
                CW_USEDEFAULT,            // initial y size
                NULL,                     // parent window handle
                NULL,                     // window menu handle
                hInstance,                  // program instance handle
                NULL) ;                     // creation parameters
       
        ShowWindow (hwnd, iCmdShow) ;
        UpdateWindow (hwnd) ;

        while (GetMessage (&msg, NULL, 0, 0))
        {
                TranslateMessage (&msg) ;
                DispatchMessage (&msg) ;
        }
        return msg.wParam ;
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        switch (message)
        {
        case WM_CREATE:
                return 0 ;
        case WM_SYSCOMMAND:
                if( wParam == SC_CLOSE )
                {
                        MessageBox(hwnd, "WM_SYSCOMMAND,窗口还在,还可以撤销操作", "Msg", 0 );
                        SendMessage( hwnd, WM_CLOSE, 0, 0 );
                }
                return 0;
        case WM_CLOSE:
                {
                        MessageBox(hwnd, "WM_CLOSE,窗口还在,还可以撤销操作", "Msg", 0 );
                        DestroyWindow( hwnd );
                        return 0;
                }
        case WM_DESTROY:
                {
                        MessageBox(hwnd, "WM_DESTROY,窗口不在,不可以撤销操作", "Msg", 0 );
                        PostQuitMessage (0) ;
                        return 0 ;
                }
        }
        return DefWindowProc (hwnd, message, wParam, lParam) ;
}

E=MC2 发表于 2014-7-16 11:35:07

仰望天上的光 发表于 2014-7-15 21:15
常用的窗口关闭判断由三个消息构成:,WM_SYSCOMMAND,WM_CLOSE和WM_DESTROY以下代码模拟了它们出现的顺序.用 ...

学习了。但是问题2貌似还是无解啊?

E=MC2 发表于 2014-7-16 17:59:21

仰望天上的光 发表于 2014-7-16 14:56


谢谢了。HTCLOSE 看来还真有这个专门在非客户区关闭的消息。相关的MSDN 我已经找到

tlwangxd 发表于 2014-12-2 06:33:52

学习

wljlwyq 发表于 2014-12-12 13:05:11

智商是硬伤 发表于 2015-9-4 09:36:58

{:7_146:}

fsd82ht 发表于 2016-12-3 11:52:25

学习,,
页: 1 [2]
查看完整版本: 在第6讲视频中的WM_NCLBUTTONDOWN用法问题