WTL框架小结

来源:互联网 发布:linux系统网络邻居 编辑:程序博客网 时间:2024/06/05 15:40
  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<T*>(this)->IDD),                    hWndParent, T::StartDialogProc, dwInitParam);                    **CreateDialogParam**(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(static_cast<T*>(this)->IDD),                    hWndParent, T::StartDialogProc, dwInitParam);

接下来的过程和CWindow就一样了。

8.关于thunk技术,wtl和mfc差不多,参见:http://www.cnblogs.com/satng/archive/2010/12/30/2138833.html

0 0
原创粉丝点击