今天学习了DirectUI最初的版本http://www.viksoe.dk/code/windowless1.htm,尝试着自己把它提取出来,写成一个更简单的DEMO,所以做一个小笔记:
主程序是基于CFrameWindowWnd创建的
1.CWindowWnd:是所有窗口的基类,
它包含了RegisterWindowClass用于注册窗口,在注册中设置窗口过程函数__WndProc
Create中调用CreateWindowEx,CreateWindowEx最后一个参数传入this,
CFrameWindowWnd基于CWindowWnd注册创建,
下面具体说下这个窗口的实现:
1.RegisterWindowClass用于注册窗口,在注册中设置窗口过程函数__WndProc
2.在Create中调用CreateWindowEx,CreateWindowEx最后一个参数传入this,根据MSDN,可以知道,
this被存入the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message
3.在__WndProc中处理消息,其中包括:
3.1.在WM_NCCREATE消息中得到CreateWindowEx传入的this指针(CREATESTRUCT ::lpCreateParams ),通过this指针就可以从CWindowWnd
指向特定的子类对象CFrameWindowWnd,同时为了以后处理消息能被调用到,将其通过SetWindowLongPtr的GWLP_USERDATA存入,这样就
可以每次消息时都取出this(通过GetWindowLongPtr).
3.2.在3.1基础上,this调用HandleMessage(虚函数)处理它自身消息,如this指针取出为空,调用默认DefWindowProc
我们可以看到,通过注册窗口,创建窗口,传递自身指针,CFrameWindowWnd最终实现了在它自身的
HandleMessage函数中处理它自身的窗口过程消息,相当于实现了子类化.
4.在HandleMessage的WM_CREATE开始创建它的子窗口page_start
page_start和CFrameWindowWnd类似创建,同样注册窗口,创建窗口,传递自身指针,
最终实现了在它自身的HandleMessage函数中处理它自身的所有消息,但子窗口加入了绘制类CPaintManagerUI对象
extern:
下面说说绘制类CPaintManagerUI
1.在Main()中调用MessageLoop函数,MessageLoop实现了过滤当前线程的所有消息
也就是一个GetMessage.
2.通过SetResourceInstance把hInstance保存
3.通过MessageHandler处理窗口消息.
5.接上面的,子窗口的HandleMessage中加入了绘制类CPaintManagerUI的MessageHandler处理窗口消息.
所以很清楚了,最终所有的窗口都通过HandleMessage来代替原有的系统窗口过程函数处理消息
子窗口同时通过CPaintManagerUI绘制类的MessageHandler处理窗口消息.同时CPaintManagerUI绘制类
还通过MessageLoop实现了过滤处理当前线程的所有消息