预编译头以及windowsAPI函数实际用它的ANSI(非指ASCII)字符版本函数还是用它的宽字符版本函数取决于啥

一、#include头文件或是宏的定义不要放在#include"stdafx.h"的前面,否则会提示warning ,甚至编译失败。

1、

//test.cpp : 定义控制台应用程序的入口点。

//

#include<Windows.h>

#include"stdafx.h"

1>------ 已启动全部重新生成: 项目: test, 配置: Debug Win32 ------

1>  stdafx.cpp

1>  test.cpp

1>c:\users\hc\documents\visualstudio 2010\projects\test\test\test.cpp(3): warning C4627: “#include<Windows.h>”: 在查找预编译头使用时跳过

1>          将指令添加到“StdAfx.h”或重新生成预编译头

1>c:\users\hc\documents\visualstudio 2010\projects\test\test\test.cpp(160): error C2065: “CHAR”: 未声明的标识符

1>   c:\users\hc\documents\visual studio2010\projects\test\test\test.cpp(162): error C3861: “GetUserName”: 找不到标识符

注释:

预编译头,貌似就是指的是StdAfx.h。vs系列编译器貌似已经固定死了就认名为StdAfx.h的头文件为预编译头。

函数GetUserName属于<Windows.h>里。从warning C4627: “#include <Windows.h>”: 在查找预编译头使用时跳过;将指令添加到“StdAfx.h”或重新生成预编译头,可以看出:

   

vs系列编译器编译一个项目时,先找出main函数所在的cpp文件,并查找该cpp文件里是否有预编译头#include"stdafx.h"如果该cpp文件里有#include"stdafx.h",则先对stdafx.cpp(以及stdafx.h)进行编译(即所谓预编译),再对test.cpp即main函数所在的cpp文件进行编译。(对于不存在main函数的项目,如编译一个dll项目该项目中不存在main函数,只有多个相互独立的类,则编译器该怎么知道先编译哪个cpp文件??)

即“生成”里显示的顺序:

1>------ 已启动全部重新生成: 项目: test, 配置: Debug Win32 ------

1>  stdafx.cpp

1>  test.cpp

 

 

而在main函数所在的cpp文件里排在#include"stdafx.h"的语句被跳过,即不会参加编译。这里由于Windows.h被跳过未被参加编译,故而main函数里被调用的属于<Windows.h>的函数GetUserName编译时会提示error C3861: “GetUserName”: 找不到标识符。

 

 

2、

//test.cpp : 定义控制台应用程序的入口点。

//

#definettttt

 

#include"stdafx.h"

 

1>------ 已启动全部重新生成: 项目: test, 配置: Debug Win32 ------

1>  stdafx.cpp

1>  test.cpp

1>c:\users\hc\documents\visualstudio 2010\projects\test\test\test.cpp(3): warning C4603: “ttttt”: 未定义宏或在预编译头使用后定义发生改变

1>          将宏添加到预编译头中,而不是在此处定义

1>          c:\users\hc\documents\visual studio2010\projects\test\test\test.cpp(5) : 使用预编译头

注释:

这里宏“ttttt”提示warning C4603: 未定义宏,也是因为#definettttt排在#include"stdafx.h"前面,故而在编译时被跳过而未被参加一起编译了。

附加:

//stdafx.cpp : 只包括标准包含文件的源文件

// test.pch将作为预编译头??

//stdafx.obj 将包含预编译类型信息

 

#include"stdafx.h"

 

// TODO: STDAFX.H

// 引用任何所需的附加头文件,而不是在此文件中引用

 

二、对于一个windows API函数最后实际是用它的ASCII版本函数(即该windows API函数的函数名结尾跟上A)还是用它的宽字符(即unicode)版本函数(即该windows API函数的函数名结尾跟上W),取决于相关设置。

