Delphi 11.3调用SHGetFileInfo触发ERangeError问题求助
Delphi 11.3调用SHGetFileInfo获取系统图标触发ERangeError异常
我编写了调用SHGetFileInfo获取系统图标列表的代码:
FileIcons: TImageList; procedure LoadFileIcons; var listHandle: Integer; shFileInfo: TSHFileInfo; begin listHandle:= SHGetFileInfo('', 0, shFileInfo, Sizeof(shFileInfo), SHGFI_SYSICONINDEX or SHGFI_LARGEICON); if (listHandle <> 0) then begin FileIcons.Handle:=listHandle; FileIcons.ShareImages:=true; end; end
该代码在Delphi 10.4中可正常加载并显示文件图标,但在Delphi 11.3中触发ERangeError异常:
Project Project.exe raised exception class ERangeError with message 'Range check error at address 00000000035C7A99'.
一、Delphi 10.4到11.3的相关变更
- TImageList句柄类型变更:Delphi 11起,
TImageList.Handle的类型从Integer改为HIMAGELIST(本质是指针类型,64位环境下占8字节),原代码用Integer存储句柄,会导致64位下句柄值被截断,触发范围检查错误。 - 范围检查机制强化:Delphi 11对64位环境下的类型不匹配问题检查更严格,之前10.4中被忽略的指针截断问题,在11.3中直接抛出异常。
二、修复方案
方案1:修正变量类型(推荐)
将存储句柄的变量类型改为HIMAGELIST,确保64位环境下能完整存储系统句柄:
FileIcons: TImageList; procedure LoadFileIcons; var listHandle: HIMAGELIST; // 修正为对应系统句柄类型 shFileInfo: TSHFileInfo; begin listHandle:= SHGetFileInfo('', 0, shFileInfo, SizeOf(shFileInfo), SHGFI_SYSICONINDEX or SHGFI_LARGEICON); if (listHandle <> 0) then begin FileIcons.Handle := listHandle; FileIcons.ShareImages := True; end; end;
方案2:显式类型转换(仅兼容旧代码场景)
如果需保留原变量类型,可在赋值时显式转换为HIMAGELIST,但这种方式存在潜在风险,不推荐长期使用:
FileIcons.Handle := HIMAGELIST(listHandle);
额外注意事项
- 确保
FileIcons已被正确初始化(比如在窗体创建时完成实例化),未初始化的TImageList也可能引发异常。 - 64位编译环境下,所有系统句柄相关变量都应使用对应类型(如
HIMAGELIST、HWND等),避免用Integer存储指针类型值。
内容的提问来源于stack exchange,提问作者Federico Pessina
相关产品推荐
相关产品推荐

