• win32 API编程之常用消息详解


    一、发送消息的函数

    • sendmessage
    • postmessage
    • postthreadmessage:向消息队列添加一个消息

    实例代码:

    #include<windows.h>
    #include<stdio.h>
    //自定义消息
    #define  WM_AAA    WM_USER+1
    
    HWND  hWnd; 
    HWND  hWnd2;
    
    //自定义的窗口过程
    LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
        WPARAM wParam, LPARAM lParam)
    {
        switch (Msg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);//可以使GetMessage返回0    
            return 0; 
    
        case WM_AAA:
            MessageBoxA(NULL, "窗口过程:WM_AAA", "测试", MB_OK);
            return 0;
        }
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
        LPSTR lpCmdLine, int  nShowCmd)
    {
        //1.注册窗口类
        WNDCLASS  wnd;
        wnd.cbClsExtra = 0;
        wnd.cbWndExtra = 0;
        wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
        wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
        wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                    //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
        wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
        wnd.lpszClassName = L"MrHuang";//窗口类名
        wnd.lpszMenuName = NULL;//菜单资源名称
        wnd.style = CS_HREDRAW;//窗口类、样式
        wnd.hInstance = hInstance;//实例句柄
        RegisterClass(&wnd);
    
        //创建窗口(返回之前发送WM_CREATE)
        hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
            WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);
    
        //显示窗口
        ShowWindow(hWnd, nShowCmd);
        //更新窗口(发送WM_PAINT)
        UpdateWindow(hWnd);
    
        //创建窗口2(返回之前发送WM_CREATE)
        hWnd2 = CreateWindow(L"MrHuang", L"第二个窗口程序",
            WS_OVERLAPPEDWINDOW, 100, 500, 300, 300, NULL, NULL, hInstance, NULL);
        //显示窗口
        ShowWindow(hWnd2, nShowCmd);
        //更新窗口(发送WM_PAINT)
        UpdateWindow(hWnd2);
    //消息循环(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { //说明两个窗口公用一个消息循环和线程消息队列 if (msg.message == WM_LBUTTONDOWN) { //char str[64]; //sprintf(str,"窗口句柄:%p", msg.hwnd); //MessageBoxA(NULL, str,"测试", MB_OK); //SendMessage直接发给窗口过程函数,并且阻塞,除非被窗口过程处理才返回 //SendMessage(hWnd, WM_AAA, 0, 0); //PostMessage放到线程消息队列里,并且立即返回,通过消息循环到窗口过程处理 //PostMessage(hWnd, WM_AAA, 0, 0); //PostThreadMessage放到线程消息队列里,不进入窗口过程 //PostThreadMessage(GetCurrentThreadId(), WM_AAA, 0, 0); //PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0); PostQuitMessage(0);//等价于上面的一行调用 int a = 100; } if (msg.message == WM_AAA) { MessageBoxA(NULL, "消息循环:WM_AAA","测试", MB_OK); } TranslateMessage(&msg);//翻译消息 DispatchMessage(&msg);//分发消息到窗口过程 } }

    二、windows各种消息

    • 标准消息:所有以WM开头的消息,WM_COMMAND除外。为了避免系统消息与用户定义的消息冲突,微软定义了一个宏WM_USER,小于WM_USER的ID被系统使用,大于的被用户使用。
    • 命令消息:来自菜单、工具栏按钮或者加速键的消息,以WM_COMMAND呈现。
    • 通告消息:由控件产生的消息。

    三、响应窗口创建和删除

    代码实例

    #include<windows.h>
    #include<stdio.h>
    
    //自定义的窗口过程
    LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
        WPARAM wParam, LPARAM lParam)
    {
        switch (Msg)
        {
            ///////////////////////////创建窗口///////////////////////////////
        case WM_NCCREATE:
    
            SetWindowTextA(hWnd, "改变标题");
    
            char str[64];
            sprintf(str, "WM_NCCREATE消息:%p!
    ", hWnd);
            OutputDebugStringA(str);
            return  true;//这里必须返回true,否则不会发WM_CREATE消息,CreateWindow返回NULL
    
        case WM_CREATE:
        {
            CREATESTRUCT  *p = (CREATESTRUCT*)lParam; 
            sprintf(str, "WM_CREATE消息:%p!
    ", hWnd); 
    
            OutputDebugStringA(str);
            return true;
        }
    
            ///////////////////////////销毁窗口/////////////////////////////// 
        case WM_CLOSE:
            sprintf(str, "WM_CLOSE消息:%p!
    ", hWnd);
            OutputDebugStringA(str); 
            DestroyWindow(hWnd);//销毁窗口,发出WM_DESTROY消息
            return 0;
    
        case WM_DESTROY: 
            sprintf(str, "WM_DESTROY消息:%p!
    ", hWnd);
            OutputDebugStringA(str);
            PostQuitMessage(0);//可以使GetMessage返回0    
            return 0;
        case WM_NCDESTROY: 
            sprintf(str, "WM_NCDESTROY消息:%p!
    ", hWnd);
            OutputDebugStringA(str);
            return 0;
        }
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
        LPSTR lpCmdLine, int  nShowCmd)
    {
        //1.注册窗口类
        WNDCLASS  wnd;
        wnd.cbClsExtra = 0;
        wnd.cbWndExtra = 0;
        wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
        wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
        wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                    //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
        wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
        wnd.lpszClassName = L"MrHuang";//窗口类名
        wnd.lpszMenuName = NULL;//菜单资源名称
        wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
        wnd.hInstance = hInstance;//实例句柄
        RegisterClass(&wnd);
    
        //创建窗口(返回之前发送WM_CREATE)
        HWND  hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
            WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);
        char str[64];
        sprintf(str, "CreateWindow返回:%p!
    ", hWnd);
        OutputDebugStringA(str); 
    
        //显示窗口
        ShowWindow(hWnd, nShowCmd);
        //更新窗口(发送WM_PAINT)
        UpdateWindow(hWnd);
    
        //消息循环(收到WM_QUIT消息退出)
        MSG  msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);//翻译消息
            DispatchMessage(&msg);//分发消息到窗口过程
        }
    }

     四、WM_PAINT消息

    1)以下操作会触发WM_PAINT消息

    注:

    代码实例:

    #include<windows.h>
    #include<stdio.h>
    
    //自定义的窗口过程
    LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
        WPARAM wParam, LPARAM lParam)
    {
        switch (Msg)
        {
          case WM_DESTROY:
            PostQuitMessage(0);//可以使GetMessage返回0    
            return 0; 
    
          case WM_ERASEBKGND:
          {  
              static  int  j = 0;
              char str[64];
              sprintf(str, "第%d次产生WM_ERASEBKGND!
    ", ++j);
              OutputDebugStringA(str);//在输出窗口打印信息
              return  1; 
          }
    
          case WM_PAINT:
          {  PAINTSTRUCT  ps;
          HDC  hdc = BeginPaint(hWnd, &ps);//使无效区域变得有效
    
          static  int  i = 0;
          char str[64];
          sprintf(str, "第%d次产生WM_PAINT!
    ", ++i);
          OutputDebugStringA(str);//在输出窗口打印信息
    
          EndPaint(hWnd, &ps);
          return 0;
          }
          case  WM_LBUTTONDOWN:
              //InvalidateRect(hWnd, NULL, true);//添加更新区域
              //UpdateWindow(hWnd);//更新区域不为空,则马上发出WM_PAINT消息
            
              //不管窗口的任何部分是否无效,都会导致WM_PAINT消息被发布到窗口。
              RedrawWindow(hWnd, NULL, NULL, RDW_INTERNALPAINT);
              break;
    
          case  WM_NCPAINT://自定义绘制非客户区
              HDC  hdc = GetWindowDC(hWnd); 
              RECT  r;
              r.left = 0;
              r.top = 0;
              r.right = 300;
              r.bottom = 30;
              HBRUSH  brh = CreateSolidBrush(RGB(255, 0, 0));
              FillRect(hdc, &r, brh);
              SetBkMode(hdc, TRANSPARENT);
              TextOutA(hdc, 5, 5, "自定义窗口标题", 14);//最后一个参数为字符串长度
              DeleteObject(brh);
              ReleaseDC(hWnd,  hdc);
              return  true;
              //break;
        }
        return DefWindowProc(hWnd, Msg, wParam, lParam);
     }
    
        int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
            LPSTR lpCmdLine, int  nShowCmd)
        {
            //1.注册窗口类
            WNDCLASS  wnd;
            wnd.cbClsExtra = 0;
            wnd.cbWndExtra = 0;
            wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
            wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
            wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                        //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
            wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
            wnd.lpszClassName = L"MrHuang";//窗口类名
            wnd.lpszMenuName = NULL;//菜单资源名称
            wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
            wnd.hInstance = hInstance;//实例句柄
            RegisterClass(&wnd);
    
            //创建窗口(返回之前发送WM_CREATE)
            HWND  hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
                WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);
    
            //显示窗口
            ShowWindow(hWnd, nShowCmd);
            //更新窗口(发送WM_PAINT)
            UpdateWindow(hWnd);
    
            //消息循环(收到WM_QUIT消息退出)
            MSG  msg;
            while (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);//翻译消息
                DispatchMessage(&msg);//分发消息到窗口过程
            }
        }

    五、WM_ERASEBKGND消息

    代码实例:见上面WM_PAINT的代码实例。

    六、更新窗口的函数

    代码实例:见上面WM_PAINT的代码实例。

    七、WM_NCPAINT消息

    代码实例:见上面WM_PAINT的代码实例。

    八、窗口鼠标键盘消息

    代码实例:

    #include<windows.h>
    #include<stdio.h>
    
    //自定义的窗口过程
    LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
        WPARAM wParam, LPARAM lParam)
    {
        switch (Msg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);//可以使GetMessage返回0    
            return 0; 
    
            //鼠标消息
        case  WM_LBUTTONDOWN:
            char str[64];
            sprintf(str, "鼠标左键按下:  %d, %d
    ", LOWORD(lParam), HIWORD(lParam));
            OutputDebugStringA(str);
            break;
        case  WM_LBUTTONUP: 
            sprintf(str, "鼠标左键弹起:  %d, %d
    ", LOWORD(lParam), HIWORD(lParam));
            OutputDebugStringA(str);
            break;
        case  WM_MOUSEMOVE: 
            sprintf(str, "鼠标移动:  %d, %d
    ", LOWORD(lParam), HIWORD(lParam));
            OutputDebugStringA(str);
            break;
        case  WM_LBUTTONDBLCLK: 
            sprintf(str, "鼠标左键双击:  %d, %d
    ", LOWORD(lParam), HIWORD(lParam));
            OutputDebugStringA(str);
            break;
             //键盘消息
        case  WM_KEYDOWN:
            sprintf(str, "键盘按下:  %X, %c
    ", wParam , wParam);
            OutputDebugStringA(str);
            break;
        case  WM_CHAR:
            sprintf(str, "字符消息:  %X, %c
    ", wParam, wParam);
            OutputDebugStringA(str);
            break; 
        case  WM_KEYUP:
            sprintf(str, "键盘弹起:  %X, %c
    ", wParam, wParam);
            OutputDebugStringA(str);
            break;
    
        case  WM_SYSKEYDOWN: //alt同时按下的键
            sprintf(str, "系统按键按下:  %X, %c
    ", wParam, wParam);
            OutputDebugStringA(str);
            break;
        case  WM_SYSCHAR:  
            sprintf(str, "系统字符:  %X, %c
    ", wParam, wParam);
            OutputDebugStringA(str);
            break;
        case  WM_SYSKEYUP:
            sprintf(str, "系统按键弹起:  %X, %c
    ", wParam, wParam);
            OutputDebugStringA(str);
            break;
        }
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    
    int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
        LPSTR lpCmdLine, int  nShowCmd)
    {
        //1.注册窗口类
        WNDCLASS  wnd;
        wnd.cbClsExtra = 0;
        wnd.cbWndExtra = 0;
        wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
        wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
        wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                    //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
        wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
        wnd.lpszClassName = L"MrHuang";//窗口类名
        wnd.lpszMenuName = NULL;//菜单资源名称
        wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式,只有添加CS_DBLCLKS才能响应双击消息
        wnd.hInstance = hInstance;//实例句柄
        RegisterClass(&wnd);
    
        //创建窗口(返回之前发送WM_CREATE)
        HWND  hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
            WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);
    
        //显示窗口
        ShowWindow(hWnd, nShowCmd);
        //更新窗口(发送WM_PAINT)
        UpdateWindow(hWnd);
    //消息循环(收到WM_QUIT消息退出) MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);//翻译消息 DispatchMessage(&msg);//分发消息到窗口过程 } }

    注:wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式,只有添加CS_DBLCLKS才能响应双击消息

  • 相关阅读:
    根据数据类型选择特征 select_dtypes(include=[]/exclude=[])
    quantile()
    concat()、merge()的区别
    json.dumps()和json.loads()
    Linux-top命令详解
    性能测试总结(一)---基础理论篇
    jmeter-常见问题及解决方法
    Jmeter之Bean shell使用(五)
    Jmeter-内存溢出原因及解决方法
    JMeter- JDBC Request
  • 原文地址:https://www.cnblogs.com/mango1997/p/14607520.html
Copyright © 2020-2023  润新知