一步一步实现自己的模拟控件(4)——根控件

 

窗口、控件驱动、根控件之间的关系

前面我们已经说了,一个窗口只能关联一个控件驱动,一个控件驱动也同样对应一个根控件。为什么呢?因为我们的驱动需要作用于一个控件体系,一个控件体系具有一个根控件,这个根控件管理了整个窗口的客户区。这样我们才能在这个根控件下创建任意的控件,并活动在窗口客户区。

生命周期控制

基于上面的关系,控件驱动和根控件的生命息息相关,那么我们让其相互制约。既然是他们自身相互制约,那么用户就不应该管理其生命周期,我们特意引入一个简单的对象池来管理,并用访问控制来避免外部直接构造。

private:
explicit Widget(widget::Driver* pDriver);
~Widget();
Widget(
const Widget&);
Widget
& operator =(const Widget&);

// 让对象池能够创建Widget对象
friend class ObjectPool<Widget>;
#pragma warning(push)
#pragma warning(disable:4396)
friend
void std::_Destroy(Widget _FARQ *);
#pragma warning(pop)

public:
static Widget* Create(HWND hWnd); // 创建根控件
void Destroy();

 

我们提供了一个静态接口Create用于创建根控件,可以注意到的一点是参数是窗口句柄。其实用户对于什么驱动、什么过滤的都不关心,用户只关心控件体系,所以说我们可以通过这个接口透明的创建根组件,实现中会自动的去驱动此窗口。

Widget* Widget::Create(HWND hWnd)
{
return GetWidgetPool_().Construct(widget::Driver::Create(hWnd));
}

 

驱动构造时会创建根控件,析构时销毁根控件

Driver::Driver(HWND hWnd)
: pImpl_(
new DriverImpl(hWnd))
{
// 创建根控件
pImpl_->SetRootWidget(Widget::Create_(this));
}
~DriverImpl()
{
// 销毁根控件
Widget* pOldRootWidget = GetRootWidget();
pRootWidget_
= 0;
if (pOldRootWidget)
{
pOldRootWidget
->Destroy();
}
}

 

同样,根控件析构时也销毁控件驱动

Widget::~Widget()
{
if (IsRoot())
{
pImpl_
->GetDriver()->Destroy();
}
delete pImpl_;
}

 

这样,用户其实有两个入口可以进入到我们的控件系统,一个是通过控件驱动,一个是通过控件本身。我们提倡用户不去关心控件驱动。那么甚至我们可以隐藏Driver这个类,目前我没有这样做。

下载测试工程源码

作者: Evil.Ghost 发表于 2011-04-06 21:21 原文链接

评论: 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谈起

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

posted on 2011-04-06 21:21 EvilGhost 阅读(351) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


导航

统计

常用链接

留言簿

随笔档案(12)

文章档案(1)

最新随笔

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