window程序一个线程中可以有几个消息队列?和几个消息循环
Posted demystify
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了window程序一个线程中可以有几个消息队列?和几个消息循环相关的知识,希望对你有一定的参考价值。
参看:http://wenku.baidu.com/link?url=Z9UcZPaN0lf9u4MwtkSvt4do3kCPuHISedW3CLyzXsr2uDvhZauc0ziwsYTOK_F2r_ffbnI6myevV7WxaD1WKzD8u1QYTOjh7H86rXdtkQy
在windows中一个线程只有一个消息队列(PostMessage消息队列),非模态对话框的消息在主线程的消息循环中处理,对于模态对话框,其先禁止主窗口,然后自己建立一个消息循环进行消息处理,对话框结束后,停止对话框自己的消息循环,然后enable主窗口。
所以,一个线程中只有一个消息队列(PostMessage消息队列),但是可能存在主线程消息循环外的其他局部消息循环,但是他们不会并行执行。
模态对话框与非模态对话框的内部机制区别:
非模态对话框与APP共用消息循环,不会独占用户 ;模态对话框独占用户输入,其他界面无法响应,有自己的消息循环;
模态对话框的具体实现有以下步骤:
1.让父窗口失效EnableWindow(parentWindow, FALSE);
2.建立模态对话框自己的消息循环(RunModalLoop);
3.直至接收关闭消息,消息循环终止,并销毁窗口。
具体代码:
INT_PTR CDialog::DoModal()
//对话框资源加载
......
//在创建模态窗口之前先让父窗口失效,不响应键盘、鼠标产生的消息
HWND hWndParent = PreModal();
AfxUnhookWindowCreate();
BOOL bEnableParent = FALSE;
if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))
::EnableWindow(hWndParent, FALSE);
bEnableParent = TRUE;
.......
//创建模态窗口,并进行消息循环,若窗口不关闭,则循环不退出
AfxHookWindowCreate(this);
VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
//窗口关闭,销毁窗口
DestroyWindow();
PostModal();
//释放资源,并让父窗口有效
pMainWnd->EnableWindow(TRUE);
//返回
return m_nModalResult;
模态对话框中的消息循环:
int CWnd::RunModalLoop(DWORD dwFlags)
//要检查窗口状态是否是模态窗口
//若状态一直为模态,则一直进行消息循环
for (;;)
ASSERT(ContinueModal());
// phase1: check to see if we can do idle work
while (bIdle &&!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
ASSERT(ContinueModal());
// show the dialog when the message queue goes idle
if (bShowIdle)
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
if ((dwFlags & MLF_NOKICKIDLE) ||!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
// stop idle processing next time
bIdle = FALSE;
//在有消息的情况下取消息处理
do
ASSERT(ContinueModal());
// pump message, but quit on WM_QUIT
if (!AfxPumpMessage())
AfxPostQuitMessage(0);
return -1;
// show the window when certain special messages rec'd
if (bShowIdle &&(pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
if (!ContinueModal())
goto ExitModal;
// reset "no idle" state after pumping "normal" message
if (AfxIsIdleMessage(pMsg))
bIdle = TRUE;
lIdleCount = 0;
while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
ExitModal:
m_nFlags &= ~(WF_MODALLOOP | WF_CONTINUEMODAL);
return m_nModalResult;
线程主消息循环:
//thrdcore.cpp
// main running routine until thread exits
int CWinThread::Run()
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
//消息读取乃至分发 当为WM_QUIT时,退出循环
for (;;)
//检查是否为空闲时刻
while (bIdle &&!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
//有消息,读消息并分发
do
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance();
// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
bIdle = TRUE;
lIdleCount = 0;
while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
主消息循环与模态对话框中的局部消息循环之间的关系:
当模态对话框显示时,进入模态对话框的消息循环,除非将模态对话框关闭,否则APP的DispatchMessage函数一直出不来。
以上是关于window程序一个线程中可以有几个消息队列?和几个消息循环的主要内容,如果未能解决你的问题,请参考以下文章