Image 如何将图标从资源加载到图像?

Image 如何将图标从资源加载到图像?,image,delphi,resources,delphi-10.3-rio,Image,Delphi,Resources,Delphi 10.3 Rio,我尝试了以下代码,但它不起作用LoadIconWithScaleDown返回一个负错误代码 unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; type

我尝试了以下代码,但它不起作用
LoadIconWithScaleDown
返回一个负错误代码

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure LoadResToImg(RID: String; const Img: TImage);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
{$R UserResources.res}

uses Winapi.CommCtrl;

procedure TForm1.LoadResToImg(RID: String; const Img: TImage);
var Ico: TIcon;
    hI: HICON;
    HR: HResult;
begin
 Ico:= TIcon.Create;
 HR:= LoadIconWithScaleDown(HInstance, PChar(RID), Img.Width, Img.Height, hI);
 Ico.Handle:= hI;
 Img.Picture.Bitmap.Assign(Ico);
 Ico.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 LoadResToImg('OFFLINE', Image1);
end;

end.
UserResources.rc

OFFLINE      ICON    "gray_button.ico"
ONLINE       ICON    "green_button.ico" 

这可能是因为此Win32函数的VCL包装器(在
Winapi.CommCtrl.pas
中)有故障,或者至少不能立即使用

因此,你可以自己声明:

函数LoadIconWithScaleDown(hinst:hinst;pszName:LPCWSTR;cx:Integer;
cy:Integer;var phico:HICON):HResult;stdcall;外部“ComCtl32”;

但请注意,此功能仅在Windows Vista+(IIRC)上提供。

如评论中所述,您也可以使用。 我认为Andreas答案中的方法更简单,但如果有人喜欢使用
InitCommonControlsEx
,下面是代码:

uses
  Winapi.Windows, Winapi.CommCtrl;

...

var
  IconHandle : HICON;
  ICC: TInitCommonControlsEx;
begin
  ICC.dwSize := SizeOf(TInitCommonControlsEx);
  ICC.dwICC := ICC_BAR_CLASSES;

  if(not InitCommonControlsEx(ICC)) then
    raise Exception.Create('InitCommonControlsEx error');

  if(LoadIconWithScaleDown(0, MAKEINTRESOURCE(<your res id>), 32, 32, IconHandle) <> S_OK) then
    raise Exception.Create('LoadIconWithScaleDown error');

  <here you can use IconHandle as you need>
end;
使用
Winapi.Windows,Winapi.CommCtrl;
...
变量
IconHandle:HICON;
ICC:TInitCommonControlsEx;
开始
ICC.dwSize:=SizeOf(TInitCommonControlsEx);
ICC.dwICC:=ICC\u BAR\u类;
如果(不是国际刑事法院),那么
引发异常。创建('InitCommonControlsEx错误');
如果(LoadIconWithScaleDown(0,MAKEINTRESOURCE(),32,32,IconHandle)S_OK),则
引发异常。创建('LoadIconWithScaleDown错误');
结束;

注意:我已经测试过它通过
IDI_信息
作为

在图像上有一个
常量,但在字符串上没有。它“应该”是相反的!所以像
TImage
ar这样的对象是通过引用传递的,即使它们没有
const
?是的,对象总是通过引用传递的。字符串使用COW语义,使用
const
编译器不需要更新refcount。事实上,就是这样!它现在起作用了。。。谢谢这让我疯狂了大约4个小时……或者,你可以在使用
LoadIconWithScaleDown
之前调用
InitCommonControlsEx
,但我认为从Win32的角度来看,这是不必要的。“但请注意,此函数仅在Windows Vista+(IIRC)上存在。”-在这种情况下,您应该在函数声明中包含函数,然后不要在Vista之前的运行时调用函数systems@RemyLebeau:或者是老派:
LoadLibrary
+
GetProcAddress
。如果您使用的是旧版本的Delphi,这是必需的。@AndreasRejbrand真正的旧版本,因为
延迟
是在D2010中引入的。