这一章讲一讲七个步骤
简介
窗口类:是包含窗口之中信息的数据结构
每个窗口都有窗口类
1 | 1 定义WinMain函数 |
接下来我们看一段代码分析
1 | #include "windows.h" |
在窗口处理函数中, DefWindowProc这个函数是默认的窗口处理函数,我们可以把不关心的消息都丢给它来处理。需要我们处理的我们再做处理。这个函数在处理关闭窗口消息WM_CLOSE时,是调用 DestroyWindow函数关闭窗口并且发 WM_DESTROY消息给应用程序;而它对WM_DESTROY这个消息是不处理的;我们在应用程序中对这个消息的处理是发出WM_QUIT消息。因此WM_CLOSE、WM_DESTROY、WM_QUIT这三个消息是先后产生的。
对于RegisterClass,我们可以看看解释
1 | RegisterClass is basically you defining a class and including it in your program (much like a #include in C++). |
Windows系统包含一系列的预定义的窗口,例如按钮(button)、编辑框(edit)等。但如果你要创建一个属于你自己的个性窗口,你就要告诉系统这个窗口的“类”。而这个类你已经通过RegisterClass注册过了,所以系统会直接创建你定制的这个窗口类的实例。
CreateWindowEx内部实现:
根传入的名称,先在局部窗口类查找,找到了再将hinstance是否一样,如果相等,就基于它创建。若不相等。就在全局窗口类寻找,若还是找不到,就在系统窗口类查找。均找不到,则创建失败。
创建子窗口:
创建时设置父窗口句柄,创建风格加WS_CHILD|WS_VISIBLE.
消息:
消息基础:
组成:窗口句柄,消息ID,消息的两个参数,消息参数的时间,消息产生时鼠标位置
作用:当系统通知消息工作时,就采用消息的方式派发给窗口
我们可以看看MSG结构体的内容:
1 | typedef struct tagMSG { |
1 | DispatchMessage(&nMsg){ |
所以每一个窗口都有窗口处理函数
浅谈消息相关函数:
GetMessage
1 | GetMessage{ |
简单说说,假如我们想关闭进程,就将WM_QUIT放入本进程某个位置,然后GetMessage就会在系统中抓取这个消息
TranslateMessage
翻译消息。将按键消息,翻译成字符消息
检查消息是否时按键消息,如果是,就翻译消息,不是就return 0;
常用消息
WM_DESTROY:
窗口被摧毁时产生,摧毁之前,做相应善后处理,例如资源,消息
WM_SYSCOMMAND:
产生时间:窗口最大化,最小化,和关闭等
附带参数 wParam:具体点击的位置;IParam:鼠标光标位置(LOWORD:水平 HIWORD:垂直)
用法:常在窗口关闭时,提示用户处理
WM_CREATE:
产生时间:创建窗口但未显示时
IParam:为CREATESTRUCT类型的指针,通过它可以获取CreateWindowEx中的12个参数
用法:初始化窗口参数,资源等,包括创建子窗口
WM_SIZE:
产生时间:窗口大小发生变化时。
参数: wParam:窗口大小变化的原因 ;IParam:窗口变化后大小(LOWORD:变化后宽度 HIWORD:变化后高度)
用法:窗口大小变化时,调整窗口各个部分布局
WM_QUIT:
产生时间:程序员发送
参数:wParam:PostQuitMessage函数传递的参数 ;
用法:结束消息循环,当GetMessage收到消息时,返回false,退出循环
消息循环阻塞:
GetMessage-系统获取消息,将消息从系统中移除,阻塞函数,无消息时,等候下一条消息
PeekMessage-以查看方式从系统中获取,不将消息从系统中移除,非阻塞函数。无消息时,返回false,执行后面代码
发送消息:
SendMessage-发送消息,等候处理结果
PostMessage-投递消息,消息发出后立刻返回,不等侯消息执行结果。
系统消息ID范围(0-0x3FF)
用户自定义ID范围(0x0400-0x7FFF)
自定义消息宏:WM_USER
消息队列:
进程产生的消息先进系统队列,每隔一段时间,系统队列消息会发送到各个进程队列
postmessage消息扔到了系统队列
sendmessage消息既不进系统队列,也没进本进程队列
所以可知,sendmessage为非队列消息,他是直接将消息发送到窗口的函数,等候消息处理结果
一个消息无队列和非队列之分,看是否放入队列
WM_QUIT必须进队列(不仅队列,进程无法终止),WM-CREATE必须不能进队列(若进队列,无法抓取)
深谈GetMessage
1.在本进程查找消息,检查是否满足抓取
2.向操作系统队列抓消息(让系统分发消息,打破时间界限)
3.检查进程所有窗口需要绘制,若需要,产生WM_PAINT消息,取得消息返回处理
4.检查定时器,若某一定时器时间到,产生WM_TIMER消息
5.没有定时器,整理程序资源,内存等。
6.GetMessage等候下一条消息,PeekMessage返回false。交出程序控制权
下一节,讲讲资源