消息处理(Message Handling)

来源:互联网 发布:二维码识别源码 编辑:程序博客网 时间:2024/06/07 21:04
消息处理(Message Handling)
       应用程序必须移除并处理被发布到线程消息队列中的消息。一个单线程应用程序通常利用消息循环在WinMain函数中,移除并发送消息到合适的窗口过程进行处理。多线程应用程序可以在每个创建窗口的线程里包括一个消息循环。接下来的部分描述了消息队列如何工作以及解释了窗口过程的地位:
        消息循环(Message Loop)
        一个简单的消息循环有三个函数调用组成:GetMessage函数,TranslateMessage函数,DispatchMessage函数。注意,如果有错误发生,GetMessage函数会返回-1--因此需要特别的测试。
    
    MSG msg;
    
    While(GetMessage(&msg,NULL,0,0)>0)
    {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
     }


        GetMessage函数从队列中获取一条消息,然后把它填充到MSG数据类型中。这个函数成功执行后会返回一个非零值,然而当这个函数遇到WM_QUIT消息时,它会返回FALSE并且结束循环。在单线程程序中,结束消息循环往往是关闭程序的第一步。应用程序可以利用PostQuitMessage函数结束自己的消息循环。响应在应用程序主窗口的窗口过程中的WM_DESTROY消息。
        如果你指定一个窗口句柄作为GetMessage函数的第二个参数,那么只能从消息队列中获取针对这个窗口的消息。GetMessage函数也可以过滤队列中的消息,只获取属于一个特殊级别的消息。关于过滤消息的更多信息,参见Message Filtering。
        如果线程是用来接收键盘输入消息,那么线程消息循环必须包括TranslateMessage。当用户每次按下一个键时,系统会产生虚拟键消息(WM_DEYDOWN和WM_KEYUP)而不是字符值。为了获取这个值,消息循环必须包括TranslateMessage函数,这个函数会把虚拟键消息翻译成字符消息(WM_CHAR),并把翻译后的字符消息放回应用程序消息队列中。这个字符消息在消息循环的连续迭代中被移到队列首部,然后被分配给窗口过程。
         DispatchMessage函数发送一个消息到窗口过程,这个窗口过程与指定MSG结构的窗口句柄有关。如果窗口句柄是HWND_TOPMOST,DispatchMessage函数为系统中最高级别的窗口的窗口过程发送消息。如果窗口句柄是NULL,DispatchMessage函数不会对消息做任何事。
         应用程序主线程在初始化应用程序以及创建至少一个窗口之后,会开始它的消息循环。消息循环一旦开始后,将持续从线程消息队列中获取消息,并把这些消息发送给合适的窗口。当GetMessage函数从消息队列中移出WM_QUIT消息时,消息循环会结束。
         即使一个应用程序包含许多窗口,对于一个消息队列只需要一个消息循环。DispatchMessage函数总是把消息发送给合适的窗口,这是因为每个消息队列中的消息是一个MSG结构,这个结构包含消息关联的窗口句柄。
        你可以通过多种方式修改消息循环。例如,你可以从队列中获取消息而不需要把这些消息发送到窗口。当应用程序发布不指定任何窗口的消息时,这种方式是很有用的。你也可以指导GetMessage函数查找指定的消息,而把其他的消息留在队列中。如果你必须临时忽视消息队列先进先出(FIFO)的规则,那么这个方式很有用。
        应用程序如果使用了快捷键,那么应用程序必须可以把键盘消息翻译成控制消息。应用程序消息循环必须包含TranslateAccelerator函数来做这件事。更多关于快捷键信息参见Keyboard Accelerator。
        如果线程使用了非模态对话框,消息循环必须包含IsDialogMessage函数,这样对话框可以接收键盘输入消息。


        窗口过程(Window Procedure)
        一个窗口过程是一个接收并处理所有发送到窗口的消息的函数。每个窗口类都有一个窗口过程。每个利用相同窗口类创建的窗口使用相同的窗口过程响应消息。
       系统通过把消息数据作为窗口过程的参数,来实现发送消息到窗口过程。然后窗口过程为消息执行合适的动作。窗口过程会检查消息标识符,利用消息参数信息处理消息。
        过程通常不会忽略一条消息。如果遇到不能处理的消息,窗口过程会把这条消息发送回系统让系统默认窗口过程处理。窗口通过调用DefWindowPro函数来实现这个功能,这个函数执行默认的动作并返回消息结果。窗口过程必须返回这个值作为其自己的消息结果。大多数窗口过程只能处理一部分消息,而把其它的消息通过调用DefWindowProc函数传递给系统。
        因为一个窗口过程被属于一个窗口类的所有窗口共享,所以这个窗口过程可以为多个不同窗口处理消息。为了鉴定被消息影响的特定的窗口,一个窗口过程可以检查窗口句柄。
原创粉丝点击