Delphi XE4,TControl.Perform() 的 wParam 只接受无符号整数?

Delphi XE4, wParam for TControl.Perform() accepts only unsigned int?

在 Delphi7 中,TControl.Perform() 接受 wParam 参数的负值,这就是它应该做的,因为例如 EM_LINEFROMCHAR winapi wParam.

的消息期望 -1

但在Delphi XE4 下,wParam 的数据类型已更改为NativeUInt,不接受负整数。

这是Delphi RTL的一个bug,还是我理解有误?谢谢。

类型为WPARAM,定义为UINT_PTR。如果你想传递负值,你可以传递例如

WPARAM(-1)

这应该会按预期工作。

这是 Delphi 7 header 翻译中的一个缺陷,其中之一。这种类型是 documented on MSDN 像这样:

WPARAM

A message parameter. This type is declared in WinDef.h as follows:

typedef UINT_PTR WPARAM;

反过来,UINT_PTR是一个无符号整数类型,其大小与平台指针相同。

在引入 64 位编译器时,这个缺陷已得到纠正,并且类型的 Delphi 声明变为无符号,以匹配底层平台 API.

如果你想传递一个负值,你应该转换它。像这样:

WPARAM(-1)

这样的转换是 SendMessage API 的一个必要的邪恶原因,它为所有消息类型提供了一个通用接口。有时您只需要使您的消息负载适合可用类型。我还要评论 lParam 参数的类型为 LPARAM,它是一个指针大小的有符号整数。这意味着当决定如何将附加数据与消息一起传递时,您可以在签名 (lParam) 和未签名 (wParam) 类型之间进行选择。当然,如果你想传递两个有符号的值,或者两个无符号的值,那么你需要强制转换。

EM_LINEFROMCHAR 的情况下,您可能会发现未使用 lParam。您可能会问为什么设计者没有在有符号 lParam 参数中传递字符索引,而不是在无符号 wParam 参数中传递字符索引。一个可能的原因是 -1 是标记值。通过使用无符号参数,字符索引可以是 0$ffffffff - 1 之间的任何值(假设为 32 位整数)。这意味着字符索引的有效范围是使用有符号值的两倍大。现在,如果使用了有符号值,它可以再次转换为大于 fffffff 的值,但只对特殊标记值要求转换是有意义的。