4

对于 x64 目标构建,从“OLE_HANDLE”转换为“HICON”的正确方法是什么?

特别是对于普通的 C 样式转换,我在使用 x64 配置编译时收到此警告:

警告 C4312:“类型转换”:从“OLE_HANDLE”转换为更大尺寸的“HICON”

这是有问题的代码:

imgList.Add((HICON)ohIcon);

上面的代码对我来说很好,但我想在为 x64 构建时摆脱警告。

4

5 回答 5

6

H 放弃了它,在这种情况下,库代码创建了一个独特的类型,为您提供更多的类型安全性(在旧的 C API 时代)。

它们实际上都是 HANDLE,它是一个内核对象,并不真正关心资源是什么,只是你有它的“句柄”。记住 API 是 C 的,所以使用 C 风格转换,当你要删除它时,使用 DeleteObject()。

编辑:64 位嗯...问题是因为 MS 将句柄更新为 64 位,但留下了 OLE 的东西。幸运的是,他们所做的只是用零填充额外的位。

尝试使用LongToHandle 转换例程并查看MIDL 移植指南- 向下滚动到“USER 和 GDI 句柄是符号扩展 32b 值”部分。

于 2008-12-30T23:53:01.153 回答
4

假设您根据问题使用 Microsoft Visual Studio...

如果您仅针对 32 位目标进行开发,则可以选择通过关闭项目选项“检测 64 位可移植性问题”(C++ 编译器选项 /Wp64)来禁用此功能(以及一些其他类似的警告)。

如果您也在为 64 位目标进行开发,那么@Harper 可能是正确的,您需要更多地挖掘正确的方法来处理这个问题。您可能想阅读这份白皮书作为起点;转到有关 USER 和 GDI 句柄的部分。

于 2008-12-31T05:18:21.980 回答
1

我做了一点挖掘 - OLE_HANDLE 似乎是一个无符号长整数,而 HICON 是一个 void* 。在 32 位 Windows 中,它们的大小相同,但在 Windows x64 中,void* 是 64 位。没有一种安全的方法来进行这种转换——额外的 32 位是未定义的。不幸的是,我能够挖掘出的涉及 ULONG(OLE_HANDLE 甚至更罕见的野兽)的唯一建议只是简单地说“不要将其转换为指针”。

于 2008-12-31T03:37:04.960 回答
1

我怀疑在它们之间进行“正确”投射的“正确”答案是“不要那样做”。诚然,这不是很有帮助...... OLE_HANDLE 首先来自哪里?听起来您将不得不使用 OLE_HANDLE 重写代码才能在任何地方使用 HICON。

于 2008-12-31T14:14:43.693 回答
0
HICON hSomeIcon = (HICON) hSomeOLEHandle;

即它们是可互换的。

于 2008-12-30T23:40:53.113 回答