常见控制版本

本主题列出了 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 的修补程序编号,该修补程序提供了比较版本号的更可靠方法。 由于 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.
}

Project版本

为了确保应用程序与.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。 若要定义其他值,可以将以下内容添加到生成文件中的编译器指令;将所需版本号替换为0x0400。

/D _WIN32_IE=0x0400

另一种方法是在包含 Shell 头文件之前,在源代码中添加类似于以下内容的行。 将所需的版本号替换为0x0400。

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

关于通用控件