w/atl的thunk技术

本文详细解析了MFC中对话框的实现机制,重点介绍了如何通过dlg.DoModal()调用StartDialogProc函数,并深入探讨了thunk内存分配及DialogProc成员函数的调用过程。
用dialog为例
CAboutDlg dlg;
dlg.DoModal();
其中class CAboutDlg : public CDialogImpl<CAboutDlg>{...}
当执行到dlg.DoModal();里面的
return ::DialogBoxParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(static_cast<T*>(this)->IDD),
                    hWndParent, T::StartDialogProc, dwInitParam);
时, 会调用StartDialogProc函数
该函数如下
 1template <class TBase>
 2INT_PTR CALLBACK CDialogImplBaseT< TBase >::StartDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 3ExpandedBlockStart.gifContractedBlock.gif{
 4    CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)_AtlWinModule.ExtractCreateWndData();
 5    ATLASSERT(pThis != NULL);
 6    if(!pThis)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 8        return 0;
 9    }

10    pThis->m_hWnd = hWnd;
11    // Initialize the thunk.  This was allocated in CDialogImpl::DoModal or
12    // CDialogImpl::Create, so failure is unexpected here.
13
14    pThis->m_thunk.Init((WNDPROC)pThis->GetDialogProc(), pThis);
15    DLGPROC pProc = (DLGPROC)pThis->m_thunk.GetWNDPROC();
16    DLGPROC pOldProc = (DLGPROC)::SetWindowLongPtr(hWnd, DWLP_DLGPROC, (LONG_PTR)pProc);
17#ifdef _DEBUG
18    // check if somebody has subclassed us already since we discard it
19    if(pOldProc != StartDialogProc)
20        ATLTRACE(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
21#else
22    pOldProc;    // avoid unused warning
23#endif
24    return pProc(hWnd, uMsg, wParam, lParam);
25}
第11行初始化thunk, 该thunk会alloc内存,然后向该内存写入 mov hWnd, pthis; jmp wndProc这里的wndProc为成员函数 template <class TBase>
INT_PTR CALLBACK CDialogImplBaseT< TBase >::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)hWnd;
...
看到该函数第一行直接将hWnd转换为类指针了吧, 其实这个hWnd是假的, 真正保存的的确是类指针, 该替换是在thunk里面做的
具体调用顺序为:
我们设置好wndProc (其实是这个thunk)
该窗口有消息来时,调用wndproc, 这里会对hWnd做一个替换,然后真正调用成员函数DialogProc
...over....
有时间仿照这个写一个简单的, 示范一下

转载于:https://www.cnblogs.com/cutepig/archive/2009/08/05/1539156.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值