消息处理流程:
创建完窗口后,对窗口的处理,窗口的响应,就是窗口的消息循环
void CPaintManagerUI::MessageLoop() {
MSG msg = { 0 };
int ret = 0;
while (ret = ::GetMessage(&msg, NULL, 0, 0)) {
if (msg.message == WM_QUIT) {
break;
} else if (msg.message == UIMSG_UPDATE_ON_MAIN) {
UIMainQueue::getInstance().finish();
}
if (!CPaintManagerUI::TranslateMessage(&msg)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
MessageLoop 是对整个进程进行消息处理
TranslateMessage 函数
函数功能描述:将虚拟键消息转换为字符消息。字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。
CPaintManagerUI::TranslateMessage(&msg) duilib自己的一些预处理消息,我们可以继承些接口比如:
1、
class ITranslateAccelerator
{
public:
virtual LRESULT TranslateAccelerator(MSG *pMsg) = 0;
};
TranslateAccelerator 来预处理些想处理的消息
2、
class IMessageFilterUI
{
public:
virtual LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled) = 0;
};
MessageHandler 中处理想处理的消息
3、
if(pMsg->hwnd == pT->GetPaintWindow() || hTempParent == pT->GetPaintWindow())
{
if (pT->TranslateAccelerator(pMsg))
return true;
pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes);
}
如果是子窗口,会发送给父窗口消息处理,父窗口可以通过两个接口进行处理:
(1) MessageHandler
(2) TranslateAccelerator
消息循环流程:
MessageLoop后,
1、
bool CPaintManagerUI::TranslateAccelerator(LPMSG pMsg)
2、
bool CPaintManagerUI::PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& /*lRes*/)
LRESULT lResult = item1->MessageHandler(uMsg, wParam, lParam, bHandled);
然后
::TranslateMessage(&msg);
子类继承HandleMessage进行处理
LRESULT CWindowWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
PostMessage:
只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数。而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息投放函数。
如果在同一个线程内,PostMessage发送消息时,消息要先放入线程的消息队列,然后通过消息循环Dispatch到目标窗口。SendMessage发送消息时,系统直接调用目标窗口的消息处理程序,并将结果返回,SendMessage在同一线程中发送消息并不入线程消息队列。
windows消息处理机制是这样:
首先系统(也就是windows)把来自硬件(鼠标,键盘等消息)和来自应用程序的消息 放到一个系统消息队列中去, 而应用程序须要有自己的消息队列,也就是线程消息队列,每个线程有自己的消息队列,对于多线程的应用程序就有和线程数目相等的线程消息队列。
windows消息队列把得到的消息发送到线程消息队列,线程消息队列每次取出一条消息发送到指定窗体,不断循环直到程序退出.这个循环就是靠消息环(while(GetMessage()) TranslateMessage();DispatchMessage();实现的.GetMessage()仅仅是从线程消息中取出一条消息。