一般控制件版本

本主題列出 Common Control 連結庫 (ComCtl32.dll) 的可用版本,說明如何識別應用程式正在使用的版本,並說明如何將應用程式設為特定版本的目標。

本主題包含下列各節。

一般控制 DLL 版本號碼

一般控件的支援是由 ComCtl32.dll 提供,所有 32 位和 64 位版本的 Windows 都包含。 DLL 的每個後續版本都支援舊版的功能和 API,並新增新功能。

因為各種版本的 ComCtl32.dll是隨 Internet Explorer 一起散發的,所以使用中版本有時與操作系統隨附的版本不同。 因此,您的應用程式必須直接判斷ComCtl32.dll的版本存在。

在一般控件參考檔中,許多程式設計元素會指定最低支援的 DLL 版本號碼。 這個版本號碼表示除非另有指定,否則程式設計專案會實作在該版本和後續版本的 DLL 中。 如果未指定版本號碼,則程式設計專案會在所有現有的 DLL 版本中實作。

下表概述不同的 DLL 版本,以及如何在支援的 OS 上散發它們。

ComCtl32.dll

版本

發佈 平台

5.81

Microsoft Internet Explorer 5.01、Microsoft Internet Explorer 5.5 和 Microsoft Internet Explorer 6

5.82

Windows Server 2003、Windows Vista、Windows Server 2008 和 Windows 7

6.0

Windows Server 2003

6.10

Windows Vista、Windows Server 2008 和 Windows 7

 

不同通用控制項版本的結構大小

一般控件的持續增強功能導致需要擴充許多結構。 因此,結構的大小在不同版本的 Commctrl.h 之間已變更。 由於大部分常見的控件結構會採用結構大小做為其中一個參數,因此如果無法辨識大小,訊息或函式可能會失敗。 為了解決這個問題,已定義結構大小常數,以協助以不同版本的ComCtl32.dll為目標。 下列清單會定義結構大小常數。

結構大小常數 定義
HDITEM_V1_SIZE 4.0 版中的 HDITEM 結構大小
IMAGELISTDRAWPARAMS_V3_SIZE 5.9 版中 IMAGELISTDRAWPARAMS 結構的大小
LVCOLUMN_V1_SIZE 4.0 版中 LVCOLUMN 結構的大小
LVGROUP_V5_SIZE 6.0 版中 LVGROUP 結構的大小
LVHITTESTINFO_V1_SIZE 4.0 版中 LVHITTESTINFO 結構的大小
LVITEM_V1_SIZE 4.0 版中的 LVITEM 結構大小
LVITEM_V5_SIZE 6.0 版中 LVITEM 結構的大小
LVTILEINFO_V5_SIZE 6.0 版中 LVTILEINFO 結構的大小
MCHITTESTINFO_V1_SIZE 4.0 版中的 MCHITTESTINFO 結構大小
NMLVCUSTOMDRAW_V3_SIZE 4.7 版中的 NMLVCUSTOMDRAW 結構大小
NMTTDISPINFO_V1_SIZE 4.0 版中的NMTTDISPINFO結構大小
NMTVCUSTOMDRAW_V3_SIZE 4.7 版中的NMTVCUSTOMDRAW結構大小
PROPSHEETHEADER_V1_SIZE 4.0 版中的 PROPSHEETHEADER 結構大小。
PROPSHEETPAGE_V1_SIZE 4.0 版中的 PROPSHEETPAGE 結構大小
REBARBANDINFO_V3_SIZE 4.7 版中的 REBARBANDINFO 結構大小
REBARBANDINFO_V6_SIZE 6.0 版中的 REBARBANDINFO 結構大小
TTTOOLINFO_V1_SIZE 4.0 版 TOOLINFO 結構的大小
TTTOOLINFO_V2_SIZE 4.7 版 TOOLINFO 結構的大小
TTTOOLINFO_V3_SIZE 6.0 版的 TOOLINFO 結構大小
TVINSERTSTRUCT_V1_SIZE 4.0 版中的TVINSERTSTRUCT結構大小

 

使用 DllGetVersion 判斷版本號碼

應用程式可以呼叫 DllGetVersion 函式,以判斷系統上存在的 DLL 版本。

DllGetVersion 會傳回DLLVERSIONINFO2結構。 除了透過 DLLVERSIONINFO 提供的資訊之外,DLLVERSIONINFO2也提供可識別最新安裝 Service Pack 的 Hotfix 編號,以提供更健全的方式來比較版本號碼。 由於DLLVERSIONINFO2的第一個成員是 DLLVERSIONINFO 結構,因此較新的結構與回溯相容。

