【问题标题】:Delphi HDC Type Declaration in D2007 versus DXE2D2007 与 DXE2 中的 Delphi HDC 类型声明
【发布时间】:2013-03-28 08:27:06
【问题描述】:

在 Delphi 2007 和 Delphi XE2 中声明 HDC 类型(设备上下文句柄)的方式是否存在差异。

在 D2007 中,以下代码可以正常工作,但在 DXE2 中会产生范围检查错误:

Control.Parent.Perform(WM_PAINT, Integer(DC), 0);

在 D2007 中单步执行代码时,DC(设备上下文)的值似乎总是小于 MaxInt,但在 DXE2 中,DC 的值通常大于 MaxInt。

为什么D2007和DXE2在同一台机器上(同一个项目,同一个代码,同一个操作系统)运行时DC的值不同?

将 DC 转换为 WParam(我认为是无符号整数)是否安全?

【问题讨论】:

  • 我强烈建议您使用转换为WParam,它应该在两种环境中都可以编译。

标签: delphi


【解决方案1】:

您的演员表在现代 Delphi 版本中不正确。 Perform 的第二个参数输入为WPARAM,在 XE2 中是无符号的。所以如果你要投,那么你应该投到WPARAM。

在 32 位代码中,您的演员将 DC 的大值重新解释为负值。然后,当您传递给无符号参数时,就会出现范围检查错误。在 64 位代码中,您的强制转换会导致指针截断。

但无论如何你都不需要投射。那是因为HDC 是UINT_PTR,WPARAM 也是。只需删除演员表:

Control.Parent.Perform(WM_PAINT, DC, 0);

Windows 类型的定义传统上在 Delphi 中是一团糟,许多关键类型定义不正确。在引入 64 位 Delphi 编译器时,Embarcadero 选择了纠正这些错误的时机。

在较旧的 Delphi 版本中,需要强制转换,因为 WPARAM 的第二个参数已签名,但 HDC 未签名。

【讨论】:

  • 刚刚发现这个previous post 指出 WParam 在 XE2 中更改为无符号。因此,如果我理解正确,如果您的代码要在 XE2 之前的 Delphi 版本中编译,您应该转换 HDC,然后将其转换为 WParam(而不是整数)。从 XE2 开始,您根本不应该投射 HDC。听起来对吗?
  • 是的,我认为这是正确的。基本问题是旧版本的 Delphi 做错了。因此,您必须进行投射以弥补这些错误。如果您想要在新旧版本上编译的代码,请转换为 WPARAM。
【解决方案2】:

be carfull 类型的整数不是 WParam .. 您需要将 DC 类型转换为 WParam 类型

 Control.Parent.Perform(WM_PAINT, WPARAM(DC), 0);

【讨论】:

  • 您不需要将HDC 转换为WPARAM,因为它们已经兼容。他们都是UINT_PTR。
  • @David,那是你不应该依赖的。您现在不需要这样做,但谁知道呢,HDC 或 WPARAM 将来可能会被定义为不同的类型。 [+1]
  • @TLama 它只是因为 Borland 在很久以前就把它搞砸了而改变了。在世界其他地方,它永远没有签名。它不会改变,因为这样做会破坏一切!回到足够远的地方,参数的 Borland 声明是Integer。因此,根据您的分析,转换为整数是正确的。但这首先导致了错误。现在类型已正确声明,可以删除强制转换。强制转换的问题在于它把你带到了类型系统之外。演员表总是一种代码味道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
相关资源
最近更新 更多