设为首页 加入收藏

TOP

11.2.1 WinMain()函数(4)
2013-10-07 16:10:26 来源: 作者: 【 】 浏览:90
Tags:11.2.1 WinMain 函数

11.2.1  WinMain()函数(4)

该函数只需要一个实参:标识特定程序窗口的窗口句柄hWnd。该调用的结果是Windows给程序发送一条请求重画工作区的消息。

4. 处理Windows消息

最后一项需要WinMain()完成的任务是处理Windows为应用程序排好的消息队列。这么说似乎有点儿奇怪,因为前面曾经说过需要WindowProc()函数来处理消息,下面进一步解释。

排队消息与非排队消息

前面介绍的Windows消息概念过于简化。事实上有两种Windows消息。

一种是被Windows放入队列的排队消息,WinMain()函数必须从队列中提取这些消息进行处理。WinMain()函数中做这件事的代码称为消息循环。排队消息包括因用户从键盘输入、移动鼠标以及单击鼠标按钮而产生的消息。来自定时器的消息和请求重画窗口的Windows消息也都是排队消息。

另一种是致使Windows直接调用WindowProc()函数的非排队消息。大量的非排队消息是作为处理排队消息的结果产生的。我们在WinMain()函数内消息循环中所做的事情是从Windows为应用程序排好的消息队列中提取一条消息,然后请求Windows调用WindowProc()函数来处理该消息。为什么Windows不能在需要时直接调用WindowProc()函数呢?当然可以,但只是没有以这种方式工作,原因与Windows对多个同时执行的应用程序的管理方式有关。

消息循环

如前所述,从消息队列中获取消息是使用某种标准机制完成的,该机制在Windows编程(www.cppentry.com)中称为消息泵或消息循环。消息循环的代码如下所示:

  1. MSG msg;                                                // Windows message structure  
  2. while(GetMessage(&msg, 0, 0, 0) == TRUE)            // Get any messages  
  3. {  
  4. TranslateMessage(&msg);                             // Translate the message  
  5. DispatchMessage(&msg);                                  // Dispatch the message  
  6. }  

这部分代码涉及处理每条消息的3个步骤:

GetMessage():从队列中检索一条消息。

TranslateMessage():对检索的消息执行任何必要的转换。

DispatchMessage():使Windows调用应用程序的WindowProc()函数来处理消息。

GetMessage()函数的作用非常重要,因为它对Windows处理多个应用程序的方式具有重大贡献。接下来详细地看一看这个函数。

GetMessage()函数检索应用程序窗口的消息队列中的某条消息,并将与该消息有关的信息存储在第一个实参指向的变量msg。变量msg是MSG类型的struct,包含许多没有在这里访问的不同成员。但为完整起见,下面给出该结构的定义:

  1. struct MSG  
  2. {  
  3. HWND hwnd;                                                      // Handle for the relevant window  
  4. UINT message;                                               // The message ID  
  5. WPARAM wParam;                                          // Message parameter (32-bits)  
  6. LPARAM lParam;                                          // Message parameter (32-bits)  
  7. DWORD time;                                                 // The time when the message was queued  
  8. POINT pt;                                                           // The mouse position  
  9. };  

前面提到的对匈牙利表示法前缀的误解现在可能在wParam成员上成为现实。我们可能认为该成员属于WORD类型(即16位无符号整数),这种想法在早期的Windows版本中是正确的,但现在该成员属于WPARAM类型,它是一个32位整数值。

wParam和lParam成员的确切内容取决于消息的种类。message成员中的消息ID是一个整数值,它可以是一组在windows.h头文件中预定义为符号常量的值之一。普通窗口的消息ID都以WM_开始,典型的例子如表11-3所示。普通窗口消息覆盖了大量不同的事件,并且包括与鼠标和菜单事件、键盘输入以及窗口创建和管理相关的消息。

表  11-3

ID
   
WM_PAINT
应该重画窗口
WM_SIZE
已重新调整窗口大小
WM_LBUTTONDOWN
按下鼠标左键
WM_RBUTTONDOWN
按下鼠标右键
WM_MOUSEMOVE
已移动鼠标
WM_CLOSE
应该关闭窗口或应用程序
WM_DESTROY
正在销毁窗口
WM_QUIT
应该终止程序

GetMessage()函数总是返回TRUE,除非该消息是终止程序的WM_QUIT(此时返回值是FALSE),或者发生了错误(此时返回值是-1)。因此,while循环将持续执行,直到产生关闭应用程序的退出消息或者出现错误状态。在这两种情况下,都需要在return语句中将wParam值回传给Windows,来结束程序。

对于为不同于普通窗口的其他窗口类型指定的消息,也有除了WM之外的前缀。

对GetMessage()函数的调用中,第二个实参是某个窗口的句柄,希望为该窗口获取消息。该参数可用来单独地为某一个窗口检索消息。如果该参数像此处这样是0,则GetMessage()函数将检索应用程序的所有消息。这是一种简单的检索该程序所有消息的方法,而不管某个应用程序有多少窗口。它也是最安全的方法,因为我们肯定可以获得应用程序的全部消息。例如,当Windows程序的用户关闭应用程序的窗口时,该窗口是在生成WM_QUIT消息之前关闭的。因此,如果仅仅通过给GetMessage()函数指定窗口句柄来检索消息,则不能检索这条WM_QUIT消息,导致程序不能正常终止。
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇11.2.1 WinMain()函数(3) 下一篇11.2.1 WinMain()函数(5)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·python数据分析岗的 (2025-12-25 10:02:21)
·python做数据分析需 (2025-12-25 10:02:19)
·成为一个优秀的pytho (2025-12-25 10:02:16)
·Java后端面试实习自 (2025-12-25 09:24:21)
·Java LTS版本有哪些 (2025-12-25 09:24:18)