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

问题描述

我尝试下面的代码,但是它不起作用... 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中)有问题,或者至少不能立即使用。

因此,请自己声明:

function LoadIconWithScaleDown(hinst: HINST; pszName: LPCWSTR; cx: Integer;
    cy: Integer; var phico: HICON): HResult; stdcall; external 'ComCtl32';

但是请注意,此功能仅在Windows Vista +(IIRC)中存在。

,

如评论中所述,您也可以使用InitCommonControlsEx执行相同的操作。 我认为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,IconHandle) <> S_OK) then
    raise Exception.Create('LoadIconWithScaleDown error');

  <here you can use IconHandle as you need>
end;

注意:我已经通过IDI_INFORMATION作为<your res id>

对其进行了测试