参看: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());
-
-
- while (bIdle &&!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
- {
- ASSERT(ContinueModal());
-
- if (bShowIdle)
- {
- ShowWindow(SW_SHOWNORMAL);
- UpdateWindow();
- bShowIdle = FALSE;
- }
-
- if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
- {
-
- ::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
- }
- if ((dwFlags & MLF_NOKICKIDLE) ||!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
- {
-
- bIdle = FALSE;
- }
- }
-
-
- do
- {
- ASSERT(ContinueModal());
-
- if (!AfxPumpMessage())
- {
- AfxPostQuitMessage(0);
- return -1;
- }
-
- if (bShowIdle &&(pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
- {
- ShowWindow(SW_SHOWNORMAL);
- UpdateWindow();
- bShowIdle = FALSE;
- }
-
- if (!ContinueModal())
- goto ExitModal;
-
- 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;
- }
线程主消息循环:
-
-
- int CWinThread::Run()
- {
-
- BOOL bIdle = TRUE;
- LONG lIdleCount = 0;
-
-
- for (;;)
- {
-
- while (bIdle &&!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
- {
-
- if (!OnIdle(lIdleCount++))
- bIdle = FALSE;
- }
-
-
- do
- {
-
- if (!PumpMessage())
- return ExitInstance();
-
-
- if (IsIdleMessage(&m_msgCur))
- {
- bIdle = TRUE;
- lIdleCount = 0;
- }
-
- }
- while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
- }
- }
主消息循环与模态对话框中的局部消息循环之间的关系:
![](https://img-blog.csdn.net/20150504202023931?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hpYW95dXNoZW5nMjAxMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
当模态对话框显示时,进入模态对话框的消息循环,除非将模态对话框关闭,否则APP的DispatchMessage函数一直出不来。
http://blog.csdn.net/xiaoxiaoyusheng2012/article/details/45484669