【问题标题】:What is the proper way to cast from an 'OLE_HANDLE' to an 'HICON'?从“OLE_HANDLE”转换为“HICON”的正确方法是什么?
【发布时间】:2008-12-30 23:16:24
【问题描述】:

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

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

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

这是有问题的代码:

imgList.Add((HICON)ohIcon);

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

【问题讨论】:

    标签: c++ windows winapi mfc casting


    【解决方案1】:

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

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

    编辑:64 位嗯...问题是因为 MS 将句柄更新为 64 位,但不理会 OLE 的东西。幸运的是,他们所做的只是用零填充多余的位。

    尝试使用LongToHandle conversion routines 并查看MIDL porting guide - 向下滚动大约一半到“USER 和 GDI 句柄是符号扩展的 32b 值”部分。

    【讨论】:

    • 好发现 - 我找不到明确说明如何从一个到另一个的信息。
    【解决方案2】:

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

    如果您仅针对 32 位目标进行开发,您可以通过关闭项目选项 "Detect 64-bit Portability Issues" (C++ compiler option /Wp64). 来选择禁用此功能(以及一些其他类似的警告)

    如果您也在为 64 位目标进行开发,那么 @Harper 可能是正确的,您需要进一步挖掘处理此问题的正确方法。您可能想阅读this white paper 作为起点;转到关于 USER 和 GDI 句柄的部分。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:
          HICON hSomeIcon = (HICON) hSomeOLEHandle;
          

          即它们是可以互换的。

          【讨论】:

          • 看看我的新 cmets 为什么这不是我要找的东西
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-08-16
          • 1970-01-01
          • 1970-01-01
          • 2018-11-02
          • 2013-04-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多