鱼C论坛

 找回密码
 立即注册
查看: 3669|回复: 1

[学习笔记] win32编程(002)——消息机制

[复制链接]
发表于 2017-6-14 20:17:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zzxwbs 于 2017-6-15 21:16 编辑
程序执行机制
过程驱动 - 程序的执行过程是按照预定好的顺序执行。
事件驱动 - 程序的执行是无序,用户可以根据需要随机触发相应的事件。
Win32窗口程序就是采用事件驱动方式执行,也就是消息机制。
当系统通知窗口工作时,就采用消息的方式派发给窗口。


1.消息组成
1.1窗口句柄
1.2消息ID
1.3消息的两个参数
1.4消息产生的时间
1.5消息产生时的鼠标位置

窗口创建中,有一个结构体为MSG,共有6个参数,正好对应上面6中消息
MSG structure
  1. typedef struct tagMSG {
  2.   HWND   hwnd;//窗口句柄
  3.   UINT   message;//消息ID
  4.   WPARAM wParam;//消息的一个参数
  5.   LPARAM lParam;//消息的另一个参数
  6.   DWORD  time;//消息产生的时间
  7.   POINT  pt;//消息产生时的鼠标位置
  8. } MSG, *PMSG, *LPMSG
复制代码


2.窗口处理函数和消息
每个窗口都必须具有窗口处理函数。
  1. LRESULT CALLBACK WindowProc(
  2.     HWND hwnd, //窗口句柄
  3.     UINT uMsg, //消息ID
  4.     WPARAM wParam, //消息参数
  5.     LPARAM lParam  //消息参数
  6. );
复制代码


当系统通知窗口时,会调用窗口处理函数同时,将消息ID和消息参数传递给窗口处理函数。
在窗口处理函数中,不处理的消息,使用缺省窗口处理函数,例如DefWindowProc。

3.消息相关函数
3.1GetMessage获取消息。

  1. BOOL GetMessage(
  2.         LPMSG lpMsg, //存放获取到的消息BUFF
  3.         HWND hWnd, //窗口句柄
  4.          UINT wMsgFilterMin,//获取消息的最小ID
  5.         UINT wMsgFilterMax   //获取消息的最大ID
  6. );
复制代码

lpMsg - 当获取到消息后,将消息的参数存放到MSG结构中。
hWnd - 获取到hWnd所指定窗口的消息。
wMsgFilterMin和wMsgFilterMax -只能获取到由它们指定的消息范围内的消息,如果都为0,表示没有范围。
返回值:如果函数取得WM_QUIT之外的其他消息,返回非零值。如果函数取得WM_QUIT消息,返回值是零

3.2TranslateMessage - 翻译消息。将按键消息,翻译成字符消息。
  1. BOOL TranslateMessage(
  2.             CONST MSG *lpMsg //要翻译的消息地址
  3.     );
复制代码

检查消息是否是按键的消息,如果不是按键消息,不做任何处理,继续执行。

3.3DispatchMessage - 派发消息。将消息派发到该消息所属窗口的窗口处理函数上。
  1. LRESULT DispatchMessage(
  2.             CONST MSG *lpmsg //要派发的消息
  3.         );
复制代码


3.4Windows常用消息
一般从3个方面去了解:消息的产生时间,消息的一般用法,消息的附带的两个信息
3.4.1WM_DESTROY
窗口被销毁时的消息(保存窗口数据的内存释放后),无消息参数。常用于在窗口被销毁之前,做相应的善后处理,例如资源、内存等。
3.4.2WM_SYSCOMMAND
系统命令消息,当点击窗口的最大化、最小化、关闭等命令时,收到这个消息。常用在窗口关闭时,提示用户处理。
wParam - 具体是什么命令,例如关闭SC_CLOSE等.
lParam - 鼠标位置(LOWORD 低字 - 水平位置,HIWORD 高字 - 垂直位置)
  1. long a;
  2. int x = a & 0x0000FFFF;//低字节
  3. int y = (a>>16) & 0x0000FFFF; //高字节
  4. int x = LOWORD(lParam);
  5. int y = HIWORD(lParam);
  6. #define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))
  7. #define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
复制代码

  1. #include "stdafx.h"

  2. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  3. {
  4.         switch (msgID)
  5.         {
  6.         case WM_SYSCOMMAND:
  7.                 MessageBox(hWnd,"WM_SYSCOMMAND","Infor",MB_OK);
  8.                 break;
  9.         case WM_DESTROY:
  10.                 PostQuitMessage(0);
  11.                 break;
  12.         default:
  13.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  14.         }
  15.         return DefWindowProc(hWnd, msgID, wParam, lParam);//试试return 0会是什么情况
  16. }

  17. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  18. {
  19.         WNDCLASSEX wc = { 0 };
  20.         wc.cbSize = sizeof(wc);
  21.         wc.hIconSm = NULL;
  22.         wc.cbClsExtra = 0;
  23.         wc.cbWndExtra = 0;
  24.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  25.         wc.hCursor = NULL;
  26.         wc.hIcon = NULL;
  27.         wc.hInstance = hInstance;
  28.         wc.lpfnWndProc = WndProc;
  29.         wc.lpszClassName = "fishc";
  30.         wc.lpszMenuName = NULL;
  31.         wc.style = CS_HREDRAW | CS_VREDRAW;
  32.         RegisterClassEx(&wc);
  33.         HWND hWnd = CreateWindow("fishic", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,NULL);
  34.         ShowWindow(hWnd,SW_SHOW);
  35.         UpdateWindow(hWnd);
  36.         MSG nMsg= { 0 };
  37.         while (GetMessage(&nMsg, NULL, 0, 0))
  38.         {
  39.                 TranslateMessage(&nMsg);
  40.                 DispatchMessage(&nMsg);
  41.         }
  42.         return 0;
  43. }
复制代码
  1. #include "stdafx.h"

  2. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  3. {
  4.         switch (msgID)
  5.         {
  6.         case WM_SYSCOMMAND:
  7.                 if(wParam == SC_CLOSE)
  8.                 {
  9.                         BOOL nRet = MessageBox(hWnd,"是否退出","信息",MB_YESNO);
  10.                         if(nRet == IDYES)
  11.                         {

  12.                         }
  13.                         else
  14.                         {
  15.                                 return 0;
  16.                         }
  17.                 }
  18.                 break;
  19.         case WM_DESTROY:
  20.                 PostQuitMessage(0);
  21.                 break;
  22.         default:
  23.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  24.         }
  25.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  26. }

  27. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  28. {
  29.         WNDCLASSEX wc = { 0 };
  30.         wc.cbSize = sizeof(wc);
  31.         wc.hIconSm = NULL;
  32.         wc.cbClsExtra = 0;
  33.         wc.cbWndExtra = 0;
  34.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  35.         wc.hCursor = NULL;
  36.         wc.hIcon = NULL;
  37.         wc.hInstance = hInstance;
  38.         wc.lpfnWndProc = WndProc;
  39.         wc.lpszClassName = "fishc";
  40.         wc.lpszMenuName = NULL;
  41.         wc.style = CS_HREDRAW | CS_VREDRAW;
  42.         RegisterClassEx(&wc);
  43.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,NULL);
  44.         ShowWindow(hWnd,SW_SHOW);
  45.         UpdateWindow(hWnd);
  46.         MSG nMsg= { 0 };
  47.         while (GetMessage(&nMsg, NULL, 0, 0))
  48.         {
  49.                 TranslateMessage(&nMsg);
  50.                 DispatchMessage(&nMsg);
  51.         }
  52.         return 0;
  53. }
复制代码


