何问起C++教程 - Windows编程 - Win32编程
WinMain与wWinMain的区别和选用
使用Visual Studio创建Windows桌面应用程序(C++),代码中的入口函数是wWinMain,而不是WinMain,如下:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
}

另外,WinMain函数也是应用程序入口点。

总的来说,每个Windows程序都包含一个名为 WinMain 或 wWinMain 的入口点函数。 下面是 wWinMain 的签名。(C++)

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);

那么WinMain和wWinMain有什么区别呢?

WinMain对应的是ANSI字符集,wWinMain对应Unicode字符集。一般首选wWinMain
要更改字符集的话,在vs里面点 项目->项目属性,如下图:


另外有时会有_tWinMain的入口函数,在tchar.h文件里定义如下:
#ifdef _UNICODE
#define _tWinMain wWinMain
#else
#define _tWinMain WinMain
#endif

编译时当字符集为ANSI时_tWinMain就同于WinMain,字符集为Unicode时_tWinMain同于wWinMain。

windows api很多函数都分为两个版本,比如CreateWindow的定义如下:
#ifdef UNICODE
#define CreateWindow CreateWindowW
#else
#define CreateWindow CreateWindowA
#endif

那么,什么时候该用Unicode字符集,什么时候该用多字节字符集呢?

其实并不是程序中有中文时就必须用Unicode字符集,当windows系统语言为中文时,不管你选择哪个字符集都是可以正常显示中文的.

如果选择了多字节字符集(ANSI),但是系统语言不为中文时就可能出现乱码了。所以如果你的软件需要适应多语言的windows系统的话就选用Unicode字符集。

另外需要说明的是,当字符集为Unicode时,向api函数传递的一个字符串的时候应该将该字符串转换为Unicode编码的,可用L转换:

CreateWindow(wndClass, L"这是窗口标题-何问起", ......);

补充:
在实际应用中接触比较多的文本编码有3种:ASCII、ANSI和UNICODE,其中ASCII码是后两种也是大多数常用编码的基础。

ASCII码
文本编码方式的基础是ASCII码,它是一个7位的编码标准,包括26个小写字母、26个大写字母、10个数字、32个符号、33个控制代码和一个空格,共128个代码。由于计算机通常采用“字节”为单位存储和交换数据信息,因此很多计算机厂家对ASCII码进行了扩充,在原来的基础上又增加了128个附加字符,如ANSI、UNICODE等字符集。

UNICODE
对于英文来讲,ASCII码就足以编码所有字符,但对于中文,则必须使用两个字节来代表一个汉字,这种表示汉字的方式习惯上称为双字节。虽然双字节可以解决中英文字符混合使用的情况,但对于不同字符系统而言,就要经过字符码转换,非常麻烦,如中英、中日、日韩混合的情况。为解决这一问题,很多公司联合起来制定了一套可以适用于全世界所有国家的字符码,不管是东方文字还是西方文字,一律用两个字节来表示,这就是UNICODE。

ANSI
ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~0xFFFF来编码,即扩展的ASCII编码。

为使计算机支持更多语言,通常使用 0x80~0xFFFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GB2312编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 JIS 编码。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。ANSI编码表示英文字符时用一个字节,表示中文用两个或四个字节。
ANSI编码作为中国以及部分亚太地区的多字符编码格式,Windows系统和OS X都是提供原生支持的。但是即便如此,许多国外开发者仍然在开发笔记或者文字录入类应用的时候将ANSI编码完全忽略,只加入全球通用的UTF-8编码。

wWinMain说明:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);

这四个参数为:

hInstance 称为“实例句柄”或“模块句柄”。操作系统使用此值在内存中加载可执行文件时标识可执行文件 (EXE) 。 某些Windows函数需要实例句柄,例如加载图标或位图。
hPrevInstance 没有意义。 它在 16 位Windows中使用,但现在始终为零。
pCmdLine 包含命令行参数作为 Unicode 字符串。
nCmdShow 是一个标志,指示主应用程序窗口是最小化、最大化还是正常显示。

该函数返回 int 值。 操作系统不使用返回值,但可以使用返回值将状态代码传达给你编写的其他程序。

WINAPI 是调用约定。 调用约定定义函数如何从调用方接收参数。 例如,它定义参数在堆栈上显示的顺序。 只需确保声明 wWinMain 函数,如下所示。

WinMain 函数与 wWinMain 相同,但命令行参数作为 ANSI 字符串传递。 首选 Unicode 版本。 即使将程序编译为 Unicode,也可以使用 ANSI WinMain 函数。 若要获取命令行参数的 Unicode 副本,请调用 GetCommandLine 函数。 此函数返回单个字符串中的所有参数。 如果要将参数作为 argv 样式数组,请将此字符串传递给 CommandLineToArgvW。

编译器如何知道调用 wWinMain 而不是标准 主 函数? 实际上,Microsoft C 运行时库 (CRT) 提供了调用 WinMain 或 wWinMain的主要实现。

备注

CRT 在 main 中执行一些额外的工作。 例如,在 wWinMain 之前调用任何静态初始值设定项。 虽然你可以告诉链接器使用不同的入口点函数,但如果链接到 CRT,请使用默认值。 否则,将跳过 CRT 初始化代码,结果不可预知。 (例如,全局对象不会正确初始化。)

下面是一个空 的 WinMain 函数。(C++)
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
return 0;
}
收藏 列表

评论: