如何将图标从资源加载到 TImage?
How to load an icon from resources to a TImage?
我尝试了以下代码,但它不起作用...LoadIconWithScaleDown
returns 负错误代码。
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, 32, IconHandle) <> S_OK) then
raise Exception.Create('LoadIconWithScaleDown error');
<here you can use IconHandle as you need>
end;
注意: 我已经测试过 IDI_INFORMATION
作为 <your res id>
我尝试了以下代码,但它不起作用...LoadIconWithScaleDown
returns 负错误代码。
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, 32, IconHandle) <> S_OK) then
raise Exception.Create('LoadIconWithScaleDown error');
<here you can use IconHandle as you need>
end;
注意: 我已经测试过 IDI_INFORMATION
作为 <your res id>