3.4.3WM_CREATE
在窗口创建成功还未显示之前,收到这个消息。常用于初始化窗口的参数、资源等等,包括创建子窗口等。       
WPARAM - 不使用
LPARAM - 是CREATESTRUCT结构的指针,保存了CreatWindowEx中的12个参数。
  1. #include "stdafx.h"

  2. void OnCreate(HWND hWnd,LPARAM lParam)
  3. {
  4.         CREATESTRUCT *pcs = (CREATESTRUCT*)lParam;//接收指针并打印内容
  5.         char *pszText = (char*)pcs->lpCreateParams;
  6.         MessageBox(hWnd,pszText,"信息",MB_OK);
  7. }

  8. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  9. {
  10.         switch (msgID)
  11.         {
  12.         case WM_CREATE:
  13.                 OnCreate(hWnd,lParam);
  14.                 break;
  15.         case WM_DESTROY:
  16.                 PostQuitMessage(0);
  17.                 break;
  18.         default:
  19.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  20.         }
  21.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  22. }

  23. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  24. {
  25.         WNDCLASSEX wc = { 0 };
  26.         wc.cbSize = sizeof(wc);
  27.         wc.hIconSm = NULL;
  28.         wc.cbClsExtra = 0;
  29.         wc.cbWndExtra = 0;
  30.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  31.         wc.hCursor = NULL;
  32.         wc.hIcon = NULL;
  33.         wc.hInstance = hInstance;
  34.         wc.lpfnWndProc = WndProc;
  35.         wc.lpszClassName = "fishc";
  36.         wc.lpszMenuName = NULL;
  37.         wc.style = CS_HREDRAW | CS_VREDRAW;
  38.         RegisterClassEx(&wc);
  39.         char *pszText = "fishc";//定义一个字符串并传给CreateWindow的最后一个参数
  40.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  41.         ShowWindow(hWnd,SW_SHOW);
  42.         UpdateWindow(hWnd);
  43.         MSG nMsg= { 0 };
  44.         while (GetMessage(&nMsg, NULL, 0, 0))
  45.         {
  46.                 TranslateMessage(&nMsg);
  47.                 DispatchMessage(&nMsg);
  48.         }
  49.         return 0;
  50. }
复制代码

  1. #include "stdafx.h"

  2. void OnCreate(HWND hWnd,LPARAM lParam)
  3. {
  4.         CreateWindowEx(0,"EDIT","fishc",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,NULL,NULL);//创建子窗口
  5. }

  6. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  7. {
  8.         switch (msgID)
  9.         {
  10.         case WM_CREATE:
  11.                 OnCreate(hWnd,lParam);
  12.                 break;
  13.         case WM_DESTROY:
  14.                 PostQuitMessage(0);
  15.                 break;
  16.         default:
  17.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  18.         }
  19.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  20. }

  21. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  22. {
  23.         WNDCLASSEX wc = { 0 };
  24.         wc.cbSize = sizeof(wc);
  25.         wc.hIconSm = NULL;
  26.         wc.cbClsExtra = 0;
  27.         wc.cbWndExtra = 0;
  28.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  29.         wc.hCursor = NULL;
  30.         wc.hIcon = NULL;
  31.         wc.hInstance = hInstance;
  32.         wc.lpfnWndProc = WndProc;
  33.         wc.lpszClassName = "fishc";
  34.         wc.lpszMenuName = NULL;
  35.         wc.style = CS_HREDRAW | CS_VREDRAW;
  36.         RegisterClassEx(&wc);
  37.         char *pszText = "fishc";
  38.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  39.         ShowWindow(hWnd,SW_SHOW);
  40.         UpdateWindow(hWnd);
  41.         MSG nMsg= { 0 };
  42.         while (GetMessage(&nMsg, NULL, 0, 0))
  43.         {
  44.                 TranslateMessage(&nMsg);
  45.                 DispatchMessage(&nMsg);
  46.         }
  47.         return 0;
  48. }
复制代码


3.4.4WM_SIZE
在窗口的大小发生变化后,会收到WM_SIZE。常用于窗口大小变化后,调整窗口内各个部分的布局。
WPARAM - 窗口大小变化的原因。
LPARAM - 变化窗口客户区的大小
LOWORD - 变化后的宽度
HIOWORD- 变化后的高度

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. void OnSize(HWND hWnd,LPARAM lParam)
  4. {
  5.         int nWight = LOWORD(lParam);
  6.         int nHight = HIWORD(lParam);
  7.         char szText[256] = {0};
  8.         sprintf(szText,"WM_SIZE:宽=%d,高=%d\n",nWight,nHight);
  9.         MessageBox(hWnd,szText,"信息",MB_OK);
  10. }

  11. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  12. {
  13.         switch (msgID)
  14.         {
  15.         case WM_SIZE:
  16.                 OnSize(hWnd,lParam);
  17.                 break;
  18.         case WM_DESTROY:
  19.                 PostQuitMessage(0);
  20.                 break;
  21.         default:
  22.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  23.         }
  24.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  25. }

  26. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  27. {
  28.         WNDCLASSEX wc = { 0 };
  29.         wc.cbSize = sizeof(wc);
  30.         wc.hIconSm = NULL;
  31.         wc.cbClsExtra = 0;
  32.         wc.cbWndExtra = 0;
  33.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  34.         wc.hCursor = NULL;
  35.         wc.hIcon = NULL;
  36.         wc.hInstance = hInstance;
  37.         wc.lpfnWndProc = WndProc;
  38.         wc.lpszClassName = "fishc";
  39.         wc.lpszMenuName = NULL;
  40.         wc.style = CS_HREDRAW | CS_VREDRAW;
  41.         RegisterClassEx(&wc);
  42.         char *pszText = "fishc";
  43.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  44.         ShowWindow(hWnd,SW_SHOW);
  45.         UpdateWindow(hWnd);
  46.         MSG nMsg= { 0 };
  47.         while (GetMessage(&nMsg, NULL, 0, 0))
  48.         {
  49.                 TranslateMessage(&nMsg);
  50.                 DispatchMessage(&nMsg);
  51.         }
  52.         return 0;
  53. }