相关设置有两种方式。一种影响范围为整个项目,一种影响范围为一个(含有#include"stdafx.h")cpp文件。

一种影响范围为整个项目:

选中一个项目,右键点击属性,跳出窗口里选择字符集来设置。

 

一种影响范围为一个(含有#include"stdafx.h")cpp文件:

假设当前项目-》属性-》字符集里的值为“使用unicode字符集”,而你想在项目里的某些cpp文件上使用多字节字符集编码的字符串,则你可以在stdafx.h里写上一语句:#undefUNICODE,并在那些要使用多字节字符集编码的字符串得cpp文件上写上一语句:#include"stdafx.h"即可。

那么你如何知道刚才的设置已经起作用了呢?

两种方法:

1、         如果你装了VX插件,则鼠标移到一windowsAPI函数上时会有如下显示:


2、         在windowsAPI函数上右键选“转到定义”之后看到当前不是灰色的函数版本即为起作用的函数版本:

 

假设当前项目-》属性-》字符集里的值为“使用多字节字符集”,而你想在项目里的某些cpp文件上使用unicode字符集编码的字符串,则你可以在stdafx.h里写上一语句:#defineUNICODE,并在那些要使用多字节字符集编码的字符串得cpp文件上写上一语句:#include"stdafx.h"即可。



 附加:

1、

至于像#defineUNICODE或是#undefUNICODE一定要放在stdafx.h里才起作用,而直接放在那些要使用多字节字符集编码的字符串得cpp文件上不起作用的原因暂时不知了。反正,程序员自己在cpp文件上定义的宏是可以在该cpp文件上起作用的。例如,在一cpp文件上

// #define ttttt 

//

 #ifdefttttt

 intG_r=5;//没定义宏ttttt时该句就是灰色的,有定义则不是灰的,这说明定义的宏起作用了。

 #endif


 2、

#ifdefUNICODE

#defineGetUserName GetUserNameW

#else

#defineGetUserName GetUserNameA

#endif// !UNICODE

从上述定义模板设计可以看出,对于一个windows API函数要用它的ASCII版本函数(即该windows API函数的函数名结尾跟上A)还是用它的宽字符(即unicode)版本函数(即该windows API函数的函数名结尾跟上W),是利用定义或是取消定义宏UNICODE,而定义或是取消定义宏MBCS之类的名字不起作用的。

 3、

对于在tchar.h里定义的TCHAR数据类型,上述第一种方法对其是起作用的:

如果你装了VX插件,

假设当前项目-》属性-》字符集里的值为“使用多字节字符集”,则鼠标移到TCHAR数据类型上时会有如下显示:

 

typedefchar   TCHAR;

 

假设当前项目-》属性-》字符集里的值为“使用unicode字符集”,则鼠标移到TCHAR数据类型上时会有如下显示:

 

typedefwchar_t    TCHAR;

 

 

上述第二种方法对tchar.h里定义的TCHAR数据类型是不起作用的,原因暂时不知。原因应该是

tchar.h 头文件里,使用 _UNCODE 定义而不是使用UNCODE 定义

#ifdef  _UNICODE

... ...                    

#define __T(x)  L##x             /* for UNICODE */

... ...

#else

... ...

#define __T(x)  x               /* for ANSI */

... ...
 
#endif


#define _T(x)  __T(x)

上述第二种方法只要改为定义或是取消定义宏_UNCODE即可起作用。

参见:

宏UNICODE VS 宏_UNICODE 与 TEXT() VS _T()


4、

对于一个windows API函数来说,

它的ASCII版本函数(即该windows API函数的函数名结尾跟上A)的参数里有一个使用字符串的参数,那么ASCII版本函数使用的字符串只能是char数据类型定义的字符串(即多字节字符集编码的字符如char str[20]="asdfg";),而不能使用unicode字符集编码的字符串,即wchar数据类型定义的字符串如wchar str[20]=L"asdfg"。

它的宽字符(即unicode)版本函数(即该windows API函数的函数名结尾跟上W)亦是如此。

不要以为当前项目-》属性-》字符集里的值为“使用unicode字符集”后,该项目里出现的字符串就都是unicode字符集

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值