关于Windows窗口框架

咱们知道Windows的窗口消息处理函数是C方式, 面向过程的, 因此窗口框架的基本任务就是将它转成面向对象的方式, 确切的说如何将消息处理函数第一参数HWND转成对象指针。

 

关于这个问题, 其实网上你们已经说滥了,  这里只是简单记录一下。

 

Map方式:MFC就是采用这种方式, 就是创建一张从HWND到CWindow*的映射表, 每次收到消息都从Map中根据HWND找到CWindow*, 再进行调用
UserData的方式: CreateWindow 时将最后一个附加数据设置为对象CWindow* 指针, 当收到第一个消息WM_NCCREATE时, 取出传过来的附加数据指针, 将该指针设置成窗口的UserData, SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pThis)) , 后面收到任何消息就能够直接调用GetWindowLongPtr(hWnd, GWLP_USERDATA) 取出窗口指针, 进行面向对象方式的调用。
Thunk方式:这是ATL采用的方式,经过汇编代码,直接将窗口消息处理函数的第一个参数HWND改写成CWindow*, 而后进行面向对象方式的调用, 原理能够见我之前写的  理解ATL中的一些汇编代码

 

这里也有一篇文章总结了这些封装方式:  MFC、ATL窗口消息封装机制对比分析

 

最近工做中要写一些简单窗口相关的代码, 考虑用什么方式封装窗口过程:
MFC确定不引入, map方式也不考虑。
UserData方式过低效 ,并且窗口的UserData让框架用了,咱们其余地方可能还要用呢。
ATL的Thunk方式不错, 可是咱们不想引入COM, 也不想用ATL的库和代码。  
原始的 C API方式, 依赖性和效率都最佳, 惋惜就是否是面向对象的。

 

各有优缺,怎样才能熊掌和鱼翅兼得?

 

最后决定把ATL中窗口Thunk相关的核心代码剥离出来, 作一个彻底独立的最基本窗口框架。咱们框架的基本目标是可让咱们方便的开发一些简单的窗口, 因此去掉了ATL窗口中一些不经常使用或是可替代的东西, 只留下必须和最有用的。简单说来,把ATL中的CWindow给去掉了,它只是窗口API的封装, 咱们能够直接调用API来实现;把CWinTraits给去掉了,由于它只是窗口风格的封装; 把SubClass和SuperClass也去掉了, 咱们的简单窗口用不到这个特性; 把Dialog, Container和COM相关的都去掉了, 这些都不是窗口的核心部分。最后只留下,窗口注册建立, thunk和消息映射相关的代码。html

 

测试了下,这个窗口框架基本上只有2个核心文件,彻底独立, 能够直接放到任何现有框架中使用(ATL/WTL中使用可能要改下内部一些类名, 可是用了ATL/WTL确定就不用这个框架了)。

测试代码: CAltWinTest.rar
相关文章
相关标签/搜索