zoukankan      html  css  js  c++  java
  • 关于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和消息映射相关的代码。

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

    测试代码: CAltWinTest.rar
  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/weiym/p/3308347.html
Copyright © 2011-2022 走看看