zoukankan      html  css  js  c++  java
  • 一步一步实现自己的模拟控件(3)——Widget驱动

    前面我们利用现有的微软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内核的运作系统的实现,从测试工程中感受得到一定的体验了。

    下载测试工程源码

    By Evil.Ghost
  • 相关阅读:
    16.什么是面向对象编程?
    15.运动
    14.this指向和ES6常用内容
    13.正则表达式
    12.事件模型
    11.event事件对象
    10.BOM
    9.DOM
    拓扑排序学习(复习)笔记
    [Luogu] P1987 摇钱树
  • 原文地址:https://www.cnblogs.com/EvilGhost/p/Abstract_Widget_3.html
Copyright © 2011-2022 走看看