zoukankan      html  css  js  c++  java
  • 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才能响应双击消息

  • 相关阅读:
    js截取字符串区分汉字字母代码
    List 去处自定义重复对象方法
    63. Unique Paths II
    62. Unique Paths
    388. Longest Absolute File Path
    41. First Missing Positive
    140. Word Break II
    139. Word Break
    239. Sliding Window Maximum
    5. Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/mango1997/p/14607520.html
Copyright © 2011-2022 走看看