使用Windows API构建窗体应用
就历史来说,使用纯API开发窗体应用程序是上个世纪80年代以前的事情了,开发应用程序的人需要使用大量接近系统内核的API来完成应用程序的设计(当时C的版本还很低,没有类等概念,使用大量流程式,函数式的代码写一个窗体应用是一件很恐怖的事情)。MFC的第一个公开版本发布于1992年3月,使用C语言开发窗体应用的程序员们转而开始使用MFC来代替使用API直接开发窗体类应用程序。MFC相当彻底的用类封装了Win32 API,使得C程序员的开发窗体类应用的效率大大提高了。本文试图展示一下使用Windows API直接编写窗体类应用的核心内容,为之后关于Qt制作窗体应用的介绍以及一些别的有趣的东西做铺垫。
先从入口函数开始介绍。当Windows操作系统启动一个程序之后,由编译器插入到可执行文件中的启动代码(之前还干了一堆事情,初始化各个段,初始化堆、栈等)调用WinMain函数启动应用程序。WinMain函数是一个标准API函数,你需要一个声明,它被包含在标准库头文件中。 WinMain函数的作用和我们制作控制台程序时的main函数的作用是相同的,你的程序将从WinMain函数作为主函数开始执行。
面向过程编程,如果你不只是简单的想让你的程序弹出一个对话框而是创建一个窗体,你需要了解一个窗体是如何创建的。在Windows平台使用API绘制窗体的基本流程是:
*第一步按照Windows平台的标准,定义并设计一个窗体类(定义并设置一个包含窗体属性的结构体WNDCLASSEX,这个结构体的结构是有官方文档的);
*第二步使用RegisterClassEx函数注册窗体类,所有窗体在创建前都必须注册窗体类,只有注册的窗体类才被系统认知并允许实例化,窗体上的控件在API的命名中也同属于Window,但是当你要在窗体上绘制控件就不需要对控件(Window)的类进行注册了;
*第三步使用CreateWindow传参在内存中创建窗体(当然同时可以创建控件);
*最后使用ShowWindow显示窗体,这是处理显存程序必须做的事情。必要时还需要使用UpdateWindow更新显存重绘窗体。
在完成绘制之后我们的程序应该进入一个循环,用来处理各种消息,如窗体大小调整或关闭,按键和鼠标输入等等。我们使用Windows系统提供的API的方案进行消息处理。总共有两个消息队列,一个是应用程序的(进程的),另一个是窗体的。
使用PeekMessage获取应用程序的消息(包括控件,我们传入句柄来获取传向不同窗体的消息),这类消息包含很多麻烦的参数,是用结构体来描述的。我们需要将消息进行翻译简化(使用TranslateMessage函数)然后发送到窗体消息队列中(DispatchMessage函数)让窗体的消息处理函数对简化了的消息进行处理并做出反应。我们在窗体类中写入了一个消息处理函数(一个函数指针),窗体类被注册后,系统会在窗体收到消息之后自动调用该消息处理函数以处理消息。
最后如果接收到退出消息,你需要退出消息处理循环后,按顺序分别使用API,DestroyWindow删除窗体,UnregisterClass取消注册窗体类然后退出程序。最后给出一个使用纯API构建包含一个窗体的应用程序实例。
其中没有说明的是DefWindowProc函数,该API函数为你处理并响应一些默认的鼠标和键盘操作产生的消息。
必须要说的是,必要的API类似单不同的函数的辨析我都略去了,其中问题包括一堆可互相替代使用的API函数,加与不加后缀Ex的函数的区别以及,消息处理机制的部分重要内容,一切只为突出本文的重点,描绘出Windows系统程序使用API创建窗体应用的轮廓。现在你们大可不必直接使用API制作窗体应用程序(在理解API的使用流程下使用MFC或是用Qt写窗体应用),但是了解原理是非常必要的。现在我们有如此多的语言(Java、Python等)和相应的编译器,他们大多是基于API函数才能在Windows平台上施展拳脚(各类编译器在当前平台上使用C++加上Windows SDK编写编译),对底层有一定的了解可以让我们注意到那些语言和语法中更本质的内容,而不会每次面对一些新的内容茫然不知所踪。
参考资料:《逐梦旅程:Windows游戏编程之从零开始》
p.s. 有趣的是,这类游戏制作教程会比较流程式和完整的介绍API的使用方法
本文来自企鹅号 - 华水极客乐园官微媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文来自企鹅号 - 华水极客乐园官微媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。