复制代码


3.4.5WM_QUIT
用于结束消息循环处理。一般不需要我们处理
wParam - PostQuitMessage 函数传递的参数。
lParam - 不使用
当GetMessage收到这个消息后,会返回FALSE,结束while处理,退出消息循环。

3.4.5绘图消息,键盘消息,鼠标消息,定时器消息(暂时pass,后面几期再说)

3.5消息的获取
3.5.1GetMessage - 从系统获取消息,将消息从系统中移除,阻塞函数。当系统无消息时,GetMessage会等候下一条消息。
3.5.2PeekMessage - 以查看的方式从系统获取消息,可以不将消息从系统移除,非阻塞函数。当系统无消息时,返回FALSE,继续执行后续代码。
  1. BOOL PeekMessage(
  2. LPMSG lpMsg,         // message information
  3. HWND hWnd,           // handle to window
  4. UINT wMsgFilterMin,  // first message
  5. UINT wMsgFilterMax,  // last message
  6. UINT wRemoveMsg //移除标识
  7. );
复制代码

  1. #include "stdafx.h"
  2. #include "stdio.h"

  3. void OnSize(HWND hWnd,LPARAM lParam)
  4. {
  5.         int nWight = LOWORD(lParam);
  6.         int nHight = HIWORD(lParam);
  7.         char szText[256] = {0};
  8.         sprintf(szText,"WM_SIZE:宽=%d,高=%d\n",nWight,nHight);
  9.         MessageBox(hWnd,szText,"信息",MB_OK);
  10. }

  11. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  12. {
  13.         switch (msgID)
  14.         {
  15.         case WM_SIZE:
  16.                 OnSize(hWnd,lParam);
  17.                 break;
  18.         case WM_DESTROY:
  19.                 PostQuitMessage(0);
  20.                 break;
  21.         default:
  22.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  23.         }
  24.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  25. }

  26. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  27. {
  28.         WNDCLASSEX wc = { 0 };
  29.         wc.cbSize = sizeof(wc);
  30.         wc.hIconSm = NULL;
  31.         wc.cbClsExtra = 0;
  32.         wc.cbWndExtra = 0;
  33.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  34.         wc.hCursor = NULL;
  35.         wc.hIcon = NULL;
  36.         wc.hInstance = hInstance;
  37.         wc.lpfnWndProc = WndProc;
  38.         wc.lpszClassName = "fishc";
  39.         wc.lpszMenuName = NULL;
  40.         wc.style = CS_HREDRAW | CS_VREDRAW;
  41.         RegisterClassEx(&wc);
  42.         char *pszText = "fishc";
  43.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  44.         ShowWindow(hWnd,SW_SHOW);
  45.         UpdateWindow(hWnd);
  46.         MSG nMsg= { 0 };
  47.         /*
  48.         while (GetMessage(&nMsg, NULL, 0, 0))
  49.         {
  50.                 TranslateMessage(&nMsg);
  51.                 DispatchMessage(&nMsg);
  52.         }
  53.         */
  54.         while(1)
  55.         {
  56.                 if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE))
  57.                 {
  58.                         //有消息
  59.                         if(GetMessage(&nMsg,NULL,0,0))
  60.                         {
  61.                                 TranslateMessage(&nMsg);
  62.                                 DispatchMessage(&nMsg);
  63.                         }
  64.                         else
  65.                         {
  66.                                 return 0;
  67.                         }
  68.                 }
  69.                 else
  70.                 {
  71.                         //没消息时的空闲处理
  72.                 }
  73.         }
  74.         return 0;
  75. }
