原文地址:
http://www.directxtutorial.com/Lesson.aspx?lessonid=11-1-2
运行环境:Visual Studio 2015
Win32 Console Programs vs. Windows Programs
Win32控制台程序和Windows程序
两项的区别:
我们在学习C++时,用cin、cout那一套写出来的程序通常都是一个黑洞洞的基于DOS的窗口,那就是所谓的【Win32控制台程序】
而我们现在学习编写在Windows下运行的Win32窗口程序。Windows下绝大多数的游戏程序,都是基于在新建工程时创建Win32项目,在这个类型程序的基础上进行开发的。
所以,新建工程时一定要确认好选择的是Win32项目。
接下来,在资源管理器中展开Hello World项目,并在源文件一栏中单击鼠标右键,添加新建项。在弹出来的对话框找到C++文件(cpp),一般情况下默认为该文件类型,选定后,为准备新建的源文件取一个名称,比如main.cpp。
The WinMain() Function
WinMain()函数:
这个函数等同于在Win32控制台中的main函数,是所有Windows程序的入口点函数。当WinMain函数结束或返回时,Windows应用程序也就结束了。
WinMain()函数的原型如下:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow);
WINAPI
宏定义如下:
#define WINAPI _stdcall
#define CALLBACK _stdcall
也就是说WINAPI其实就是_stdcall,只是为了让我们清楚知道这里的_stdcall表示的是一种调用约定,它让编译器知道了应当以Windows兼容的方式来产生机器命令(In short, what it does is reverse the order the parameters are passed. They normally pass from right to left, but with WINAPI, they are passed from left to right.)意同CALLBACK,即要求编译器从右向左传递参数。为什么要这样并不是很重要,只是Windows要求我们需要这样做。
HINSTANCE hInstance,
HINSTANCE类型的hInstance,它表示该程序当前运行的实例句柄。一个句柄是一个32位整数,用来表示某物的身份,就像一个对象一样。而instance是一个实例的拷贝,其实也就是一个数值。由于多任务和执行多个重复程序的需要,Windows需要通过这个方法来保持程序身份的跟踪。当一个程序在Windows下运行时,它唯一对应一个运行中的实例,也只有运行中的程序实例,才有资格分配到实例句柄。一个应用程序可以运行多个实例,每运行一个实例,系统都会给该实例分配一个句柄值,并通过hInstance参数传递给程序的入口点WinMain函数。
HINSTANCE hPrevInstance,
HINSTANCE类型的hPrevInstance,表示当前实例的前一个实例的句柄。意味着,如果有一个运行中的应用程序被多次拷贝,hPrevInstance就会保存上一个被创造的实例的值。在Windows 95之前,一个相同应用程序的多重拷贝是共享内存空间的,而如今在32位环境下的话,Windows给每个应用程序都分配了自己的内存空间,hPrevInstance也因此废弃。这里只是为了与过去版本兼容的方便,所以我们现在在任何应用程序里都把这个参数设为NULL。
LPSTR lpCmdLine
LPSTR类型的lpCmdLine,lp意味着这个参数是一个指针,指向一个以空终止的字符串,指定传递给应用程序的命令行参数。例如,如果你有一个应用程序为MyApp.exe,然后你在命令提示符中运行它,你可以像这样运行“MyApp.exe” or “MyApp.exe RunA” or “MyApp.exe RunB”。
不管哪一种方式,lpCmdLine会存储你输入的整一个字符串,用来允许程序检查特殊参数。
这对于游戏编程运行特殊的模式很有帮助。
int nCmdShow
int类型的nCmdShow,指定程序窗口如何显示,是最大化、最小化还是隐藏等等。
这个参数可有如下取值:
MessageBox函数:
先看一个实际的例子,“Hello World!”
#include <windows.h> // include the basic windows header file
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
// create a "Hello World" message box using MessageBox()
MessageBox(NULL,
L"Hello World!",
L"Just another Hello World program!",
MB_ICONEXCLAMATION | MB_OK);
// return 0 to Windows
return 0;
}
运行如下:
#include <windows.h>
我们编写Windows程序中所说的API函数,就是指系统提供的函数,主要的Windows函数都在windows.h这个头文件中进行声明了。
MessageBox()
函数原型如下:
int MessageBox(HWND hWnd,
LPCTSTR lptext,
LPCTSTR lpcaption,
UINT utype);
HWND hWnd,
HWND类型的hWnd,表示我们显示的消息框所属的窗口的句柄。在这个例子中,因为我们没有创建任何窗口,所以我们设为NULL,表示消息框是从属于桌面的。
LPCTSTR lptext,
LPCTSTR类型的lptext,lp表明它是一个指针,指向所要显示的消息的内容。
LPCTSTR lpcaption,
LPCTSTR类型的lpcaption,lp表明它是一个指针,指向我们要显示的消息框的标题的内容。
UINT utype
UINT类型的utype,表示我们消息窗口需要什么样的样式。当需要多种样式时,使用逻辑or操作符“|”连接
这个参数可有以下取值:
常用的图标我们也是通过一些标识名来指定,有如下几种:
当然,像大多数Win32函数一样,MessageBox函数也有返回值。在游戏编程里,我们一般不需要这个返回值,因为错误信息只有一个去向:退出。而如果我们创建了具有对应按钮的消息框,就涉及到按下具体的按键,就需要给出按键的返回值,这样我们就需要判断哪个键被按下了,再对应作出相应的响应。
返回值的列表如下: