这篇文章是接着上篇文章继续聊的,Chrome的代码实在太多,每一个东西单拿出来都可以说很很多,
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
|
之后我们把测试代码都加载test()这个函数中就可以了,另外这里之后的代码可能会泄漏的问题,这里我们先暂时不去理会他,后面会单独聊。
3.3. 实现一个简单的窗口
建立好了工程之后,我们就可以添加代码了,先让我们来建立一个最简单的窗口:一个空白的Widget。
1
2
3
4
5
|
|
短短几行我们就创建了一个最基本的窗口了,但是这个窗口实在是。。。有点难看啊。。
3.4. 添加一个按钮吧
既然难看,我们就来添加一些小控件到里面吧,先加一个小按钮吧。
首先,让我们来回想一下Chrome UI的元素结构,还记得这幅图么:
chrome-view-hierarchy:
所以为了增加按钮,我们需要创建一个按钮的控件,并且为Widget的ClientView生成一个ContentsView来保存我们的这个按钮。
首先我们先添加几个头文件:
1
2
|
|
另外我们添加了一个TestWidgetDelegate的类,用于设置Widget样式并且提供ContentsView。另外我们还给它添加了一个FillLayout,让按钮与窗口保持一样的大小。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
|
另外生成Widget的代码也要做少许的改动:
1
2
3
4
5
|
|
编译运行,可以看到一个按钮已经出现啦~
3.5. 添加一个原生控件
好,我们已经可以添加一个自绘的控件了,现在让我们来试着添加一个系统原生的控件吧。
由于Chrome是在View的基础上封装的原生控件,所以添加原生控件也并非难事。比如我们现在来添加一个Tab栏,我们只需要添加一个头文件,再稍稍修改一下TestWidgetDelegate的构造函数就可以了。
添加头文件:
1
|
|
修改TestWidgetDelegate的构造函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
|
这里需要注意的一点是:Chrome很多原生控件的真实实现类都是在View层次关系发生改变的时候创建的,所以在Tab等原生控件创建完成之后,需要马上将其加入View中,不然后续调用其接口就会发生崩溃。
让我们来看看最终的效果:
3.6. 控件的生命周期
Chrome控件的生命周期是比较晦涩的,在上面的代码,我们可以看见我们new出来了很多对象,但是从未调用过delete,那中间会有内存泄漏么?
答案是:不会。
这些的对象都会在窗口接收到最后一个消息的时候把所有在View树中的对象都释放掉。在Windows下,也就是在
WM_NCDESTROY
消息中的处理中,主动释放所有的对象的。
所以我们在使用中,只需要保存好这些对象的裸指针,并且在合适的时机将其置空即可。对于置空的时机,Widget和View也有对应的回调,如
Widget::DeleteDelegate
,或者在析构函数里面来进行。
4. 写在最后
对于Chrome UI控件库,这里只是做了写简要的记录。对于各种控件的使用,在Chrome的代码里面也提供了非常详细的实例程序,大家可以在
src/ui/views/examples
下找到这些代码。在VS中也提供了相应的工程:views_examples_exe,供大家参考。