流程介绍

创建一个窗口一共需要6步:
- 注册类
- 创建窗口获取句柄
- 进入回调
- 显示窗口
- 更新窗口
- 获取消息

代码解释

在注册类之前我们先要建立基本的代码框架,也就是编写WinMain函数,这是Windows窗口程序的入口函数名,相当于控制台下的main函数,WinMain的定义为:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
参数列表解释:
- hInstance:当前运行的实例句柄
- hPrevInstance:上一个实例的句柄,不过这个句柄基本没用了
- szCmdLine:传递给应用程序的命令行参数
- iCmdShow:指定程序的窗口的显示方法
注册类用的是RegisterClass函数,RegisterClass只有一个参数用于接收WNDCLASSW型变量。 WNDCLASSW是作为一个结构体tagWNDCLASSW的别名,tagWNDCLASSW的结构如下:enter image description here

而我们的参数使用如下: enter image description here

窗口类型为CS_HREDRAW,该类型的意思是:移动或者调整窗口的高度(垂直方向)时,重绘整个窗口。 回调函数后的两个扩展一般都是填0的。
Icon使用默认应用程序图标资源,Cursor使用箭头光标。
背景色为白色,当然也可以改成黑色或是灰色。
无菜单栏。
类名我们定义为MainWindow,当然定其他的名字也可以,但最好避免定义如button之类的系统内定的字符串,字符串不区分大小写,这点我专门测试过。创建一个按钮,类名写“BuTton”都可以,但目前我们不需要太关心这个,只是顺便提一下。
写完了WNDCLASS的配置后,就可以用RegisterClass(&wndclass);来注册类了。

注册类后,我们就可以通过CreateWindow来获取窗口句柄,CreateWindow函数的定义如下:enter image description here

enter image description here

而我们的调用如下:enter image description here

在调用之前,我们获取了屏幕的宽高,以便计算让窗口位于屏幕的中间,当然也可以用CW_USEDEFAULT,在dwStyle中传入WS_OVERLAPPEDWINDOW后可以用CW_USEDEFAULT来使窗口位于屏幕中间。
创建窗口后程序就会进入WndProc回调函数,该回调函数的定义如下:
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
名称不一定非要是WndProc不可,换成其他的也可以,甚至是ABCProc,但必须要与注册类时使用的回调函数名称一样,否则将会回调失败。
接下来就是回调函数的实现:enter image description here

其中hwnd是窗口句柄。
message是传回来的窗口消息。
后面两个都是额外的参数,使用方面没什么两样,主要区别在于wParam偏向数据本身,而lParam偏向结构体,不理解就当一样的东西用好了,问题不太大。
在截图上我们处理了一个叫WM_DESTROY的窗口消息,在用Windows API创建窗口后,如果关闭窗口,就会发出这个消息,但如果不做处理那只是窗口被关闭了,进程依然会留在内存中,所以我们在接收到消息后就调用PostQuitMessage(0);来退出进程。
而其他的消息则交给默认的处理方法DefWindowProc。

最后

现在我们已经写完了能创建一个600 * 400的窗口的程序了,但别急着编译运行,先检查一下语法是否正确,括号是否写全,我在截图中没有显示出来的括号有没有补上去,请检查一下。
检查完了吗?那么请编译运行吧,用G++也可以,用Visual Studio也可以,编译运行后就会出现一个空白窗口了,截图如下:enter image description here

现在空白窗口我们就建立完毕了。