You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 23:22:08