views通过其Widget对象为创建对话框和其他类型的窗口提供支持。开发人员通过创建一个WidgetDelegate(或子接口)实现,为窗口提供必要的信息以显示其自身,还提供有关窗口事件的回调。
- WidgetDelegate是一个为Widget类提供信息并显示窗口的接口,例如其标题和图标,以及诸如窗口是否可调整大小等属性。
窗口封装:Widget
- Widget实现了窗口的封装,一个Widget对应着一个真实的窗口。
为了将平台相关的窗口细节隐藏在Widget内部,Chromium为平台相关的窗口抽取出了一个接口:NativeWidgetPrivate,用以封装平台相关的代码,而在里面将平台相关的消息转化为平台无关的消息,再通过NativeWidgetDelegate回调出来。而NativeWidgetDelegate除了接收回调以外,他还有很多用以指定原生窗口风格的回调函数,供NativeWidgetPrivate创建时调用。
这些处理过后的消息,就可以被统一来处理了。这里Widget本身作为NativeWidgetDelegate接收并处理这些消息或者分发给所有的控件,即View(界面元素),由这些控件来触发真实的逻辑。
Client and Non Client Views
一个窗口的内容实际上分成两个部分:
- 非客户区:一个窗口只有一个非客户区,这部分包括标题栏,关闭按钮等等
- 客户区:这部分包括很多内容,按钮,工具条等等我们用到的控件
在Chrome里面,各种不同的View成树形的关系组织在一起,他们的根节点就是Widget,Widget接收到系统原生的消息,并通过RootView将消息分发给下层的View,这里Widget和RootView是一一对应的
下层的View主要分为三种:
- 用于表示整个窗体非客户区的NonClientView,负责设置窗口边框大小。它也是其他两种View的父,原因很简单:他管着整个窗体的边框,所以其他的View必须是他的子。
- 用于表示非客户区的内容的NonClientFrameView,负责绘制非客户区里面的元素,如标题栏,关闭按钮等等.
用于表示客户区和其内容的ClientView,负责生成各种窗口元素(标题栏/框架内的东西)。
通过这样的一个关系,chrome将所有的界面元素都管理了起来。
除了RootView之外, Window's View层次结构中最顶层的View是NonClientView 。这个视图恰好是下面两个视图的容器