VC6中使用高版本系统API的方法
生活随笔
收集整理的這篇文章主要介紹了
VC6中使用高版本系统API的方法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
有同學(xué)在如鵬論壇提問,在VC6中使用GetListBoxInfo這個API函數(shù)的時候編譯提示: 'GetListBoxInfo' : undeclared identifier
詳見:http://student.csdn.net/link.php?url=http://www.rupeng.com%2Fforum%2Fthread-3214-1-1.html
他已經(jīng)將GetListBoxInfo所在的頭文件WinUser.h直接或者間接的包含進(jìn)來了,打開WinUser.h文件,看到GetListBoxInfo就活生生的躺在那里呢,為什么還是報“'GetListBoxInfo' : undeclared identifier”呢?難道VC眼瞎了嗎???
一開始就解決GetListBoxInfo的這個問題可能比較麻煩,咱們先來看另外一個API函數(shù):LockWorkStation,他就在GetListBoxInfo函數(shù)的定義下面: 復(fù)制內(nèi)容到剪貼板
我們仔細(xì)看LockWorkStation函數(shù)的定義,看更大范圍的: 復(fù)制內(nèi)容到剪貼板
WINUSERAPI
BOOL
WINAPI
LockWorkStation(
? ? VOID);
#endif /* _WIN32_WINNT >= 0x0500 */對C/C++比較熟悉的同學(xué)應(yīng)該知道“#if”是條件編譯的意思,也就是說被“#if”、“#endif”包圍的代碼只有滿足“#if”的條件的時候才會被編譯,這個if判斷是在編譯的時候執(zhí)行的,而不是運(yùn)行的時候執(zhí)行的。
_WIN32_WINNT是一個宏定義,它表示W(wǎng)indows的版本,它有很多取值,取值列表如下: 復(fù)制內(nèi)容到剪貼板
Windows 2000? ?_WIN32_WINNT>=0x0500? ???
Windows NT 4.0??_WIN32_WINNT>=0x0400? ???因此“#if(_WIN32_WINNT >= 0x0500)”這句話的意思是只有Windows的版本大于Windows 2000 的時候LockWorkStation函數(shù)的定義才會起作用,才會被編譯。
為什么要根據(jù)操作系統(tǒng)的版本決定函數(shù)的定義是否編譯呢?道理很簡單,因為有的API函數(shù)是高版本的Windows下才提供的,低版本的Windows沒有那個API函數(shù),所以需要根據(jù)操作系統(tǒng)進(jìn)行判斷。
不對呀!我的操作系統(tǒng)是WindowsXP,確實比Windows 2000高呀,為什么不能編譯呢?
原因就是“_WIN32_WINNT”并不是像大家想象的那樣真的會代表當(dāng)前編譯程序電腦的操作系統(tǒng)的版本,它需要程序員去指定,當(dāng)然VC也給了“_WIN32_WINNT”一個默認(rèn)值,不過這個默認(rèn)值是VC從微軟那發(fā)布的時候微軟定義的: 復(fù)制內(nèi)容到剪貼板
#define _WIN32_WINNT 0x0400
#endifVC6是1998年發(fā)布的,那時候Windows98剛發(fā)布,微軟當(dāng)時肯定認(rèn)為大部分人還是Windows? ?NT? ?4.0操作系統(tǒng),為了“主流”,微軟就把VC6中_WIN32_WINNT宏的默認(rèn)值設(shè)置成了Windows NT 4.0的0x0400。
時光荏苒,日月如梭,現(xiàn)在已經(jīng)是2009年了,主流的Windows桌面操作系統(tǒng)已經(jīng)是WindowsXP了,還有相當(dāng)一部分人用上了Vista甚至Windows7,那么“ _WIN32_WINNT 0x0400”這個默認(rèn)值已經(jīng)Out了!
那么咱們怎么修改_WIN32_WINNT的默認(rèn)值呢?打開StdAfx.h文件,在文件最開始加入“#define _WIN32_WINNT 0x0501”就ok了,也就是設(shè)置為WindowsXP。再編譯LockWorkStation函數(shù)就通過了!!!
暈呀,怎么GetListBoxInfo函數(shù)還是不能編譯通過???還是“undeclared identifier”,難道LockWorkStation是“這個可以有”,而GetListBoxInfo是“這個真沒有”嗎?搞技術(shù)的不信邪,慢慢琢磨,是不是還是有其他的宏定義控制的條件編譯呢?順著GetListBoxInfo的定義向上搜“#if”,終于發(fā)現(xiàn)這么一句“#if(WINVER >= 0x0500)”,WINVER是什么宏呢?也是表示W(wǎng)indows的版本,可取值列表如下: 復(fù)制內(nèi)容到剪貼板
Windows 98 and Windows 2000? ?? ?? ?WINVER=0x0500? ???
Windows 2000? ?? ?? ?? ?? ?? ?? ?? ?? ???WINVER=0x0500
Windows xp? ?? ?? ?? ?? ?? ?? ?? ?? ???WINVER=0x0501??估計WINVER還是和_WIN32_WINNT一樣的問題,因此我們同樣打開StdAfx.h文件,在文件最開始加入“#define WINVER??0x0501”就ok了,也就是設(shè)置為WindowsXP。再編譯GetListBoxInfo函數(shù)就通過了!!!
有同學(xué)問,怎么微軟還弄了_WIN32_WINNT、WINVER兩個宏來表示W(wǎng)indows版本呢?詳見這篇文章,我就不詳細(xì)講了:
http://student.csdn.net/link.php?url=http://blogs.msdn.com%2Foldnewthing%2Farchive%2F2007%2F04%2F11%2F2079137.aspx
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. 我承認(rèn)我很卑鄙,在這等著你們呢。我相信80%的同學(xué)跳過了剛才我貼的這段英文,“全是英文,密密麻麻,不看了”,就像上面這段英文像梵文一樣你看不懂。呵呵。學(xué)計算機(jī)的要鍛煉自己閱讀英文資料的能力,所以請?zhí)^這段文章的同學(xué)現(xiàn)在回去讀一讀,“浪子回頭金不換”!每個閱讀的同學(xué)都把它翻譯出來,最好落實到紙面上。
除了_WIN32_WINNT、WINVER這兩個宏,還有一個重要的宏_WIN32_IE,顯而易見,它表示IE的版本,可選值如下: 復(fù)制內(nèi)容到剪貼板
Internet Explorer 4.0? ?_WIN32_IE=0x0400? ?? ?
Internet Explorer 5.0? ?_WIN32_IE=0x0500? ?
Internet Explorer 6.0??_WIN32_IE=0x0600? ?有部分函數(shù)也是依賴于IE的版本進(jìn)行條件編譯的,因此最好也把_WIN32_IE設(shè)置為0x0600。
總結(jié)一下,為了避免麻煩,最好每次新建項目的時候把下面幾個宏定義加到StdAfx.h中,這樣就免除了后顧之憂: 復(fù)制內(nèi)容到剪貼板
#define _WIN32_IE 0x0600??
#define WINVER??0x0501我也考慮更新“如鵬版對話框程序生成向?qū)А?#xff08;Rupeng DialogBased Application wizard),把上面的宏定義自動加到StdAfx.h中,在“如鵬版對話框程序生成向?qū)А鄙壷巴瑢W(xué)們先手動加吧。
有同學(xué)問:
你給的這些宏的數(shù)值可以更改嗎?按照我上面搜集的資料,vista系統(tǒng)的應(yīng)該是:
? ?_WIN32_WINNT>=0x0600
? ? WINVER>=0x0600
為何你給的那些數(shù)還要小呢?
詳見:http://student.csdn.net/link.php?url=http://www.rupeng.com%2Fforum%2Fthread-3214-1-1.html
他已經(jīng)將GetListBoxInfo所在的頭文件WinUser.h直接或者間接的包含進(jìn)來了,打開WinUser.h文件,看到GetListBoxInfo就活生生的躺在那里呢,為什么還是報“'GetListBoxInfo' : undeclared identifier”呢?難道VC眼瞎了嗎???
一開始就解決GetListBoxInfo的這個問題可能比較麻煩,咱們先來看另外一個API函數(shù):LockWorkStation,他就在GetListBoxInfo函數(shù)的定義下面: 復(fù)制內(nèi)容到剪貼板
代碼:
WINUSERAPI??BOOL WINAPI??LockWorkStation(VOID);這個函數(shù)用來鎖定操作系統(tǒng)。LockWorkStation安靜的的躺在WinUser.h中,按理來說應(yīng)該能輕松的調(diào)用,因此我在文件中調(diào)用LockWorkStation卻無情的報告了“LockWorkStation undeclared identifier”。為什么呢?我們仔細(xì)看LockWorkStation函數(shù)的定義,看更大范圍的: 復(fù)制內(nèi)容到剪貼板
代碼:
#if(_WIN32_WINNT >= 0x0500)WINUSERAPI
BOOL
WINAPI
LockWorkStation(
? ? VOID);
#endif /* _WIN32_WINNT >= 0x0500 */對C/C++比較熟悉的同學(xué)應(yīng)該知道“#if”是條件編譯的意思,也就是說被“#if”、“#endif”包圍的代碼只有滿足“#if”的條件的時候才會被編譯,這個if判斷是在編譯的時候執(zhí)行的,而不是運(yùn)行的時候執(zhí)行的。
_WIN32_WINNT是一個宏定義,它表示W(wǎng)indows的版本,它有很多取值,取值列表如下: 復(fù)制內(nèi)容到剪貼板
代碼:
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函數(shù)的定義才會起作用,才會被編譯。
為什么要根據(jù)操作系統(tǒng)的版本決定函數(shù)的定義是否編譯呢?道理很簡單,因為有的API函數(shù)是高版本的Windows下才提供的,低版本的Windows沒有那個API函數(shù),所以需要根據(jù)操作系統(tǒng)進(jìn)行判斷。
不對呀!我的操作系統(tǒng)是WindowsXP,確實比Windows 2000高呀,為什么不能編譯呢?
原因就是“_WIN32_WINNT”并不是像大家想象的那樣真的會代表當(dāng)前編譯程序電腦的操作系統(tǒng)的版本,它需要程序員去指定,當(dāng)然VC也給了“_WIN32_WINNT”一個默認(rèn)值,不過這個默認(rèn)值是VC從微軟那發(fā)布的時候微軟定義的: 復(fù)制內(nèi)容到剪貼板
代碼:
#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0400
#endifVC6是1998年發(fā)布的,那時候Windows98剛發(fā)布,微軟當(dāng)時肯定認(rèn)為大部分人還是Windows? ?NT? ?4.0操作系統(tǒng),為了“主流”,微軟就把VC6中_WIN32_WINNT宏的默認(rèn)值設(shè)置成了Windows NT 4.0的0x0400。
時光荏苒,日月如梭,現(xiàn)在已經(jīng)是2009年了,主流的Windows桌面操作系統(tǒng)已經(jīng)是WindowsXP了,還有相當(dāng)一部分人用上了Vista甚至Windows7,那么“ _WIN32_WINNT 0x0400”這個默認(rèn)值已經(jīng)Out了!
那么咱們怎么修改_WIN32_WINNT的默認(rèn)值呢?打開StdAfx.h文件,在文件最開始加入“#define _WIN32_WINNT 0x0501”就ok了,也就是設(shè)置為WindowsXP。再編譯LockWorkStation函數(shù)就通過了!!!
暈呀,怎么GetListBoxInfo函數(shù)還是不能編譯通過???還是“undeclared identifier”,難道LockWorkStation是“這個可以有”,而GetListBoxInfo是“這個真沒有”嗎?搞技術(shù)的不信邪,慢慢琢磨,是不是還是有其他的宏定義控制的條件編譯呢?順著GetListBoxInfo的定義向上搜“#if”,終于發(fā)現(xiàn)這么一句“#if(WINVER >= 0x0500)”,WINVER是什么宏呢?也是表示W(wǎng)indows的版本,可取值列表如下: 復(fù)制內(nèi)容到剪貼板
代碼:
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了,也就是設(shè)置為WindowsXP。再編譯GetListBoxInfo函數(shù)就通過了!!!
有同學(xué)問,怎么微軟還弄了_WIN32_WINNT、WINVER兩個宏來表示W(wǎng)indows版本呢?詳見這篇文章,我就不詳細(xì)講了:
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. 我承認(rèn)我很卑鄙,在這等著你們呢。我相信80%的同學(xué)跳過了剛才我貼的這段英文,“全是英文,密密麻麻,不看了”,就像上面這段英文像梵文一樣你看不懂。呵呵。學(xué)計算機(jī)的要鍛煉自己閱讀英文資料的能力,所以請?zhí)^這段文章的同學(xué)現(xiàn)在回去讀一讀,“浪子回頭金不換”!每個閱讀的同學(xué)都把它翻譯出來,最好落實到紙面上。
除了_WIN32_WINNT、WINVER這兩個宏,還有一個重要的宏_WIN32_IE,顯而易見,它表示IE的版本,可選值如下: 復(fù)制內(nèi)容到剪貼板
代碼:
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? ?有部分函數(shù)也是依賴于IE的版本進(jìn)行條件編譯的,因此最好也把_WIN32_IE設(shè)置為0x0600。
總結(jié)一下,為了避免麻煩,最好每次新建項目的時候把下面幾個宏定義加到StdAfx.h中,這樣就免除了后顧之憂: 復(fù)制內(nèi)容到剪貼板
代碼:
#define _WIN32_WINNT 0x0501#define _WIN32_IE 0x0600??
#define WINVER??0x0501我也考慮更新“如鵬版對話框程序生成向?qū)А?#xff08;Rupeng DialogBased Application wizard),把上面的宏定義自動加到StdAfx.h中,在“如鵬版對話框程序生成向?qū)А鄙壷巴瑢W(xué)們先手動加吧。
有同學(xué)問:
引用:
你給的這些宏的數(shù)值可以更改嗎?按照我上面搜集的資料,vista系統(tǒng)的應(yīng)該是:
? ?_WIN32_WINNT>=0x0600
? ? WINVER>=0x0600
為何你給的那些數(shù)還要小呢?
當(dāng)然可以改,因為我的電腦是xp,所以我設(shè)的是0x0600。其實VC6中設(shè)成0x0500以上的任意值已經(jīng)沒區(qū)別,因為翻遍了VC6中所有的頭文件沒有發(fā)現(xiàn)依賴于0x0501以上的函數(shù),很簡單,VC6第一個版本發(fā)布的的時候是1998年,而VC6配套的SDK頭文件最新的版本發(fā)布的時候還只有Windows2000,那時候根本沒有WindowsXP、Vista這些東西,所以哪怕 _WIN32_WINNT設(shè)成0x0900都行,只不過沒意義,VC6下設(shè)成0x0500就足夠了。
?
?
?
總結(jié)
以上是生活随笔為你收集整理的VC6中使用高版本系统API的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 调用cmd执行指令
- 下一篇: Word 2007中隐藏段落和格式标记