ATL中的Thunk机制学习

ATL和MFC的C++类和HWND的映射机制 最近看深入解析ATL这本书的时候看到ATL中的窗口类实现的时候,很是惊异于ATL的Thunk的运用技术,,ATL运用Thunk技术把C++的成员函数置换成Windows窗口的消息处理函数。那么更古老的MFC框架又是怎么实现CWnd类到HWND窗口类之间的映射的呢? 下面的文章将ATL和MFC的窗口封装机制做个对比. 如果让我完成C++类到HWND窗口的映射,我会写如下的代码BOOL  阅读详情

ATL利用一系列的类来管理窗口。为了使代码尽量紧凑而高效,ATL使用了一种有趣的技术来实现与窗口消息相关联的HWND和负责处理消息的对象的this指针之间的映射。具体过程如下:

 

在窗口注册时声明的窗口过程为此窗口对应的窗口类的静态成员函数StartWindowProc,当第一条消息到达此函数时,其处理如下:

 

template <class TBase, class TWinTraits>

LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

         CWindowImplBaseT< TBase, TWinTraits >* pThis =

(CWindowImplBaseT< TBase, TWinTraits >*)_Module.ExtractCreateWndData();

         ATLASSERT(pThis != NULL);

         pThis->m_hWnd = hWnd;

         pThis->m_thunk.Init(pThis->GetWindowProc(), pThis);

         WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);

         WNDPROC pOldProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)pProc);

#ifdef _DEBUG

         // check if somebody has subclassed us already since we discard it

         if(pOldProc != StartWindowProc)

                   ATLTRACE2(atlTraceWindowing, 0, _T("Subclassing through a hook discarded./n"));

#else

         pOldProc;  // avoid unused warning

#endif

         return pProc(hWnd, uMsg, wParam, lParam);

}

 

它先由全局变量_Module中取得此窗口对应的窗口类的this指针,然后通过m_thunk运用汇编指令改造此窗口类的窗口过程成员函数。m_thunk是CWndProcThunk的实例,每个窗口类各有一个。它的定义如下:

 

class CWndProcThunk

{

public:

         union

         {

                   _AtlCreateWndData cd;

                   _WndProcThunk thunk;

         };

         void Init(WNDPROC proc, void* pThis)

         {

#if defined (_M_IX86)

                   thunk.m_mov = 0x042444C7;  //C7 44 24 0C

                   thunk.m_this = (DWORD)pThis;

                   thunk.m_jmp = 0xe9;

                   thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));

#elif defined (_M_ALPHA)

                   thunk.ldah_at = (0x279f0000 | HIWORD(proc)) + (LOWORD(proc)>>15);

                   thunk.ldah_a0 = (0x261f0000 | HIWORD(pThis)) + (LOWORD(pThis)>>15);

                   thunk.lda_at = 0x239c0000 | LOWORD(proc);

                   thunk.lda_a0 = 0x22100000 | LOWORD(pThis);

                   thunk.jmp = 0x6bfc0000;

#endif

                   // write block from data cache and

                   //  flush from instruction cache

                   FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk));

         }

};

 

其Init()函数完成对WndProcThunk结构的初始化工作。WndProcThunk结构针对X86体系的定义如下:

 

struct _WndProcThunk

{

         DWORD   m_mov;          // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)

         DWORD   m_this;         //

         BYTE    m_jmp;          // jmp WndProc

         DWORD   m_relproc;      // relative jmp

};

 

结构成员中保存的是一组汇编指令。在X86体系下,在Init()函数中这组汇编指令被初始化为下面的指令:

 

mov dword ptr [esp+0x4], pThis

jmp (int)proc - ((int)this+sizeof(_WndProcThunk))

 

它完成的功能是,用窗口类的指针pThis代替窗口句柄hWnd(esp+0x4中放的就是hWnd),然后跳转到传入的proc函数处((int)proc - ((int)this+sizeof(_WndProcThunk))是proc与thunk之间的距离)。

 

在调用完m_thunk.Init()函数之后,实际上就得到了经过改造的窗口过程(m_thunk.thunk),此窗口过程是窗口类的一个成员函数,它的第一个参数定义虽然是HWND,但实际上是它的类的this指针。最后使用SetWindowLong()用这个新的窗口过程替换掉原有的窗口过程(也就是StartWindowProc),以后的所有消息都会被路由给新的窗口过程。

ATL中的Thunk机制学习 ATL中的Thunk机制学习 http://blog.youkuaiyun.com/sam1111/article/details/9790 阅读详情

相关推荐

玄机-Linux权限维持-后门

玄机-Linux权限维持-后门

m0_46439803的博客 764

ATL中的Thunk机制学习 (转)

