MFC消息传递

首先讲几个概念:

 

一般来说,每个应用程序都有一个UI线程,应该说大部分应用程序都只有一个UI线程。

 

UI线程,简单的理解:1,是一个线程。 2,创建了UI(准确的说应该是进行了消息循环)。

 

在MFC的应用框架中UI线程一般就是CWinApp的派生类。因为CWinApp派生自CWinThread,具有处理线程的功能(满足第1点)。

 

在CWinApp派生类的InitInstance中创建了主窗口(满足第2点)。在上一篇文章“程序的生和死”中已经写了,在InitInstance返回后就会调用run函数进行消息循环。

 

ok,说了UI线程,接着说消息队列。UI线程创建UI的同时,Windows系统会为线程创建一个消息队列,这个消息队列和线程是相关的。

(一般的应用程序只有一个UI线程,因此大部分应用程序也就只有一个消息队列。---注:这是我的理解)

 

消息队列是一个称为THREADINFO的结构,THREADINFO是一个未公开的数据结构,用来指定线程的登记消息队列(posted-message queue)、发送消息队列( send-message queue)、应答消息队列( r e p l y -message queue)、虚拟输入队列(virtualized-input queue)、唤醒标志(wake flag)、以及用来描述线程局部输入状态的若干变量。

 

 

针对不同消息的消息传递:

1,键盘,鼠标等系统消息。

针对这些消息,windows 驱动会将消息发送到UI线程的消息队列,不同的消息类型排到不同的消息队列。

主线程的run函数会从消息队列中取出消息,然后TranslateMessage(转换消息),然后DispatchMessage(派发消息)。因为消息结构中已经有消息要发送到的窗口句柄,所以能准确的发送到要接收消息窗口的消息处理函数。

 

下面是跟踪消息运行列出的相关函数:

+CWinThread::PumpMessage()

+AfxInternalPumpMessage()

+GetMessage()

+AfxPreTranslateMessage()

+++++++++pThread->PreTranslateMessage()

+++++++++++++应用类重载的PreTranslateMessage()

+++++++++++++++++++CWinThread::PreTranslateMessage(),如果应用类重载了就会在此调用

++++++++++++++++++++++++AfxInternalPreTranslateMessage()

+++++++++++++++++++++++++++++CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg) 

+TranslateMessage()

+DispatchMessage()

 

CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg):

在函数内部,调用pMsg所指hwnd的PreTranslateMessage,这样就到了具体窗口的PreTranslateMessage函数。也就将消息派发到了具体的窗口中。

 

2, 来自系统或者其它进程发送的消息,大致处理过程同上。

 

3,程序内部的消息(命令消息,自定义的消息等),总之是发送的窗口是同一个UI线程创建的.

如果是sendmessage发送的消息,则不发送到消息队列,不通过消息循环 直接调用相应的消息处理函数。

下面是MSDN的解释:

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message. However, the sending thread will process incoming nonqueued messages while waiting for its message to be processed.

 

如果是postMessage则会将消息放入消息队列。

 

至于sendmessage 和postMessage的区别就不在这里描述了。

 

好了,至此已经知道消息是如何从消息队列到具体窗口传递的了,至于一个消息派送到了接收窗口后的传递路径以后在描述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值