Windows桌面开发之消息

应用程序与消息

通常情况下,系统将消息发送给对应窗口的window procedure函数。
这个函数负责处理消息,如果它处理消息的时间过长,则系统认定该应用已经失去响应。
系统会生成一个ghost window,这个窗体能做一些简单的移动、拉伸等操作。
 

消息分类:

  • 系统消息
    • 系统生成,例如移动鼠标、按下键盘等等用户行为
    • 系统定义的消息一般都以固定的前缀开头
    • 例如,常见的系统消息是WM开头,包含了鼠标、键盘、剪贴板、计时器等等最常用的消息
  • 应用消息
    • 应用程序根据需要自行生成
    • 有以下限制
      • 0x0000 ~ 0x03FF 系统占用,不可使用
      • 应用程序可以在 0x0400 ~ 0x7FFF 中挑选一个数字,然后标记成自定义的消息,进行传播。应用标记4.0,则 0x8000 ~ 0xBFFF范围也可以使用
      • 注意这个消息在窗体类私有的,可能多个窗体类
      • 使用方法 RegisterWindowMessageA来注册一个消息,返回值位于0xC000 ~ 0xFFFF 作为消息标识符。如果返回0,则注册失败
      • 这样是为了防止其他应用程序也使用相同数字作为自己的消息,进行通信,导致进程之间处理错误的消息。

发送消息

系统发送消息时,有两种方式
  • Queued Messages
    • 系统为每一个GUI线程维护一个单独的消息队列
    • 属于这个线程创建的所有窗口的Queued Message(例如:鼠标、键盘)都推送到队列中
    • 应用程序不断的循环消息队列,取出消息,并再次发送给特定的窗口
    • 系统放置消息的时候一般都是放到队尾
    • 提取消息时,遇到WM_PAINT、WM_TIMER、WM_QUIT这三种消息,它们会在队列中暂存,除非再也没有其它消息处理了,原因是为了减少重绘次数,提升性能
    • 有以下API可以发送处理消息:
      • PeekMessage,仅查看消息
      • GetMessage,提取消息
      • DispatchMessage,发送给特定窗口的window procedure函数
      • PostMessage、PostThreadMessage 把消息发送给其他线程
    • 常见的Queued Message
      • WM_MOUSEMOVE
      • WM_LBUTTONDOWN
      • WM_KEYDOWN
      • WM_CHAR
      • WM_TIMER
      • WM_PAINT
      • WM_QUIT
  • Nonqueued Messages
    • WM_ACTIVATE、 WM_SETFOCUS、WM_SETCURSOR
    • 直接发送给特定的窗体的 window procedure 处理函数
    • 使用以下API发送这类消息
      • BroadcastSystemMessage, BroadcastSystemMessageEx
      • SendMessage, SendMessageTimeout
      • SendNotifyMessage

处理消息

一个window procedure处理消息时,会接收到4个参数
  • window handle
    • 指明哪个窗体处理此消息
  • message identifier
    • 消息内容
  • message parameters(2个)
    • 消息携带的额外数据

处理方法

MSG msg;
BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

 

posted @ 2022-09-17 15:30  内心澎湃的水晶侠  阅读(63)  评论(0编辑  收藏  举报