严格合规性

启用 STRICT 类型检查时,某些成功编译的源代码可能会生成错误消息。 以下各节介绍启用 STRICT 时进行代码编译的最低要求。 建议执行其他步骤,尤其是在生成可移植代码时。

一般要求

主要要求是必须声明正确的句柄类型和函数指针,而不是依赖于更常规的类型。 不能在预期使用另一种句柄类型的情况下使用一种句柄类型。 这也意味着可能需要更改函数声明并使用更多类型强制转换。

为了获得最佳结果,应仅在必要时使用泛型 HANDLE 类型。

在应用程序中声明函数

请确保已声明所有应用程序函数。 建议将所有函数声明放在包含文件中,因为可以轻松扫描声明并查找应更改的参数和返回类型。

如果使用 /Zg 编译器选项为函数创建头文件,请记住,将得到不同的结果,具体取决于是否启用了 STRICT 类型检查。 禁用 STRICT 后,所有句柄类型都会生成相同的基类型。 启用 STRICT 后,它们会生成不同的基类型。 为了避免冲突,需要在每次启用或禁用 STRICT 时重新创建头文件,或者编辑头文件以使用 类型 HWNDHDCHANDLE 等,而不是基类型。

从 Windows.h 复制到源代码中的任何函数声明都可能已更改,并且本地声明可能已过期。 删除本地声明。

需要强制转换的类型

某些函数具有泛型返回类型或参数。 例如, SendMessage 函数返回的数据可以是任意数量的类型,具体取决于上下文。 当你在源代码中看到这些函数中的任何一个时,请确保使用正确的类型强制转换,并且它尽可能具体。 以下列表是这些函数的示例。

调用 SendMessageDefWindowProcSendDlgItemMessage 时,应首先将结果强制转换为 类型UINT_PTR。 对于任何返回 LRESULTLONG_PTR 值的函数,都需要执行类似的步骤,其中结果包含句柄。 这是编写可移植代码所必需的,因为句柄的大小因 Windows 版本而异。 强制转换 (UINT_PTR) 可确保正确转换。 下面的代码演示了一个示例,其中 SendMessage 向画笔返回句柄:

HBRUSH hbr;

hbr = (HBRUSH)(UINT_PTR)SendMessage(hwnd, WM_CTLCOLOR, ..., ...);

CreateWindowCreateWindowEx 参数 hmenu 有时用于传递整数控件标识符 (ID) 。 在这种情况下,必须将 ID 强制转换为 HMENU 类型:

HWND hwnd;
int id;

hwnd = CreateWindow(
        TEXT("Button"), TEXT("OK"), BS_PUSHBUTTON,
        x, y, cx, cy, hwndParent,
        (HMENU)id,    // Cast required here
        hinst,
        NULL);

其他注意事项

若要从 STRICT 类型检查中获得最大好处,应遵循其他准则。 如果进行以下更改,代码在 Windows 的未来版本中将更具可移植性。

类型 WPARAMLPARAMLRESULTLPVOID多态数据类型。 它们在不同时间保存不同类型的数据,即使启用了 STRICT 类型检查也是如此。 若要获得类型检查的好处,应尽快强制转换这些类型的值。 (请注意,消息破解程序会自动以可移植的方式为你重新生成 wParamlParam 。)

请特别注意区分 HMODULEHINSTANCE 类型。 即使启用了 STRICT ,它们也定义为相同的基类型。 大多数内核模块管理功能使用 HINSTANCE 类型,但有一些函数仅返回或接受 HMODULE 类型。

禁用 STRICT

启用 STRICT