一步一步实现自己的模拟控件(8)——重构

模拟控件已经出了雏形,是应该重构一下了。

新概念:

其实说是新概念也不尽然,只是在这几步的实现中可以发现,这个模拟控件框架中有两个大的概念:容器和控件。我们一直一来都说的是容器窗口,但是其实这是个可以上升的概念。容器容纳一个控件体系,也就是关联一个根控件,那么它就有点类似于我们的根控件了。但是容器由必须实现和具体窗口和控件的交互,所以我们不能简单的将根控件作为容器。并且对于某些特殊的实现,我们还可能需要对容器的某些功能加以扩展,所以我们这次重构为容器抽象了一个基类,并实现了一个窗口容器。

class Container : public Monopolistic{
using Monopolistic::pWidget_;
using Monopolistic::GetWidget;

public:
Container();
virtual ~Container();

public:
Widget
* GetRootWidget() const{return GetWidget();}

public:
virtual bool IsValid() const = 0;

public:
virtual void Invalidate(const RECT& rect){} // 无效化容器矩形区域
virtual void Invalidate(HRGN hRgn){} // 无效化容器不规则区域
virtual void Invalidate(){} // 无效化整个容器区域
};

解耦:

到目前为止,我们的容器驱动和控件之间具有十分紧密的耦合关系(生命周期耦合),这次重构打算将此解耦,使得我们的容器创建和控件体系创建互不相关,仅仅通过一次操作来使得他们关联或者解除关联。

// 建立窗口容器
ghost::widget::WindowContainer container;
container.AttachWindow(hWnd);

// 建立根控件
auto pRootWidget = ghost::Widget::Create();

// 关联容器
pRootWidget->CreateRelationship(&container);

减少类:

这次还有一个大的变化就是将原先的一些概念融合成了新的概念:驱动、消息过滤、消息映射都融合到了容器当中,因为这三个概念和具体容器关系紧密,所以将他们进行融合以减少我们的类数目。

收获:

这次重构建立了容器这个概念我们是有一定收获的:原先我们无法访问控件所关联的容器,现在可以了。原先控件的容器实现不易扩展,现在可以通过继承来扩展(例如layered窗口),甚至可以为容器实现特有的绘制机制(例如使用opengl,以后我们抽象了绘制概念便可以看到,目前还只能使用GDI)。

这次没有什么新的内容添加,但重构还是有必要的,周期性重构利于我们对整个框架的管理,在重构过程中较容易发现和修改BUG。

下载测试工程源码

posted @ 2011-04-19 20:06  Evil.Ghost  阅读(1915)  评论(4编辑  收藏  举报