前面我们利用现有的微软ATL实现的thunk已经为我们截获窗口消息做好了准备,此刻我们应该编写我们的Widget驱动的初步实现了。
利用thunk对窗口消息过程进行子类化,那么窗口消息就会先流入到我们的Widget驱动对象,Widget驱动对象负责将消息传递给消息过滤器。现在我们的消息过滤器还未实现,于是我们打印了进入消息过滤器的消息ID值以观察消息的流动情况。
以下是我们的Widget驱动类,我们将其放入了一个名为widget的名字空间中,以后我们widget相关的名字都会放入到这个名字空间中。
class DriverImpl;
class Driver{
DriverImpl* pImpl_;
public:
explicit Driver(HWND hWnd);
~Driver();
private:
Driver(const Driver&);
Driver& operator =(const Driver&);
public:
inline HWND GetContainerWindow() const;
};
因为Driver的实现我们并不关心,所以我们将其实现进行了一个隐藏,这样也便于我们修改其实现方式。Driver类对象要求用于构造它的窗口句柄必须为有效的窗口句柄,并且每个窗口句柄只能被驱动一次,所以我们在调试版本中做了断言来约束我们的编码,在发布版本中不会做任何判断。
#ifdef _DEBUG
assert(::IsWindow(hContainerWnd_));
// 不能多次驱动同一窗口
assert(GetContainerWindows_().insert(hContainerWnd_).second);
#endif // _DEBUG
此处有一个
GetContainerWindows_()是一个只在调试版本中才有的实现,其返回一个std::set<HWND>&静态对象引用,用于保存已经被驱动的窗口句柄,我们断言窗口句柄未曾保存到这个set之中。
现在我们实现的Driver接口非常简单,只有一个构造接口和查询其驱动的窗口句柄的接口,显然没有任何可以控制驱动或者解除驱动的机会,此处我们先放一放,因为这在以后会涉及到这个驱动所关联的Widget体系的一些问题。
通过thunk截获的窗口消息将会进入到Driver实现中,Driver的功能仅仅是作为Widget的驱动(也就是消息驱动),它不负责任何消息的处理,所以这个窗口过程在截获到窗口消息后立即交由消息过滤处理。
LRESULT WndProc_(UINT message, WPARAM wParam, LPARAM lParam)
{
// 进行消息过滤
MessageFilter::Param param;
param.hWnd = hContainerWnd_;
param.originalProc = originalProc_;
param.message = message;
param.wParam = wParam;
param.lParam = lParam;
return MessageFilter::Filter(param);
}
这里消息过滤器的实现不在这一段讨论之中,所以我们简单的以一个类静态接口来作为过滤入口。
好了,我们到这里已经开启了Widget内核的运作系统的实现,从测试工程中感受得到一定的体验了。
下载测试工程源码
作者: Evil.Ghost 发表于 2011-04-03 13:56 原文链接
评论: 0 查看评论 发表评论
最新新闻:
· 苹果iPad 2通过3C认证 最晚5月国内上市(2011-04-10 09:18)
· 盲目依赖iPhone等工具导航 英国驴友迷路多(2011-04-10 09:14)
· 趣谈:想担任CEO的话,最好是去苹果工作,其次是微软,再才是Google(2011-04-10 08:26)
· 腾讯将建立新数据中心,规模为苹果的两倍(2011-04-10 08:25)
· 轻量化的微型博客Tumblr(2011-04-10 08:03)
编辑推荐:非战之罪,从永中Office谈起
网站导航:博客园首页 我的园子 新闻 闪存 小组 博问 知识库