复制代码


3.6消息的发送
3.6.1SendMessage - 发送消息,会等候消息处理的结果。
3.6.2PostMessage - 投递消息,消息发出后立刻返回,不等候消息执行结果。
  1. BOOL SendMessage/PostMessage(
  2.                 HWND hWnd,//消息发送的目的窗口
  3.                 UINT Msg, //消息ID
  4.                 WPARAM wParam, //消息参数
  5.                 LPARAM lParam  //消息参数
  6.         );
复制代码

  1. #include "stdafx.h"

  2. LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
  3. {
  4.         switch (msgID)
  5.         {
  6.        
  7.         case WM_DESTROY:
  8.                 //PostQuitMessage(0);
  9.                 PostMessage(hWnd,WM_QUIT,0,0);
  10.                 break;
  11.         default:
  12.                 return DefWindowProc(hWnd, msgID, wParam, lParam);
  13.         }
  14.         return DefWindowProc(hWnd, msgID, wParam, lParam);
  15. }

  16. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
  17. {
  18.         WNDCLASSEX wc = { 0 };
  19.         wc.cbSize = sizeof(wc);
  20.         wc.hIconSm = NULL;
  21.         wc.cbClsExtra = 0;
  22.         wc.cbWndExtra = 0;
  23.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  24.         wc.hCursor = NULL;
  25.         wc.hIcon = NULL;
  26.         wc.hInstance = hInstance;
  27.         wc.lpfnWndProc = WndProc;
  28.         wc.lpszClassName = "fishc";
  29.         wc.lpszMenuName = NULL;
  30.         wc.style = CS_HREDRAW | CS_VREDRAW;
  31.         RegisterClassEx(&wc);
  32.         char *pszText = "fishc";
  33.         HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
  34.         ShowWindow(hWnd,SW_SHOW);
  35.         UpdateWindow(hWnd);
  36.         MSG nMsg= { 0 };
  37.         /*
  38.         while (GetMessage(&nMsg, NULL, 0, 0))
  39.         {
  40.                 TranslateMessage(&nMsg);
  41.                 DispatchMessage(&nMsg);
  42.         }
  43.         */
  44.         while(1)
  45.         {
  46.                 if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE))
  47.                 {
  48.                         //有消息
  49.                         if(GetMessage(&nMsg,NULL,0,0))
  50.                         {
  51.                                 TranslateMessage(&nMsg);
  52.                                 DispatchMessage(&nMsg);
  53.                         }
  54.                         else
  55.                         {
  56.                                 return 0;
  57.                         }
  58.                 }
  59.                 else
  60.                 {
  61.                         //没消息时的空闲处理
  62.                 }
  63.         }
  64.         return 0;
  65. }
复制代码


3.7消息的分类
3.7.1系统消息 - ID范围 0 - 0x03FF(0-1023)
由系统定义好的消息,可以在程序中直接使用。

3.7.2用户自定义消息 - ID范围 0x0400 - 0x7FFF
由用户自己定义,满足用户自己的需求。由用户自己发出消息,并响应处理。
自定义消息宏:WM_USER
  1. #define WM_MYMESSAGE WM_USER+n
复制代码


3.7.3应用程序消息 - ID范围 0x8000 - 0xBFFF
程序之间通讯时使用的消息。
应用程序消息宏:WM_APP

3.7.4系统注册消息 - ID范围 0xC000 - 0xFFFF
在系统注册并生成相应消息,然后可以在各个程序中使用这个消息。

#include "stdafx.h"
#include "stdio.h"
#define WM_MYMESSAGE WM_USER+1001

