详见:http://student.csdn.net/link.php?url=http://www.rupeng.com%2Fforum%2Fthread-3214-1-1.html
他已经将GetListBoxInfo所在的头文件WinUser.h直接或者间接的包含进来了,打开WinUser.h文件,看到GetListBoxInfo就活生生的躺在那里呢,为什么还是报“'GetListBoxInfo' : undeclared identifier”呢?难道VC眼瞎了吗???
一开始就解决GetListBoxInfo的这个问题可能比较麻烦,咱们先来看另外一个API函数:LockWorkStation,他就在GetListBoxInfo函数的定义下面:
代码:
WINUSERAPI BOOL WINAPI LockWorkStation(VOID);
我们仔细看LockWorkStation函数的定义,看更大范围的:
代码:
#if(_WIN32_WINNT >= 0x0500)
WINUSERAPI
BOOL
WINAPI
LockWorkStation(
VOID);
#endif /* _WIN32_WINNT >= 0x0500 */
_WIN32_WINNT是一个宏定义,它表示Windows的版本,它有很多取值,取值列表如下:
代码:
Windows XP _WIN32_WINNT>=0x0501
Windows 2000 _WIN32_WINNT>=0x0500
Windows NT 4.0 _WIN32_WINNT>=0x0400
为什么要根据操作系统的版本决定函数的定义是否编译呢?道理很简单,因为有的API函数是高版本的Windows下才提供的,低版本的Windows没有那个API函数,所以需要根据操作系统进行判断。
不对呀!我的操作系统是WindowsXP,确实比Windows 2000高呀,为什么不能编译呢?
原因就是“_WIN32_WINNT”并不是像大家想象的那样真的会代表当前编译程序电脑的操作系统的版本,它需要程序员去指定,当然VC也给了“_WIN32_WINNT”一个默认值,不过这个默认值是VC从微软那发布的时候微软定义的:
代码:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
时光荏苒,日月如梭,现在已经是2009年了,主流的Windows桌面操作系统已经是WindowsXP了,还有相当一部分人用上了Vista甚至Windows7,那么“ _WIN32_WINNT 0x0400”这个默认值已经Out了!
那么咱们怎么修改_WIN32_WINNT的默认值呢?打开StdAfx.h文件,在文件最开始加入“#define _WIN32_WINNT 0x0501”就ok了,也就是设置为WindowsXP。再编译LockWorkStation函数就通过了!!!
晕呀,怎么GetListBoxInfo函数还是不能编译通过???还是“undeclared identifier”,难道LockWorkStation是“这个可以有”,而GetListBoxInfo是“这个真没有”吗?搞技术的不信邪,慢慢琢磨,是不是还是有其他的宏定义控制的条件编译呢?顺着GetListBoxInfo的定义向上搜“#if”,终于发现这么一句“#if(WINVER >= 0x0500)”,WINVER是什么宏呢?也是表示Windows的版本,可取值列表如下:
代码:
Windows 95、98 and Windows NT 4.0 WINVER=0x0400
Windows 98 and Windows 2000 WINVER=0x0500
Windows 2000 WINVER=0x0500
Windows xp WINVER=0x0501
有同学问,怎么微软还弄了_WIN32_WINNT、WINVER两个宏来表示Windows版本呢?详见这篇文章,我就不详细讲了:
http://student.csdn.net/link.php?url=http://blogs.msdn.com%2Foldnewthing%2Farchive%2F2007%2F04%2F11%2F2079137.aspx
引用:
The WINVER symbol is the earliest one. That's the symbol that 16-bit Windows used to control the versioning of its header files, and its use carried forward into the 32-bit header files, presumably from the people who did the initial conversion of the header files to 32-bit and who grew up with the WINVER symbol. This symbol is still used a lot in the header files that can trace their origins to 16-bit Windows, such as winuser.h, wingdi.h, and mmsystem.h.
The _WIN32_WINNT symbol came next. I'm not sure where it came from, but from its name it probably was invented by the Windows NT team in order to allow them to block off sections of the header file that are available only in the Windows NT implementation of Win32. Don't forget that in the early days, there was also Win32s, a subset of Win32 that could run on 16-bit Windows 3.1. The single WINVER symbol wasn't enough to specify exactly what you wanted to be compatible with. For example, a function available only in Windows NT 3.1 would be guarded with #if _WIN32_WINNT >= 0x030A so that programs that wanted to run on Win32s could set _WIN32_WINNT to zero and keep that function off-limits.
Similarly, both Windows 95 and Windows NT 4 identified themselves as Windows major version 4, so the WINVER symbol was insufficient to distinguish them. Functions that existed in Windows NT 4 but not in Window 95 were therefore guarded with _WIN32_WINNT.
On the other hand, there were also functions that were first introduced in Windows 95 and did not exist in the original version of Windows NT 4. The _WIN32_WINDOWS symbol let you specify that you wanted access to stuff that was new for Windows 95 and which would also be ported to Windows NT 4 and future versions of Windows NT.
除了_WIN32_WINNT、WINVER这两个宏,还有一个重要的宏_WIN32_IE,显而易见,它表示IE的版本,可选值如下:
代码:
Internet Explorer 3.0 _WIN32_IE=0x0300
Internet Explorer 4.0 _WIN32_IE=0x0400
Internet Explorer 5.0 _WIN32_IE=0x0500
Internet Explorer 6.0 _WIN32_IE=0x0600
总结一下,为了避免麻烦,最好每次新建项目的时候把下面几个宏定义加到StdAfx.h中,这样就免除了后顾之忧:
代码:
#define _WIN32_WINNT 0x0501
#define _WIN32_IE 0x0600
#define WINVER 0x0501
有同学问:
引用:
你给的这些宏的数值可以更改吗?按照我上面搜集的资料,vista系统的应该是:
_WIN32_WINNT>=0x0600
WINVER>=0x0600
为何你给的那些数还要小呢?
当然可以改,因为我的电脑是xp,所以我设的是0x0600。其实VC6中设成0x0500以上的任意值已经没区别,因为翻遍了VC6中所有的头文件没有发现依赖于0x0501以上的函数,很简单,VC6第一个版本发布的的时候是1998年,而VC6配套的SDK头文件最新的版本发布的时候还只有Windows2000,那时候根本没有WindowsXP、Vista这些东西,所以哪怕 _WIN32_WINNT设成0x0900都行,只不过没意义,VC6下设成0x0500就足够了。