How to load an icon from resources to a TImage?

筅森魡賤 提交于 2020-12-26 10:38:51

问题


I try the following code and it's not working... LoadIconWithScaleDown returns a negative error code.

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" 

回答1:


This is probably because the VCL's wrapper (in Winapi.CommCtrl.pas) for this Win32 function is faulty, or at least cannot be used straight away.

So instead declare it yourself:

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

But beware that this function is only present on Windows Vista+ (IIRC).




回答2:


As mentioned in comments, you can also do the same thing using InitCommonControlsEx. I think the approach in Andreas answer is simpler, but if someone prefer using InitCommonControlsEx, here is the code:

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;

Note: I've tested it passing IDI_INFORMATION as <your res id>



来源:https://stackoverflow.com/questions/63501567/how-to-load-an-icon-from-resources-to-a-timage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!