zoukankan      html  css  js  c++  java
  • w/atl的thunk技术

    用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)
     3{
     4    CDialogImplBaseT< TBase >* pThis = (CDialogImplBaseT< TBase >*)_AtlWinModule.ExtractCreateWndData();
     5    ATLASSERT(pThis != NULL);
     6    if(!pThis)
     7    {
     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....
    有时间仿照这个写一个简单的, 示范一下
  • 相关阅读:
    setStyleSheet来设定窗口部件的样式
    Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
    Qt编程—去掉标题栏和设置窗口透明用法
    php设计模式总结
    典型的MVC架构图
    搜索引擎设计分析
    社区论坛设计分析
    (二) vim的Tabbar插件
    目录结构设计分析
    用户注册系统分析
  • 原文地址:https://www.cnblogs.com/cutepig/p/1539156.html
Copyright © 2011-2022 走看看