严格合规性
启用 STRICT 类型检查时,某些成功编译的源代码可能会生成错误消息。 以下各节介绍启用 STRICT 时进行代码编译的最低要求。 建议执行其他步骤,尤其是在生成可移植代码时。
一般要求
主要要求是必须声明正确的句柄类型和函数指针,而不是依赖于更常规的类型。 不能在预期使用另一种句柄类型的情况下使用一种句柄类型。 这也意味着可能需要更改函数声明并使用更多类型强制转换。
为了获得最佳结果,应仅在必要时使用泛型 HANDLE 类型。
在应用程序中声明函数
请确保已声明所有应用程序函数。 建议将所有函数声明放在包含文件中,因为可以轻松扫描声明并查找应更改的参数和返回类型。
如果使用 /Zg 编译器选项为函数创建头文件,请记住,将得到不同的结果,具体取决于是否启用了 STRICT 类型检查。 禁用 STRICT 后,所有句柄类型都会生成相同的基类型。 启用 STRICT 后,它们会生成不同的基类型。 为了避免冲突,需要在每次启用或禁用 STRICT 时重新创建头文件,或者编辑头文件以使用 类型 HWND、 HDC、 HANDLE 等,而不是基类型。
从 Windows.h 复制到源代码中的任何函数声明都可能已更改,并且本地声明可能已过期。 删除本地声明。
需要强制转换的类型
某些函数具有泛型返回类型或参数。 例如, SendMessage 函数返回的数据可以是任意数量的类型,具体取决于上下文。 当你在源代码中看到这些函数中的任何一个时,请确保使用正确的类型强制转换,并且它尽可能具体。 以下列表是这些函数的示例。
调用 SendMessage、 DefWindowProc 或 SendDlgItemMessage 时,应首先将结果强制转换为 类型UINT_PTR。 对于任何返回 LRESULT 或 LONG_PTR 值的函数,都需要执行类似的步骤,其中结果包含句柄。 这是编写可移植代码所必需的,因为句柄的大小因 Windows 版本而异。 强制转换 (UINT_PTR) 可确保正确转换。 下面的代码演示了一个示例,其中 SendMessage 向画笔返回句柄:
HBRUSH hbr;
hbr = (HBRUSH)(UINT_PTR)SendMessage(hwnd, WM_CTLCOLOR, ..., ...);
CreateWindow 和 CreateWindowEx 参数 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 的未来版本中将更具可移植性。
类型 WPARAM、LPARAM、LRESULT 和 LPVOID 是多态数据类型。 它们在不同时间保存不同类型的数据,即使启用了 STRICT 类型检查也是如此。 若要获得类型检查的好处,应尽快强制转换这些类型的值。 (请注意,消息破解程序会自动以可移植的方式为你重新生成 wParam 和 lParam 。)
请特别注意区分 HMODULE 和 HINSTANCE 类型。 即使启用了 STRICT ,它们也定义为相同的基类型。 大多数内核模块管理功能使用 HINSTANCE 类型,但有一些函数仅返回或接受 HMODULE 类型。
相关主题