Messages and Message Queues

typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG,
*PMSG, *LPMSG;

About Messages and Message Queues

不是程序主动调用, 而是等待系统传入参数唤醒
顶层窗口不响应时, 系统隐藏窗口并且用一个ghost window替换它?

Windows Messages

系统和窗口处理函数,通过message交流

系统和应用程序都产生消息

一个应用程序 可以直接发送消息 给他自己的窗口 去执行。或者和在其他应用程序中的窗口交流

消息有四个函数:

a window handle, a message identifier, and two values called message parameters.

系统通过它决定,哪个窗口处理函数应该接收他。

Message的参数指定data or the location of data 

 

integer, packed bit flags, a pointer to a structure containing additional data, and so on.

Message Types

System-Defined Messages


Message Routing

队列消息:WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEY  DOWN, 等用户输入信息。

非队列消息: WM_TIMER, WM_PAINT, WM_QUIT.

Queued Messages

系统可以在一个时刻,显示任意数量的窗口。 将 鼠标和键盘的输入 路由到适当的窗口, 系统使用消息队列。

系统持有一个单独的“系统队列”和一个“线程独有队列”为每个GUI线程。 

Queued Messages

无论用户移动,单击鼠标,敲击键盘, 设备驱动都会将输入 放入“系统消息队列”. 系统队列 检查每一个消息 来决定目标窗口, 然后投递他们到“线程队列”。

一个“线程队列”接收所有 “窗口创建的” 鼠标键盘消息。 线程移除每一个消息 并 递交给系统去 运送他们到 适当的窗口函数和线程。

有三个例外的消息: WM_PAINT, WM_TIMER, WM_QUIT.

他们三个 只有在系统消息队列中 没有其他消息时,才被转发到 窗口。 另外 对于同一窗口的多个WM_PAINT被合并为一个WM_PAINT, 所有无效区域合并为一个总的无效区域。

系统投递消息到 线程消息队列,通过填充MSG结构包括: handle(目的地窗口的Handle), 消息定义,两个参数,时间,鼠标点。 

一个线程可以 向自己的 “线程消息队列” 投递消息,或者其他线程, 通过PostMessage, PostThreadMessage.

一个应用程序可以用GetMessage去除自己队列中的一个消息. 检查但不去除消息,可以使用PeekMessage.

DispatchMessage驱动系统传送消息到 窗口处理过程。包括(handle, message_identifier, two message parameters)

对于投递时间和投递位置, 需要用GetMessageTime GetMessagePos获取。

WaitMessage可以将当前进程挂起, 直到进程中收到消息。

Nonqueued Messages

非队列消息, 立即被传送到目标窗口过程, 跳过“系统队列”和“进程队列”。

有一些典型地发送非队列消息的情况,来直接影响窗口的状态。eg:

当用户激活一个新的应用程序窗口时, 系统发送一系列消息,包括WM_ACTIVATE,WM_SETFOCUS,WM_SETCURSOR.

一些系统函数会产生非队列消息, 例如, 系统调用SetWindowPos发送WM_WINDOWPOSCHANGED消息之后。

其他一些发送非队列消息的函数: BroadcastSystemMessage, BroadcastSystemMessageEx, SendMessage, SendMessageTimeout, SendNotifyMessage.

Message Handling

TranslateMessage将键盘虚拟键,转换为可识别的字符码。

 DispatchMessage:  发送Handle!=null的消息,到相应的Handle

如果线程使用了 非模态对话框, 消息循环必须判断 IsDialogMessage以至于对话框可以 收到键盘输入。

Window Procedure

对于用户不处理的消息,可以抛给DefWindowProc处理。

Message Filtering

GetMessage, PeekMessage最后一个参数,填写过滤范围

WM_KEYFIRST, WM_KEYLAST,检索键盘消息

WM_MOUSEFIRST, WM_MOUSELAST, 检索鼠标消息

如果GetMessage(...,NUM)不存在,GetMessage则不返回,一直等待

Posting and Sending Messages

SendMessageCallBack: 处理完这条消息, 就调用CallBack函数处理

SendMessageTimeOut: 超时作废

SendNotifyMessage: 如果是同线程, 则等处理完返回, 如果是异线程,则直接返回

SendDlgItemMessage: 向Dialog中控件发送消息

Posting Messages

PostMessage(NULL,..)送给当前线程的 Message Queue

HWND_TOPMOST  all top window

满的时候,查看返回值。

SendMessage 调用的线程,要等处理完返回,才能继续工作。

Message Deadlocks

A线程发送给B线程时, 需要等SendMessage返回, 这时候可能造成 死锁。  如果对方暂停的时候。

小结

1.  “自己发的”消息PostMessage, PostThreadMessage,RedrawWindow “目的地指定HWND窗口句柄

2.  “系统发的”键盘事件,焦点在哪个窗口,就发给哪个窗口。鼠标事件, desktop时鼠标在哪个窗口上, 就发送给哪个窗口。

3.  GetMessage获取进程消息队列中的消息DispatchMessage将消息除时间坐标的内容发送到相应窗口函数处理。

posted on 2011-02-27 11:05  oleeceo  阅读(362)  评论(0)    收藏  举报

导航