0、wtl只是對windows的訊息處理進行了模板封裝,我們可以再atlapp.h中找到CMessageLoop的代碼。
2、非模態對話方塊,想要你的對話方塊能收到訊息,你需要在PreTranslateMessage中調用IsDialogMessage,否則你將連ESC都響應不了。
3、想要處理PreTranslateMessage,你需要調用
// register object for message filtering and idle updates<br />CMessageLoop* pLoop = _Module.GetMessageLoop();<br />ATLASSERT(pLoop != NULL);<br />pLoop->AddMessageFilter(this);<br />
你用wtl的先導產生的程式碼會自動幫你添加
內部的實現很簡單,看看
BOOL AddMessageFilter(CMessageFilter* pMessageFilter)<br />{<br />return m_aMsgFilter.Add(pMessageFilter);<br />}<br />// Override to change message filtering<br />virtual BOOL PreTranslateMessage(MSG* pMsg)<br />{<br />// loop backwards<br />for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)<br />{<br />CMessageFilter* pMessageFilter = m_aMsgFilter[i];<br />if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg))<br />return TRUE;<br />}<br />return FALSE; // not translated<br />}
再看看訊息迴圈
// message loop<br />int Run()<br />{<br />BOOL bDoIdle = TRUE;<br />int nIdleCount = 0;<br />BOOL bRet;<br />for(;;)<br />{<br />while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))<br />{<br />if(!OnIdle(nIdleCount++))<br />bDoIdle = FALSE;<br />}<br />bRet = ::GetMessage(&m_msg, NULL, 0, 0);<br />if(bRet == -1)<br />{<br />ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)/n"));<br />continue; // error, don't process<br />}<br />else if(!bRet)<br />{<br />ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting/n"));<br />break; // WM_QUIT, exit message loop<br />}<br />if(!PreTranslateMessage(&m_msg))<br />{<br />::TranslateMessage(&m_msg);<br />::DispatchMessage(&m_msg);<br />}<br />if(IsIdleMessage(&m_msg))<br />{<br />bDoIdle = TRUE;<br />nIdleCount = 0;<br />}<br />}<br />return (int)m_msg.wParam;<br />}<br />
Not the end,wait for more……