有同学在如鹏论坛提问,在VC6中使用GetListBoxInfo这个API函数的时候编译提示: 'GetListBoxInfo' : undeclared identifier
详见: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安静的的躺在WinUser.h中,按理来说应该能轻松的调用,因此我在文件中调用LockWorkStation却无情的报告了“LockWorkStation undeclared identifier”。为什么呢?
我们仔细看LockWorkStation函数的定义,看更大范围的:

复制内容到剪贴板

代码:

#if(_WIN32_WINNT >= 0x0500)
WINUSERAPI
BOOL
WINAPI
LockWorkStation(
    VOID);
#endif /* _WIN32_WINNT >= 0x0500 */

对C/C++比较熟悉的同学应该知道“#if”是条件编译的意思,也就是说被“#if”、“#endif”包围的代码只有满足“#if”的条件的时候才会被编译,这个if判断是在编译的时候执行的,而不是运行的时候执行的。

_WIN32_WINNT是一个宏定义,它表示Windows的版本,它有很多取值,取值列表如下:

复制内容到剪贴板

代码:

Windows XP   _WIN32_WINNT>=0x0501     
Windows 2000   _WIN32_WINNT>=0x0500     
Windows NT 4.0  _WIN32_WINNT>=0x0400     

因此“#if(_WIN32_WINNT >= 0x0500)”这句话的意思是只有Windows的版本大于Windows 2000 的时候LockWorkStation函数的定义才会起作用,才会被编译。
为什么要根据操作系统的版本决定函数的定义是否编译呢?道理很简单,因为有的API函数是高版本的Windows下才提供的,低版本的Windows没有那个API函数,所以需要根据操作系统进行判断。

不对呀!我的操作系统是WindowsXP,确实比Windows 2000高呀,为什么不能编译呢?
原因就是“_WIN32_WINNT”并不是像大家想象的那样真的会代表当前编译程序电脑的操作系统的版本,它需要程序员去指定,当然VC也给了“_WIN32_WINNT”一个默认值,不过这个默认值是VC从微软那发布的时候微软定义的:

复制内容到剪贴板

代码:

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif

VC6是1998年发布的,那时候Windows98刚发布,微软当时肯定认为大部分人还是Windows   NT   4.0操作系统,为了“主流”,微软就把VC6中_WIN32_WINNT宏的默认值设置成了Windows NT 4.0的0x0400。

时光荏苒,日月如梭,现在已经是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  

估计WINVER还是和_WIN32_WINNT一样的问题,因此我们同样打开StdAfx.h文件,在文件最开始加入“#define WINVER  0x0501”就ok了,也就是设置为WindowsXP。再编译GetListBoxInfo函数就通过了!!!
有同学问,怎么微软还弄了_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.

我承认我很卑鄙,在这等着你们呢。我相信80%的同学跳过了刚才我贴的这段英文,“全是英文,密密麻麻,不看了”,就像上面这段英文像梵文一样你看不懂。呵呵。学计算机的要锻炼自己阅读英文资料的能力,所以请跳过这段文章的同学现在回去读一读,“浪子回头金不换”!每个阅读的同学都把它翻译出来,最好落实到纸面上。
除了_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   

有部分函数也是依赖于IE的版本进行条件编译的,因此最好也把_WIN32_IE设置为0x0600。
总结一下,为了避免麻烦,最好每次新建项目的时候把下面几个宏定义加到StdAfx.h中,这样就免除了后顾之忧:

复制内容到剪贴板

代码:

#define _WIN32_WINNT 0x0501
#define _WIN32_IE 0x0600  
#define WINVER  0x0501

我也考虑更新“如鹏版对话框程序生成向导”(Rupeng DialogBased Application wizard),把上面的宏定义自动加到StdAfx.h中,在“如鹏版对话框程序生成向导”升级之前同学们先手动加吧。

有同学问:

引用:

你给的这些宏的数值可以更改吗?按照我上面搜集的资料,vista系统的应该是:
   _WIN32_WINNT>=0x0600
    WINVER>=0x0600

为何你给的那些数还要小呢?

当然可以改,因为我的电脑是xp,所以我设的是0x0600。其实VC6中设成0x0500以上的任意值已经没区别,因为翻遍了VC6中所有的头文件没有发现依赖于0x0501以上的函数,很简单,VC6第一个版本发布的的时候是1998年,而VC6配套的SDK头文件最新的版本发布的时候还只有Windows2000,那时候根本没有WindowsXP、Vista这些东西,所以哪怕 _WIN32_WINNT设成0x0900都行,只不过没意义,VC6下设成0x0500就足够了。

