创建窗口的函数一般为
ClassName.Create()
{
}
但是为了把创建窗口过程中,定义各种属性的权限开放,微软预留了多个接口,其中两个就是:
- PreCreateWindow(): 创建窗口之前的接口函数
- OnCreate(): 和创建窗口之后的接口函数
其调用顺序为:
Create()
{
PreCreateWindow()
...
...
// 窗口创建过程:包括注册窗口、、、
OnCreate();
}
上述的的接口指的是基类的虚函数,虚函数是一种泛型编程技术,即多态,这里区别继承和多态
继承:让子类具有基类的所有功能和属性
多态(这里只讨论虚函数):能够让子类在基类的基础上具有不同的功能
说明:
(1)CWnd 是对win32窗口的封装;
(2)用 win32 创建窗口后,窗口资源的唯一标识是窗口句柄 HWND hWnd;
(3)因此,仅仅创建一个 CWnd 对象不代表创建窗口成功,完整步骤如下:
-
步骤1:创建 CWnd 对象,该对象里面封装了 win32 创建窗口过程中所有的通用代码,但是没有完成窗口创建。
CWnd MyWnd; -
用 CWnd 的成员函数“绑定一个窗口”
实际上,MyWnd.Create() 函数也是对 win32 Create() 函数的封装
而 win32 Create() 函数创建一个窗口后会生成一个窗口句柄,并
将其赋值给 CWnd 的成员 m_hWnd; 至此才算用 CWnd 创建了一个窗口
MyWnd.Create(NULL, “我是一个窗口”);类似的,如:
HWND ——> CWnd: m_hWnd
HDC ——> CDC: m_hDC
HPEN ——> CPen: m_hPen
HBBRUSH ——> CBrush: m_hBrush这也是为什么每次使用 画笔之前都要创建或者初始化而使用完之后,要销毁,否则会产生无数个“窗口”或资源。其中,CDC 的资源被 CWnd 管理,所以不用我们销毁。
-
对 CWnd 成员函数的重载:
前面说到,创建一个 CWnd 对象只是封装了 win32 创建窗口过程中所有的通用代码,
也就是设计了一个窗口的产生过程、样式等属性,但是并没有创建一个窗口,可以说是一个毛坯房的设计图;
如果我们要对该“毛坯房”进行精装修,那就需要对其一些成员函数进行重载
这些可重载的成员函数可以说是微软在构建这个毛坯房的各个节点预留了一些接口;
当你在这些接口内添加一些处理代码后,这些代码就会在窗口创建或窗口对象的使用过程中发挥作用。
就如上面讲到的
Create()
PreCreateWindow()
OnCreate();
这三个函数之间的关系。 -
重新理解模态对话框和非模态对话框
https://bbs.csdn.net/topics/300046787消息队列是属于线程的,同一线程最多只有一个消息队列。
因为消息循环本质是一个 while 的死循环,触发特定消息才 break
非模态对话框的消息响应与模态对话框没有差别。 -
模态对话框的阻塞机制
测试内容为:
在主对话框上设置 Timer 计时器,
OnTimer 每隔 2 秒 使成员数据递增 1 ,并显示在主窗口上,
当生成一个模态的子对话框的时候
OnTimer 消息依然会自动响应,没有被模态的子对话框阻塞;OnTimer 消息响应并不占用消息循环的时间,
可以看作是一个独立的“伪线程函数”