WTL框架小结

  1. 创建窗口时先注册类,通过thunk技术将窗口过程设置为StartWindowProc;
  2. 主应用程序类_Module至少有一个CMessageMap对象(可以增加、删除或者获得已经存在的引用),而CMessageLoop中存在两个数组,一个数组存放过滤消息结构:CMessageFilter,另外一个数组存CIdleHandler,用于空闲消息处理。CMessageFilter中只有一个PreTranslateMessage,而CIdleHandler中有个OnIdle()函数。所以,要使用这两个功能的窗口C++对象需要继承这两个类。
  3. 定义一个CMessageMap对象后,将其添加到_Module中,然后调用CMessageMap.Run()方法,Run()方法中进行取消息、预处理消息、发消息,如果没有消息就干Idle()该干的事情:
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

你可能感兴趣的:(Windows应用层编程)