下面是一个简单的Win32程序,main函数
是程序的起点,Windows能够向程序输入任何你认为必要的参数。
#include // include the standard input/output header file
void main(void) // our program starts here
{
printf("Hello World!"); // print "Hello World!" into the console
return; // return void to windows
}
而Windows程序除了有类似Win32程序的mian函数
一样,它还是事件驱动的。事件是指诸如用户点击鼠标、按一个键或者一个计时器归零等事情的发生。当这些事件中的任何一个发生时,Windows将这个发生的事件记录在一个消息中,并将这个消息放在该消息对应的程序的消息队列中,例如你的游戏。这个程序通过一个函数负责处理这些消息。
Windows程序的WinMain函数
就类似于Win32控制台程序的main函数
,这是程序的起点,里面可以进行一些基本的初始化操作,例如创建窗口、基本的循环以及计时器的一些代码。下面是WinMain()函数
的原型并对其中的参数进行介绍:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow);
在int
和WinMain
之间,是WINAPI
这个词。WINAPI是一种传递参数的方式,这种方式来自于Fortran和Pascal时代。简言之,它的作用就是颠倒参数的顺序。参数通常是从右往左传,但是WINAPI将它们从左往由传递。这个细节并不重要,我们只要记住Windows程序要求这样做就行。
第一个参数是“handle to an instance”(实例句柄)的缩写,句柄(handle)是一个32位整数,用于表示某些内容,例如一个对象(object)。实例(instance)其实就是应用程序的副本。由于要进行多任务以及运行程序的多个副本,Windows需要跟踪哪个程序是哪个,因此Windows通过给每个应用程序的每个实例赋予一个实例句柄来到达这个目的,简单的说就是用一个整数来标识每个应用程序。当你的程序开始时,Windows会选择一个数字并传入这个参数。
这个参数是过去遗留下来的,它表示前一个实例的句柄。这意味着,如果一个应用程序有多个副本,则hPrevInstance
将包含最后一个创建的实例的句柄。
在32位处理器出现之前,同一应用程序的多个副本是共享相同的内存空间,这使得编程变得很复杂,因此程序员常常阻止他们的应用程序运行自己的多个副本。为了避免这种情况,hPrevInstance
能够先前实例的句柄,如果当前是唯一的实例,则返回NULL。这就允许程序员能够检测任何正在运行的副本。
然而,目前的应用程序普遍都是32位,Windows为每个32位的应用程序提供了自己独立的内存空间,hPrevInstance
这个参数也就过时了。它存在的目的仅仅是为了兼容性,该值在32位应用程序中都等于NULL。
这个参数是一个指向字符串的长指针,该字符串包含了调用应用程序的命令行。例如,你有一个名为“MyAPP.exe”的应用程序,并在命令提示符(cmd)下运行该应用程序,你输入的命令行可能为“MyAPP.exe”或者“MyAPP.exe RunA”或者“MyAPP.exe RunB”。lpCmdLine
会存储所有的输入内容,从而允许程序检查特定的参数。
这个参数指示创建窗口时的外观。例如,这个参数可能要求将窗口最小化、最大化或者正常化,甚至打开一个在后台运行的窗口。通常你在游戏编程中不需要用到它们,但如果你愿意,也可以使用它们。
下面,让我们来写一个简单的实例程序!最简单的当然是“hello world”这个程序啦!
#include // include基本的Windows头文件
// 每个Windows程序都需要一个WinMain函数作为入口
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
// 使用MessageBox()创建了一个"Hello World"消息框
MessageBox(NULL,
L"Hello World!",
L"Just another Hello World program!",
MB_ICONEXCLAMATION | MB_OK);
// 返回0给Windows
return 0;
}
如果你成功运行这个程序,会得到下面这个消息框:
下面,我们将从上到下分解该程序中新出现的部分:
windows.h
头文件实际上就是一个容器,里面包含了许多对Windows编程有用的头文件,这样我们就不必自己添加大量的头文件。
这个函数用于创建一个消息框,这是它的原型:
int MessageBox(HWND hWnd,
LPCTSTR lptext,
LPCTSTR lpcaption,
UINT utype);
下面将简要介绍一些它的参数:
参数 | 作用 |
---|---|
HWND hWnd |
HWND 是窗口的句柄,如前面提到的一样,句柄是一个整数,用于表示一个对象。在这里,我们用于标识一个窗口。因为我们还没有创建任何窗口,因此将其设为NULL,并且Windows知道这个消息不是来自其他任何窗口,而是来自桌面 |
LPCTSTR lptext |
这个参数是一个指向16位字符串的指针,该字符串表示消息框文本 |
LPCTSTR lpcaption |
这个参数也是一个指向16位字符串的指针,该字符串表示消息框标题 |
UINT utype |
这个参数用于确定消息框的样式,该参数有多个类型的值,并且可以通过OR操作符结合使用 |
在游戏编程中,通常不需要返回值,因为错误消息只有一个方向可以进入:退出。