下列範例函式 GetVersion 會載入指定的 DLL,並嘗試呼叫其 DllGetVersion 函式。 如果成功,它會使用宏,將 DLLVERSIONINFO 結構中的主要和次要版本號碼封裝成傳回給呼叫應用程式的 DWORD 如果 DLL 未匯出 DllGetVersion,函式會傳回零。 您可以修改 函式來處理 DllGetVersion 傳回DLLVERSIONINFO2結構的可能性 如果是,請使用該 DLLVERSIONINFO2 結構的 ullVersion 成員中的資訊來比較版本、組建編號和 Service Pack 版本。 MAKEDLLVERULL 宏可簡化將這些值與 ullVersion比較的工作。

注意

不正確地使用 LoadLibrary 可能會造成安全性風險。 如需 有關如何以不同 Windows 版本正確載入 DLL 的資訊,請參閱 LoadLibrary 檔。

 

#include "stdafx.h"
#include "windows.h"
#include "windef.h"
#include "winbase.h"
#include "shlwapi.h"

#define PACKVERSION(major,minor) MAKELONG(minor,major)

DWORD GetVersion(LPCTSTR lpszDllName)
{
    HINSTANCE hinstDll;
    DWORD dwVersion = 0;

    // For security purposes, LoadLibrary should be provided with a fully qualified 
    // path to the DLL. The lpszDllName variable should be tested to ensure that it 
    // is a fully qualified path before it is used. 
    hinstDll = LoadLibrary(lpszDllName);
    
    if(hinstDll)
    {
        DLLGETVERSIONPROC pDllGetVersion;
        pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");

        // Because some DLLs might not implement this function, you must test for 
        // it explicitly. Depending on the particular DLL, the lack of a DllGetVersion 
        // function can be a useful indicator of the version. 

        if(pDllGetVersion)
        {
            DLLVERSIONINFO dvi;
            HRESULT hr;

            ZeroMemory(&dvi, sizeof(dvi));
            dvi.info1.cbSize = sizeof(dvi);

            hr = (*pDllGetVersion)(&dvi);

            if(SUCCEEDED(hr))
            {
               dwVersion = PACKVERSION(dvi.info1.dwMajorVersion, dvi.info1.dwMinorVersion);
            }
        }
        FreeLibrary(hinstDll);
    }
    return dwVersion;
}

下列程式代碼範例示範如何使用 GetVersion 來測試ComCtl32.dll是 6.0 版或更新版本。

LPCTSTR lpszDllName = L"C:\\Windows\\System32\\ComCtl32.dll";
DWORD dwVer = GetVersion(lpszDllName);
DWORD dwTarget = PACKVERSION(6,0);

if(dwVer >= dwTarget)
{
    // This version of ComCtl32.dll is version 6.0 or later.
}
else
{
    // Proceed knowing that version 6.0 or later additions are not available.
    // Use an alternate approach for older the DLL version.
}

專案版本

為了確保您的應用程式與.dll檔案的不同目標版本相容,版本宏會出現在頭檔中。 這些宏可用來定義、排除或重新定義不同 DLL 版本的特定定義。 如需這些宏的深入描述,請參閱 使用 Windows 標頭

例如,宏名稱 _WIN32_IE 通常位於較舊的標頭中。 您必須將宏定義為十六進位數位。 此版本號碼會定義使用 DLL 之應用程式的目標版本。 下表顯示可用的版本號碼,以及每個版本對應用程式的影響。

版本 描述
0x0300 應用程式與 ComCtl32.dll 4.70 版和更新版本相容。 應用程式無法實作在 4.70 版之後新增的功能。
0x0400 應用程式與 ComCtl32.dll 4.71 版和更新版本相容。 應用程式無法實作在 4.71 版之後新增的功能。
0x0401 應用程式與 ComCtl32.dll 4.72 版和更新版本相容。 應用程式無法實作在 4.72 版之後新增的功能。
0x0500 應用程式與 ComCtl32.dll 5.80 版和更新版本相容。 應用程式無法實作在 5.80 版之後新增的功能。
0x0501 應用程式與 ComCtl32.dll 5.81 版和更新版本相容。 應用程式無法實作在 5.81 版之後新增的功能。
0x0600 應用程式與 ComCtl32.dll 6.0 版和更新版本相容。 應用程式無法實作在 6.0 版之後新增的功能。

 

如果您未在專案中定義 _WIN32_IE 宏,它會自動定義為0x0500。 若要定義不同的值,您可以將下列內容新增至make檔案中的編譯程式指示詞;將所需的版本號碼取代為 0x0400。

/D _WIN32_IE=0x0400

另一種方法是在包含 Shell 頭檔之前,在原始程式碼中新增類似下列的一行。 將所需的版本號碼取代為 0x0400。

#define _WIN32_IE 0x0400
#include <commctrl.h>

關於通用控制件