惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
T
Threat Research - Cisco Blogs
量子位
Last Week in AI
Last Week in AI
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
F
Fortinet All Blogs
爱范儿
爱范儿
D
Docker
人人都是产品经理
人人都是产品经理
S
SegmentFault 最新的问题
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
A
About on SuperTechFans
P
Proofpoint News Feed
博客园 - 司徒正美
Recent Announcements
Recent Announcements
I
InfoQ
Hugging Face - Blog
Hugging Face - Blog
Microsoft Security Blog
Microsoft Security Blog
有赞技术团队
有赞技术团队
Webroot Blog
Webroot Blog
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
SecWiki News
SecWiki News
Attack and Defense Labs
Attack and Defense Labs
Hacker News: Ask HN
Hacker News: Ask HN
AI
AI
博客园_首页
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Recorded Future
Recorded Future
T
Tailwind CSS Blog
MyScale Blog
MyScale Blog
T
Tenable Blog
宝玉的分享
宝玉的分享
Google Online Security Blog
Google Online Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Secure Thoughts
C
Check Point Blog
S
Security Affairs
L
LINUX DO - 最新话题
大猫的无限游戏
大猫的无限游戏
Scott Helme
Scott Helme
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
月光博客
月光博客
Y
Y Combinator Blog

博客园 - vibration

ATL3.0组件注册bug的解决方法 奇怪的引用错误及解决方法 OLE2T在VS2003中转换中文失败的问题及解决方法 标题栏按钮的WTL实现 AppBar的WTL实现 招聘C++和C#开发工程师 ATL组件中文路径注册问题(转载) 关于C++模板的连接问题 - vibration - 博客园 用窗口消息解决COM接口的多线程访问问题 用全局接口表实现COM接口在不同线程中的传递 MyMSN支持自定义内容了 自画菜单的WM_MEASUREITEM只会发送一次 悼念皮皮 上了点照片 一个测试记忆力的小游戏 老板该如何向核心员工许诺 ActiveScript SkinX界面换肤框架更新 反射获取定制Attribute
Skin技术实现框架(完)
vibration · 2004-05-24 · via 博客园 - vibration

有过去一个周末了,昨天去看跳水比赛,现场的气氛还是不错的。可惜田亮没有来,否则,光看看观众席的fans也是一种享受啊
废话结束,进入正题,今天讲点以前没说清楚的内容。上次提到了消息反射,但没有深入,这个概念是这样的,许多窗口控件会向父窗口发送一些消息,比如WM_COMMAND消息和WM_NOTIFY消息,通知父窗口一些事件。因为是发给父窗口的,所以控件窗口的过程函数不能捕捉到这些消息。但是,经常我们希望在控件窗口对象中处理这些消息,这样使控件类更加独立。为了实现这个目的,MFC和ATL都提供了消息反射的机制,就是让父窗口在收到这类消息的时候,把它们再发还给控件窗口,这就是消息反射。我们要实现Skin插件,也需要在控件窗口类中收到这些消息,但是,我们不能依赖ATL或者MFC的反射,因为我们希望Skin插件可以被不同的宿主程序使用,而不是局限于ATL和MFC。其他程序可能没有消息反射机制,或者使用了不同的消息反射机制。所以,我们实现了自己的消息反射机制。
CReflectHook类就是用来完成消息反射的,其构造函数接受父窗口的句柄作为参数,然后调用SubclassWindow把对象实例链接到窗口上去,这和控件的实现类似。ProcessWindowMessage是个虚函数,它的定义可以追述到ATL窗口类的最底层,CReflectHook::ProcessWindowMessage实现反射功能,把收到的需要反射的消息发送回控件窗口。但也不是简单的原样返回,而是包装成另一个WM_REFLECT消息,以免和其他消息冲突。当反射消息发会给控件窗口时,控件窗口利用下面三个宏解开WM_REFLECT,并得到原来的消息:
LF_REFLECTED_NOTIFY_CODE_HANDLER
LF_REFLECTED_COMMAND_CODE_HANDLER
LF_REFLECTED_MESSAGE_HANDLER
这几个宏的含义不多说了,熟悉WTL的同学很容易找到答案。另外值得一提的时WM_GETREFLECTOR消息,这个自定义消息可以用来向父窗口查询于其相关联的CReflectHook实例,以避免重复安装反射钩子,因为CReflectHook::ProcessWindowMessage为这个消息返回了this指针。CWidgetHook::Install使用了WM_GETREFLECTOR消息。

值得讲的就这么多了吧,最后说一下怎么写CWidgetHook继承类吧(即控件类),这也是直接影响最终效果的。WTL定义了许多通用控件包装类,把这些类作为CWidgetHook的第二个模板参数可以是后续工作大大简化,当然,如果没有对应的包装类,也可以接收默认参数。
因为借助了ATL/WTL的基础架构,控件类的编写和写一个ATL窗口类非常相似,可以使用ATL/WTL消息映射宏,当然,这些宏需要手工输入,而不象MFC一样提供了Wizard。另外,控件类还可以选择的重载CWidgetHook定义的4个初始化和清理函数,参考Skin技术实现框架(五)。附带的例子中提供了一个Mac按钮类的实现,可以参考,这个按钮例子算是比较复杂的,因为Windows窗口类名为“Button”的窗口实际上包括普通按钮、单选钮和复选框,其他的许多控件实现起来比button容易,当然也有一些比较麻烦的。

关于这个skin框架,基本上应该都讲清楚了,不过肯定比较乱,也许以后有时间整理吧。这里使用了很多WTL的东西,可能熟悉的人并不多,而且最终没有得到微软官方支持,所以要说有多少价值,也说不上,只是喜欢的朋友可以玩一下。我现在也不怎么关注C++的东西了,没办法,新技术发展太快,不得不跟上啊。随便写一点以前的积累,和同学们共勉。