为什么在Delphi XE2 64bit中为HKEY_常量获得"常量表达式违反子范围边界"?

dum*_*uch 9 delphi 64-bit winapi delphi-xe2

当我在Delphi XE2中为目标平台64位Windows编译以下代码时......

function HKeyToString(_HKey: HKey): string;
begin
  case _HKey of
    HKEY_CLASSES_ROOT: result := 'HKEY_CLASSES_ROOT'; // do not translate
    HKEY_CURRENT_USER: result := 'HKEY_CURRENT_USER'; // do not translate
    HKEY_LOCAL_MACHINE: result := 'HKEY_LOCAL_MACHINE'; // do not translate
    HKEY_USERS: result := 'HKEY_USERS'; // do not translate
    HKEY_PERFORMANCE_DATA: result := 'HKEY_PERFORMANCE_DATA'; // do not translate
    HKEY_CURRENT_CONFIG: result := 'HKEY_CURRENT_CONFIG'; // do not translate
    HKEY_DYN_DATA: result := 'HKEY_DYN_DATA'; // do not translate
  else
    Result := Format(_('unknown Registry Root Key %x'), [_HKey]);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

...我收到每个HKEY_-Constants的警告:"W1012常量表达式违反了子范围"

我检查了Winapi.Windows中的声明(在标识符上使用Ctrl + Leftclick):

type
  HKEY = type UINT_PTR;
{...}
const
  HKEY_CLASSES_ROOT     = HKEY(Integer($80000000));
Run Code Online (Sandbox Code Playgroud)

这对我来说很好看.为什么编译器仍然认为存在问题?

Dav*_*nan 9

在64位编译器上的实际值HKEY_CLASSES_ROOT是:

FFFFFFFF80000000
Run Code Online (Sandbox Code Playgroud)

这是因为演员Integer阵容80000000变为负数.然后转换为无符号导致FFFFFFFF80000000.请注意,此值是正确的.Windows头文件中的声明是:

#define HKEY_CLASSES_ROOT (( HKEY ) (ULONG_PTR)((LONG)0x80000000) )
Run Code Online (Sandbox Code Playgroud)

当您包含头文件并检查HKEY_CLASSES_ROOTC++程序中的值时,它与Delphi声明的值完全相同.

然后我们可以从Delphi文档中解决这个难题,该文档指出case语句中的选择器只能是:

任何小于32位的序数类型的表达式

您别无选择,只能用case声明替换您的if声明.