zoukankan      html  css  js  c++  java
  • Windows窗口程序从创建到关闭产生的消息

    Windows是消息驱动的,理解消息机制及消息循环是特别重要。知道在什么情况下产生什么消息会让我们对程序有更好的控制。Windows给应用程序发消息,有些会加入应用程序的消息队列,也是就是队列消息。有些直接调用窗口消息处理程序,不会加入到消息队列,这部分为非队列消息。


    下面分析一下一个应用程序从创建到结束产生的消息。

    先给出测试用的程序,当然是一个非常经典的结构:


    #include <windows.h>
    #include <tchar.h>
    
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nShowCmd)
    {
        MSG msg;
        TCHAR szClassName[] = _T("MainWClass");
        WNDCLASSEX wndclass;
    
        wndclass.cbClsExtra = 0;
        wndclass.cbSize = sizeof(wndclass);
        wndclass.cbWndExtra = 0;
        wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
        wndclass.hCursor = ::LoadCursor(NULL, IDI_APPLICATION);
        wndclass.hIcon = ::LoadIcon(NULL, IDC_ARROW);
        wndclass.hIconSm = NULL;
        wndclass.hInstance = hInstance;
        wndclass.lpfnWndProc = WndProc;
        wndclass.lpszClassName = szClassName;
        wndclass.lpszMenuName = NULL;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        
        if (::RegisterClassEx(&wndclass) == 0)
        {
            ::MessageBox(NULL, _T("RegisterClassEx Failed"), _T("Error"), MB_OK | MB_ICONHAND);
            return 0;
        }
    
        HWND hwnd = ::CreateWindow(
            szClassName,            // lpClassName
            _T("My Window"),        // lpWindowName
            WS_OVERLAPPEDWINDOW,    // dwStyle
            CW_USEDEFAULT,          // X
            CW_USEDEFAULT,          // Y
            CW_USEDEFAULT,          // nWidth
            CW_USEDEFAULT,          // nHeight
            NULL,                   // hWndParent,
            NULL,                   // hMenu
            hInstance,              // hInstance
            NULL                    // lpParam
            );                  
    
        ::ShowWindow(hwnd, nShowCmd);
        ::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)
    {
        TCHAR szText[] = _T("Simple Window!");
        switch (message)
        {
        case WM_PAINT:
            {
                HDC hdc;
                PAINTSTRUCT ps;
                hdc = ::BeginPaint(hwnd, &ps);
                ::TextOut(hdc, 10, 10, szText, _tcslen(szText));
                ::EndPaint(hwnd, &ps);
            }
            return 0;
        case WM_DESTROY:
            ::PostQuitMessage(0);
            return 0;
        }
        return ::DefWindowProc(hwnd, message, wParam, lParam);
    }
    


    启动这个程序到关闭他都会产生什么消息呢?

    // 调用CreateWindow后产生第一条消息:
    CreateWindow()
    0X0024 WM_GETMINMAXINFO     "当窗口将要改变大小或位置时,由系统发送本消息给窗口,用户拖动一个可重置大小的窗口时便会发出本消息"
    0X0081 WM_NCCREATE          "当某窗口首次被创建时,本消息在WM_CREATE消息发送前发送"
    0X0083 WM_NCCALCSIZE        "当某窗口的客户区的大小和位置须被计算时发送本消息"
    0X0001 WM_CREATE            "新建一个窗口"
    CreateWindow() 返回
    
    ShowWindow()
    0X0018 WM_SHOWWINDOW        "发送本消息给一个窗口,以便隐藏或显示该窗口"
    0X0046 WM_WINDOWPOSCHANGING "本消息会发送给那些大小和位置(Z_Order)将被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
    0X001C WM_ACTIVATEAPP       "窗口进程激活状态改动,正被激活的窗口属于不同的应用程序 "
    0X0086 WM_NCACTIVATE        "本消息发送给某窗口,在窗口的非客户区被激活时重绘窗口"
    0X007F WM_GETICON           "本消息发送给某个窗口,用于返回与某窗口有关联的大图标或小图标的句柄(一般收到多个,用于获取不同大小的图标)"
    0X0006 WM_ACTIVATE          "一个窗口被激活或失去激活状态"
    0X0281 WM_IME_SETCONTEXT    "应用程序的窗口激活时,系统将向应用程序发送WM_IME_SETCONTEXT消息,输入焦点转移到了某个窗口上,注:输入法相关"
    0X0282 WM_IME_NOTIFY        "可使用WM_IME_NOTIFY消息来通知关于IME窗口状态的常规改变,注:输入法相关,IME窗口发生了改变" 
    0X0007 WM_SETFOCUS          "将焦点转向一个窗口"
    0X0085 WM_NCPAINT           "当窗口框架(非客户区)必须被被重绘时,应用程序发送本消息给该窗口"
    0X0014 WM_ERASEBKGND        "当一个窗口的背景必须被擦除时本消息会被触发(如:窗口大小改变时)"
    0X0047 WM_WINDOWPOSCHANGED  "本消息会发送给那些大小和位置(Z_Order)已被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
    0X0005 WM_SIZE              "改变一个窗口的大小"
    0X0003 WM_MOVE              "移动一个窗口"
    ShowWindow() 返回
    
    UpdateWindow()
    0X000F WM_PAINT             "窗口重绘"
    UpdateWindow() 返回
    0X007F WM_GETICON           "本消息发送给某个窗口,用于返回与某窗口有关联的大图标或小图标的句柄(一般收到多个,用于获取不同大小的图标)"
    
    // 进入消息循环
    0X0113 WM_TIMER             "发生了定时器事件"
    0X0101 WM_KEYUP             "当一个非系统按键被释放弹起时(<ALT>键没有被按下),会发送本消息给拥有键盘焦点的窗口"
    0X0113 WM_TIMER             "发生了定时器事件"
    0X0104 WM_SYSKEYDOWN        "当用户按住<ALT>键的同时又按下其它键时,发送本消息给拥有焦点的窗口",
    0X0112 WM_SYSCOMMAND        "当用户选择一条系统菜单命令、用户最大化或最小化或还原或关闭时,窗口会收到本消息"
    0X0010 WM_CLOSE             "用户关闭窗口时会发送本消息,紧接着会发送WM_DESTROY消息"
    0X0046 WM_WINDOWPOSCHANGING "本消息会发送给那些大小和位置(Z_Order)将被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
    0X0047 WM_WINDOWPOSCHANGED  "本消息会发送给那些大小和位置(Z_Order)已被改变的窗口,以调用SetWindowPos函数或其它窗口管理函数"
    0X0086 WM_NCACTIVATE        "本消息发送给某窗口,在窗口的非客户区被激活时重绘窗口"
    0X0006 WM_ACTIVATE          "一个窗口被激活或失去激活状态"
    0X001C WM_ACTIVATEAPP       "窗口进程激活状态改动,正被激活的窗口属于不同的应用程序 "
    0X0008 WM_KILLFOCUS         "使一个窗口失去焦点"
    0X0281 WM_IME_SETCONTEXT    "应用程序的窗口激活时,系统将向应用程序发送WM_IME_SETCONTEXT消息,输入焦点转移到了某个窗口上,注:输入法相关"
    0X0282 WM_IME_NOTIFY        "可使用WM_IME_NOTIFY消息来通知关于IME窗口状态的常规改变,注:输入法相关,IME窗口发生了改变" 
    0X0002 WM_DESTROY           "销毁一个窗口"
    0X0082 WM_NCDESTROY         "本消息通知某窗口,非客户区正在销毁"
    


    就是以上这些,可以看出上面的消息是使用系统快捷键来关闭的程序。

    作者:马 岩Furzoom) (http://www.cnblogs.com/furzoom/
    版权声明:本文的版权归作者与博客园共同所有。转载时请在明显地方注明本文的详细链接,未经作者同意请不要删除此段声明,感谢您为保护知识产权做出的贡献。
  • 相关阅读:
    XRTable 表新增列和行数据
    sql server 清理数据库日志
    C# 数字 转换 大写汉字
    NavBarControl 简单配置
    bandedGridView
    TileView 基本配置
    CardView 基本配置
    ButtonEdit 参数配置
    无边框窗体,鼠标移动窗体
    【网站】windows phpstudy v8.1搭建https
  • 原文地址:https://www.cnblogs.com/furzoom/p/7710159.html
Copyright © 2011-2022 走看看