ATL中的Thunk机制学习 (转)[@more@]ATL利用一系列的类来管理窗口。为了使代码尽量紧凑而高效,ATL使用了一种有趣的技术来实现与窗口消息相关联的HWND和负责处理消息的对象的this指针之间的映射。具体过程如下:...

csd3176的博客 153

抖音短视频数据抓取实战系列(一)——模拟器性能对比与优化配置

本文是抖音短视频数据抓取实战系列的开篇,重点探讨了模拟器选型与优化配置。通过对比雷电、夜神、逍遥三大主流模拟器在性能、抖音兼容性及抓包友好度上的表现,文章指出雷电模拟器因其稳定的桥接网络模式和良好的兼容性,是数据抓取的优选。并提供了雷电模拟器从安装、网络桥接到系统优化的详细配置指南,旨在帮助读者构建稳定高效的抓取环境。

weixin_29230901的博客 246

ATL Thunk技术简单解析

Thunk的基本原理是分配一段内存,然后将窗口过程设置为这段内存。这段内存的作用是将窗口过程的第一个参数(窗口句柄)替换成类的This指针,并jump到类的WinProc函数中。这样就完成了窗口过程到类的成员函数的一个转换。 ATL采用一种称为thunk的机制,简单来说,公共的窗口过程依然是类的一个静态函数,但只负责窗口的第一个消息WM_NCCREATE,其目的是在堆上开辟一小块数据区,

jdzfjfhnui的专栏 1379

【Autosar】学习总结-MCAL

一、简介 MCAL:微控制器抽象层;位于BSW层中的最下层; MCAL细分,可将驱动分为:微控制器驱动、存储器驱动、通信驱动、IO驱动: 二、MCAL的配置(EB-Tresos) 1.PORT 我理解的PORT:MCAL层中的IO驱动组中的pin脚总体配置: Port就是芯片上的每个pin脚,可以配置成DIO ADC PWM ICU等单引脚的功能,也能配置成CAN的TX或者RX、SPI的MOSI等等其他功能的单个pin脚功能; 总之,PORT就是芯片上的具体的某个引脚。 配置

zDavid_2018的博客 3万+

TMS320C6678开发笔记1-6---C6678单核烧写程序

第6节 单核烧写加载程序 6.1节 TI参考文档 参考文档:《KeystoneI Bootloader Resources and FAQ》讲的非常好,建议一定要看 https://processors.wiki.ti.com/index.php/KeystoneI_Bootloader_Resources_and_FAQ#Direct_Boot_Examples_.28without_IBL.29 里面有三个工程: C6678 EVM SPI boot example C6657 EVM ..

kunkliu的博客 5693

ATL之thunk技术