void OnMyMessage(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
        char szText[256] = {0};
        sprintf(szText,"自定义消息被处理wParam=%d,lParam=%d",wParam,lParam);
        MessageBox(hWnd,szText,"信息",MB_OK);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
        switch (msgID)
        {
        case WM_MYMESSAGE:
                OnMyMessage(hWnd,wParam,lParam);
                break;
        case WM_DESTROY:
                //PostQuitMessage(0);
                PostMessage(hWnd,WM_QUIT,0,0);
                break;
        default:
                return DefWindowProc(hWnd, msgID, wParam, lParam);
        }
        return DefWindowProc(hWnd, msgID, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLince, int iCmdShow)
{
        WNDCLASSEX wc = { 0 };
        wc.cbSize = sizeof(wc);
        wc.hIconSm = NULL;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wc.hCursor = NULL;
        wc.hIcon = NULL;
        wc.hInstance = hInstance;
        wc.lpfnWndProc = WndProc;
        wc.lpszClassName = "fishc";
        wc.lpszMenuName = NULL;
        wc.style = CS_HREDRAW | CS_VREDRAW;
        RegisterClassEx(&wc);
        char *pszText = "fishc";
        HWND hWnd = CreateWindow("fishc", "fishc",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hInstance,pszText);
        ShowWindow(hWnd,SW_SHOW);
        UpdateWindow(hWnd);
        MSG nMsg= { 0 };
        PostMessage(hWnd,WM_MYMESSAGE,1,2);
        //SendMessage(hWnd,WM_MYMESSAGE,1,2);
        while (GetMessage(&nMsg, NULL, 0, 0))
        {
                TranslateMessage(&nMsg);
                DispatchMessage(&nMsg);
        }
        return 0;
}

4.消息队列
消息队列用于存放消息的一个队列,消息在队列中先入先出。所有窗口程序都具有消息队列。程序可以从队列中获取消息。

4.1消息队列的类型
4.1.1系统消息队列-由系统维护的消息队列。存放系统产生的消息,例如鼠标、键盘等。
4.1.2程序消息队列-属于每一个应用程序的消息队列。由应用程序维护。

4.2消息队列的关系
4.2.1当鼠标、键盘产生消息时,会将消息存放到系统消息队列
4.2.2系统会根据存放的消息,找到对应程序的消息队列。
4.2.3将消息投递到程序的消息队列中。

4.3消息的分类
根据消息和消息队列之间使用关系,将消息分成两类:

4.3.1队列消息 - 消息的发送和获取,都是通过消息队列完成。
队列消息-消息发送后,首先放入队列,然后通过消息循环,从队列当中获取。
GetMessage - 从消息队列中获取消息
PostMessage - 将消息投递到消息队列
常见队列消息:WM_PAINT、键盘、鼠标、定时器。

4.3.2非队列消息 - 消息的发送和获取,是直接调用消息的窗口处理完成。
非队列消息-消息发送时,首先查找消息接收窗口的窗口处理函数,直接调用处理函数,完成消息。
SendMessage - 直接将消息发送给窗口的处理函数,并等候处理结果。
常见消息:WM_CREATE、WM_SIZE等。

4.4关于消息相关的总结
GetMessage /PeekMessage从程序的消息队列当中,获取到消息。
TranslateMessage 检查获取到的消息,如果发现是按键消息,产生一个字符消息,并放入程序的消息队列。
DispatchMessage 根据消息,找到窗口处理函数,调用窗口处理函数,完成消息的处理。

在程序消息队列查找消息,如果队列有消息,检查消息是否满足指定条件(HWND,ID范围),不满足条件就不会取出消息,否则从队列取出消息返回。
如果程序消息队列没有消息,向系统消息队列获取属于本程序的消息。如果系统队列的当前消息属于本程序,系统会将消息转发到程序消息队列中。
如果系统消息队列也没有消息,检查当前进程的所有窗口的需要重新绘制的区域,如果发现有需要绘制的区域,产生WM_PAINT消息,取得消息返回处理。
如果没有重新绘制区域,检查定时器如果有到时的定时器,产生WM_TIMER,返回处理执行。
如果没有到时的定时器,整理程序的资源、内存等等。
GetMessage会继续等候下一条消息。PeekMessage会返回FALSE,交出程序的控制权。
注意:GetMessage如果获取到是WM_QUIT,函数会返回FALSE。

SendMessage
发送消息到指定的窗口,并等候对方将消息处理,然后消息执行结果,用于非队列消息的发送。
PostMessage
将消息放到消息队列中,立刻返回,用于队列消息的发送。
无法获知消息是否被对方处理。

评分

参与人数 1鱼币 +6 收起 理由
小甲鱼 + 6 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-11 16:56:52 | 显示全部楼层
这个还是很有价值的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 16:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表