2.05 消息循环原理

消息循环的阻塞

GetMessage 从系统获取消息, 将消息从系统中移除, 阻塞函数. 当系统无消息时, 会等待下一条消息

OeekMessage 以查看的方式从系统获取消息, 可以不将消息从系统移除, 非阻塞函数. 当系统无消息时, 返回FALSE, 继续执行后续代码.

  1. BOOL PeekMessage(
  2. LPMSG lpMsg, // 信息
  3. HWND hWnd, // 窗口句柄
  4. UINT wMsgFilterMin // 附加消息1
  5. UINT wMsgFilterMax // 附加消息2
  6. UINT wRemoveMsg //移除标识, 是否像GetMessage一样移除消息 PM_REMOVE/ PM_NOREMOVE
  7. );
  1. while(1){
  2. if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){
  3. if(GetMessage(&nMsg,NULL,0,0)){
  4. TranslateMessage(&nMsg);
  5. DispatchMessage(&nMsg);
  6. }else{
  7. return; // 退出程序
  8. }
  9. }else{
  10. // 没消息 空闲处理
  11. WriteConsole(g_hOutput,"Onldle",strlen("Onldle"),NULL,NULL);
  12. }
  13. }

发送消息

SendMessage -> 消息队列 -> GetMessage -> TranslateMessage -> DispatchMessage -> WndProd(窗口处理函数)

SendMessage: 发送消息(打电话),阻塞, 会等候消息处理的结果。

PostMessage: 投递消息(投递邮筒),消息发出后立刻返回,不等候消息执行结果。

  1. BOOL SendMessage/PostMessage(
  2. HWND hWnd, //消息发送的目的窗口
  3. UINT Msg, //消息ID
  4. WPARAM wParam, //消息参数
  5. LPARAM lParam //消息参数
  6. );
  1. PostQuitMessage(0);
  2. PostMessage(hWnd,WM_QUIT,0,0);

区别

SendMessage 发送到消息队列, PostMessage 发到(不是消息队列)

SendMessage 函数会将调用线程阻塞,直到消息处理完毕并返回结果。而 PostMessage 函数则不会阻塞调用线程,它只是将消息放入队列中,由消息循环来异步处理。

消息分类

系统消息- 系统定义好的消息,可以直接在程序中使用, 只负责发送或处理. ID为 0- 0x03FF (1024个)

用户自定义消息- 自行发送并自行处理. ID范围为 0x0400 - 0x7FFF(31743)

自定义消息宏: WM_USER(即0x0400)

  1. // 自定义消息
  2. // 定义
  3. #define WM_MYMESSAGE WM_USER+10(小于31743的值)
  4. // 发送
  5. PostMessage(hWnd,WM_MYMESSAGE,1,2);
  6. // 接受
  7. case WM_MYMESSAGE:
  8. xx(hWnd,wParam,lParam); // 处理函数
  9. break;