<br /><br /><br />学习下 ATL 的 thunk<br />由于 C++ 成员函数的调用机制问题,对C语言回调函数的 C++ 封装是件比较棘手的事。为了保持C++对象的独立性,理想情况是将回调函数设置到成员函数,而一般的回调函数格式通常是普通的C函数,尤其是 Windows API 中的。好在有些回调函数中留出了一个额外参数,这样便可以由这个通道将 this 指针传入。比如线程函数的定义为:<br />typedef DWORD (WINAPI *PTHREAD_START_ROUTINE

xsh_123321的专栏 4790

Mplus实战:如何用潜在类别分析(LCA)快速搞定心理学数据分类?

本文详细介绍了如何运用Mplus软件进行潜在类别分析(LCA),以快速处理心理学数据并识别内部异质性群体。文章从数据准备、Mplus语法编写、模型拟合与选择,到结果解读与高级应用(如纳入协变量),提供了完整的实战指南,帮助研究者从变量视角转向个体视角,有效挖掘数据中的潜在子类别。

weixin_28318011的博客 410

ATL Thunk机制学习

      ATL模板类库使用Thunk技术来实现与窗口消息相关联的HWND和负责处理消息的对象的this指针之间的映射。    ATL中窗口类注册时,窗口过程函数缺省值都是StartWindowProc,当创建窗口产生第一条消息时将调用此函数。StartWindowProc是CWindowImplBase的一个静态成员函数,它的工作是建立CWindowImpl派生对象的HWND与对象

热爱工作,快乐生活 4743

图像配准(Image Registration)——深度学习方法

参考:https://www.cnblogs.com/carsonzhu/p/11188574.html

m0_46483236的博客 4万+

CarSim - 仿真汽车驾驶行为的完整源代码及描述

以上是多年收集的稀有软件CarSim的源代码和描述,借助CarSim提供的功能,用户可以准确地模拟和研究汽车的驾驶行为,为汽车设计、驾驶辅助系统等领域提供有价值的支持。是一款用于模拟汽车驾驶行为的稀有软件,它经过多年的收集和开发,提供了一套完整的源代码和相应的描述,能够准确地模拟真实世界中的汽车运动和操控。CarSim的源代码采用现代化的。

weixin_50547796的博客 293

w/atl的thunk技术

用dialog为例CAboutDlg dlg;dlg.DoModal();其中class CAboutDlg : public CDialogImpl&lt;CAboutDlg&gt;{...}当执行到dlg.DoModal();里面的return ::DialogBoxParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(stat...

weixin_34064653的博客 151

Python爬虫实战:Boss直聘职位数据采集实战 - Playwright + 结构化解析完整方案(附CSV导出 + SQLite持久化存储)!

我长期专注 Python 爬虫工程化实战,主理专栏 《Python爬虫实战》:从采集策略到反爬对抗,从数据清洗到分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上。

喵手的博客 2186

(转载)ATL_NO_VTABLE详解

<br />我们可以注意到在用ATL编写COM组件时,在类前面都有一个宏ATL_NO_VTABLE,那么这个宏到底有什     <br />   么作用呢?这个宏的定义如下:     <br />   #define    __declspec(novtable)    ATL_NO_VTABLE;     <br />    <br />   下面这段是MSDN中对这个宏的描述:     <br />   This    form    of    _declspec    can    be    ap

kanguolaikanguolaik的专栏 1365

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

ATL Thunk机制深入分析

如果你有SDK的编程经验,就一定应该知道在创建窗口时需要指定窗口类,窗口类中的一种重要的参数就是窗口过程。任何窗口接收到的消息,都是由该窗口过程来处理。 在面向对象编程中,如果还需要开发人员来使用原始的窗口过程这种面向过程的开发方式,面向对象就显得不那么纯粹了。所以,在界面编程的框架中,框架往往会隐藏窗口过程,开发人员看到的都是一个个的类。 如果要处理某一个消息,则需要在窗口对应的类...

dhpvukzt509573的博客 357

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ATL thunk机制

起初在DECLARE_WND_CLASS宏中可以知道,窗口类的窗口过程是CWindowImplBaseT的静态成员函数StartWindowProc,在StartWindowProc第一次被调用的时候,它把CWindowImplBaseT的非静态成员函数通过thunk机制设置为窗口过程。 template LRESULT CALLBACK CWindowImplBaseT::Start

w的专栏 1906

atl thunk源码

atlstdthunk.h // This is a part of the Active Template Library. // Copyright (C) Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // A...

晓晓梦 334

[wtl学习]-[第三天]-THUNK技术学习

还是前言:本文只是本人学习过程的思考和记录。有错误的地方诚请指教。        今天继续看ATL Internals: Working with ATL 8, Second Edition By Christopher Tavares, Kirk Fertitta, Brent Rector, Chris Sells这本书第十章,学习了CWindowImpl的一些设计思想,边看书边翻看源码

HainuCrazy的专栏 1311

ATL thunk机制

2009-05-06 23:04 344人阅读 评论(0) 收藏 举报 起初在DECLARE_WND_CLASS宏中可以知道,窗口类的窗口过程是CWindowImplBaseT的静态成员函数StartWindowProc, 在StartWindowProc第一次被调用的时候,它把CWindowImplBaseT的非静态成员函数通过thunk机制设置为窗口过程。   tem

wxl1986622的专栏 873

MFC、ATL窗口消息封装机制对比分析

http://www.brucesky.com/articles/242 新产品在不紧不慢的进行中,这应该是有史以来开发比较“自由”的一个项目。在折腾完一个功能服务器的demo之后,开始折腾起PC客户端。Leader说客户端界面需用ATL来实现。这时候可以满足一下客户端界面开发的兴趣,于是开始学习ATL界面开发,有人说做界面是个累人加无趣的体力活,但对于做界面的新手来说自得其乐,君子懂得

珍爱生命 远离C++ 2545

ATL与MFC消息分发机制的对比

上面说完了ATL的消息分发方式,下面继续MFC的实现机制。二、MFC消息分发的实现方式:     首先来看注册窗口时:     还是以对话框为例子,调用DoModal 后,进入:view plaincopy to clipboardprint?INT_PTR CDialog::DoModal()       {           //···进行资源的准备           // disable parent (before creating dialog)           HWND hWndPare

fjclc2008的专栏 1894

理解ATL中的一些汇编代码

我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以拿来学习应该是很方便的。但是因为ATL的代码充满了模板和宏,内部还夹杂着汇编,所以如果没有比较丰富的C++模板和系统底层的知识,一般人会看得一头雾水。 下面我们主要分析一下ATL中的一些汇编代码

Chinamming的专栏 1510
上一篇: C++模板代码的组织方式 ——包含模式(Inclusion Model)
下一篇: 在.NET中读写INI文件 ——兼谈正则表达式的应用
sam1111
博客等级 码龄26年 18粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值