VC6中使用高版本系统API的方法相关推荐

  1. 详解在Visual Studio中使用git版本系统 [转]

    详解在Visual Studio中使用git版本系统    作者:掷鸡蛋者 , 发布于2012-6-21   这篇教程的预期,是希望没有任何版本使用基础的新手也可以掌握,所以细节较多,不当之处,欢迎指 ...

  2. 申威 linux内核,一种申威防火墙快速移植高版本linux内核的方法与流程

    技术特征: 1.一种申威防火墙快速移植高版本linux内核的方法,其特征在于,包括以下步骤: s1:预先制作生成内存根文件系统的压缩文件: 所述步骤s1包括以下步骤: s11:通过编译busybox制 ...

  3. iis10.0 php多版本,IIS7 IIS8 中多个版本php共存的方法

    最近又重回.net,用回IIS.然后用到某个php开源项目,需要低版本的php,之前装的一个php5.5不能用,所以决定降一下版本,后面发现其实可以多个版本共用.于是打算分享下.分享之前网上先搜了下, ...

  4. 高版本自动接听电话方法

    原文地址:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=894679&page=1&_dsign=b92c470 ...

  5. 在visual studio中使用git版本系统(zz)

    第一部分: 安装 git 开发工具 如果要使用 git 进行版本管理,其实使用 git 命令行工具就完全足够了,图形化工具(无论是 git extentions ,还是TortoiseGit),都只不 ...

  6. 详解在visual studio中使用git版本系统(图文)

    第一部分: 安装 git 开发工具 如果要使用 git 进行版本管理,其实使用 git 命令行工具就完全足够了,图形化工具(无论是 git extentions ,还是TortoiseGit),都只不 ...

  7. 微博在大规模、高负载系统问题排查方法

    为什么80%的码农都做不了架构师?>>>    2015-08-05 秦迪 高可用架构 此文根据[QCON高可用架构群]分享内容,由群内[编辑组]志愿整理,转发请注明出处. 秦迪,微 ...

  8. 高并发系统—通用设计方法

    文章出自:阿里巴巴十亿级并发系统设计(2021版) 链接:https://pan.baidu.com/s/1lbqQhDWjdZe1CBU-6U4jhA 提取码:8888 我们知道,高并发代表着大流量 ...

  9. SAP中多生产版本系统应用选择规则

    企业生产同一个产品,可能存在多个有效生产版本,分别对应不同的物料清单和工艺路线.生产版本应用于MRP运行,成本核算中,生产执行等业务中.在应用时用户需要知道,如果不进行手动选择,在默认情况下,系统选择 ...

最新文章

  1. makefile跨平台,动态库,静态库
  2. 两个音轨合并_两个双音轨mkv视频合并保持原双音轨不变 MKV怎么合并视频,合并之后仍保留MKV的双音轨...
  3. Python笔记-XPath定位
  4. 字节数组和字符串的相互转化……
  5. php sphinx 查询,php-Sphinx RT索引和SphinxQL查询
  6. web 富文本编辑器总结
  7. 谁“玩死了”共享单车?
  8. python3--列表生成式
  9. JAVA中的GUI---swing 和awt
  10. android版本升级功能,手机安卓系统怎么升级 安卓系统更新升级的三种方法介绍...
  11. Eclipse修改jsp模板
  12. 计算机工控机配置,研华工控机最新配置IPC-610
  13. 算法/贪心算法/FractionalKnapsack部分背包问题
  14. 空间大数据是什么,与云计算和大数据之间有什么关系?
  15. 一张图看懂阿里云ACK
  16. 20种让你更高效的科学学习方法
  17. 训练指南 UVALive - 4043(二分图匹配 + KM算法)
  18. [SHOI2008]小约翰的游戏 题解
  19. 《我的菜谱》-西红柿炒鸡蛋
  20. CRM为3Com带来什么?

热门文章

  1. 【杂谈】为了让大家学好深度学习模型设计和优化,有三AI都做了什么
  2. 全球及中国煤层气开发产业运营规模与十四五战略决策建议报告2022版
  3. 全球及中国多非利特原料药行业发展模式分析及投资前景规划报告2022-2027年版
  4. 关于项目进度慢的思考----如何提高整体开发效率
  5. 有米android sdk,有米积分墙Android SDK开发者常见问题
  6. Visual Studio Code搭建TypeScript开发环境
  7. [再寄小读者之数学篇](2014-06-22 求导数 [中国科学技术大学2014年高等数学B考研试题])...
  8. 虚拟机windows xp 下安装配置mysql cluster 7.3.2
  9. WinCE驱动编写小结(转载)
  10. 怎么还不见2005的中文版出来的?