我们知道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和消息映射相关的代码。

测试了下,这个窗口框架基本上只有2个核心文件,完全独立, 可以直接放到任何现有框架中使用(ATL/WTL中使用可能要改下内部一些类名, 但是用了ATL/WTL肯定就不用这个框架了)。
测试代码: CAltWinTest.rar

关于Windows窗口框架的更多相关文章

  1. 在WPF控件上添加Windows窗口式调整大小行为

    起因 项目上需要对Canvas中的控件添加调整大小功能,即能在控件的四个角和四条边上可进行相应的拖动,类似Windows窗口那种.于是在参考以前同事写的代码基础上,完成了该功能. 代码实现 Adorn ...

  2. Windows窗口消息大全(转)

    Windows窗口消息大全,全不全自己看 ////////////////////////////////////////////////////////////////////////// #inc ...

  3. Windows Forms框架编程

    <Windows Forms框架编程>节选   第九章 设计模式与原则 软件设计模式(Design pattern)是一套被反复使用的代码设计经验总结.使用设计模式是为了可重用代码.让代码 ...

  4. Windows服务框架与服务的编写

    从NT内核开始,服务程序已经变为一种非常重要的系统进程,一般的驻守进程和普通的程序必须在桌面登录的情况下才能运行,而许多系统的基础程序必须在用户登录桌面之前就要运行起来,而利用服务,可以很方便的实现这 ...

  5. python-web自动化-元素操作:windows窗口切换 / alert切换 / iframe切换

    1. windows窗口切换:切换到要操作的窗口 有多个窗口: 1. 触发新窗口的出现 2. 得知道新窗口是谁 -- 依据窗口的window_handle来识别窗口 3. 得到窗口的window_ha ...

  6. Windows窗口消息大全

    ////////////////////////////////////////////////////////////////////////// #include "AFXPRIV.H& ...

  7. Windows窗口程序从创建到关闭产生的消息

    Windows是消息驱动的,理解消息机制及消息循环是特别重要.知道在什么情况下产生什么消息会让我们对程序有更好的控制.Windows给应用程序发消息,有些会加入应用程序的消息队列,也是就是队列消息.有 ...

  8. 我的第一个 Windows 窗口程序(1)

    一般来说,构建一个 Windows 程序可以分为如下几个步骤: 定义窗口类(WNDCLASS) 注册窗口类(RegisterClass) 创建窗口(CreateWindow) 更新显示窗口(Updat ...

  9. 【转】Windows 窗口层次关系

    原文链接:undefined! 相信在Windows 下面编程的很多兄弟们都不是很清楚Windows 中窗口的层次关系是怎么样的,这个东西很久已经研究过一下,后来又忘记了,今天又一次遇到了这个问题,所 ...

随机推荐

  1. 如何辨别具体的一种SaaS是否安全?

    如何辨别具体的一种SaaS是否安全,需要把握以下几点: 1.传输协议加密 首先,要看SaaS产品提供使用的协议,是https://还是一般的http://,别小看这个s,这表明所有的数据在传输过程中都 ...

  2. Surfer 软件做等值线图

    使用surfer软件做等值线图 Surfer软件美国Golden Software公司编制的一款以画三维图(等高线,image map,3d surface)的软件. Surfer具有的强大插值功能和 ...

  3. 【Mail】搭建邮件服务器(LAMP+Postfix+Dovcot+PostfixAdmin+Roundcubemail)

    大纲 一.mail部署说明 二.安装准备 三.LMAP环境配置 四.配置postfixadmin 五.配置postfix 六.配置dovecot 七.测试SMTP和POP3服务 八.配置Roundcu ...

  4. html5 完整图片上传

    <div class="photo" style="display:none;" id="upPhoto"><div cl ...

  5. AngularJS之ng-options的best practise

    废话不多说,直接上代码. function MySelectCtrl($scope) { $scope.Model = [ { id: 10002, MainCategory: '男', Produc ...

  6. iis下设置php最大执行时间

    php在执行中常见错误: The FastCGI process exceeded configured request timeout: FastCGI process exceeded confi ...

  7. 用SYS_CONNECT_BY_PATH进行层级查询时的排序问题

    用SYS_CONNECT_BY_PATH进行层级查询时, 对同一级别的节点进行排序,可以加order SIBLINGS by 子句实现 WITH N2 AS( SELECT n.ID, org.&qu ...

  8. JavaScript-事件周期-点击替换颜色

    事件周期 DOM:3个阶段 1.捕获:从最外层元素,向内层元素,逐个记录绑定的事件处理函数.默认,暂不触发任何事件 2.目标触发:优先触发目标元素绑定的事件处理函数 目标元素:实际点击的元素 3.冒泡 ...

  9. jboss 7 启动问题

    19:30:50,176 INFO [org.jboss.modules] JBoss Modules version 1.1.1.GA19:30:50,458 INFO [org.jboss.msc ...

  10. 了解及使用IPV6

    1. 什么是 IPv6 IPv6指互联网协议(IP)第6版.目前大家上网主要使用互联网协议第四版,即IPv4. 在全球互联网高度发展的今天,IPv4 地址资源已经枯竭,互联网正在经历从IPv4网络向I ...