int Run()
{
if(msg!=NULL)
{
GetMessage();
**PreTranslateMessage()**;
TranslateMeesage();
DispatchMessage();
}
else
{
**OnIdle()**;
}
}
4.PreTranslateMessage()和OnIdle()分别遍历上面说的CMessageFilter和CIdleHandler对象,并调用CMessageFilter.PreTranslateMessage()和CIdleHandler方法:
CMessagLoop::PreTranslateMessage()
{
for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
{
CMessageFilter* pMessageFilter = m_aMsgFilter[i];
pMessageFilter->PreTranslateMessage(pMsg)
}
}
CMessagLoop::OnIdle(int /*nIdleCount*/)
{
for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
{
CIdleHandler* pIdleHandler = m_aIdleHandler[i];
pIdleHandler->OnIdle();
}
}
5.当有消息产生时,调用StartWindowProc(),该函数从Thunk成员中去除对应的类的this指针,并调用该类的ProcessWindowMessage方法,WTL的消息映射只是简单地封装了一堆switch- case语句,而这个switch-case就位于这个函数之中。这样当某个消息来的时候,如果未做预处理(PreTranslateMessage)就会调用相应的消息处理函数来处理了:
static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam)
{
CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)_AtlWinModule.ExtractCreateWndData();
pThis->m_hWnd = hWnd;
pThis->m_thunk.Init(WindowProc, pThis);
WNDPROC pProc = pThis->m_thunk.GetWNDPROC();
WNDPROC pOldProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
return pProc(hWnd, uMsg, wParam, lParam);
}
6.如果是菜单这样的东西,更新机制使用CUpdateUI,这是一个模板类,传子对象的类名,然后在头文件里面添加:
BEGIN_UPDATE_UI_MAP(CMainDlg)
END_UPDATE_UI_MAP()
7.WTL对话框继承自类CDialogImpl,该类提供了两个功能,一个是模式对话框调用DoModal()方法(本质上是windows API: DialogBoxParam);另一个是非模式对话框:Create后Show就可以了,本质上是windows API CreateDialogParam。无论是DoModal还是Create,都指定了StartDialogProc:
**DialogBoxParam**(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(static_cast(this)->IDD),
hWndParent, T::StartDialogProc, dwInitParam);
**CreateDialogParam**(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(static_cast(this)->IDD),
hWndParent, T::StartDialogProc, dwInitParam);
接下来的过程和CWindow就一样了。
8.关于thunk技术,wtl和mfc差不多,参见:http://www.cnblogs.com/satng/archive/2010/12/30/2138833.html