Вопрос Как показать значок из исполняемого файла (.exe)

AlexS

Новичок
Доброго времени суток.
Есть проблема с показом значка(который нужно получить из файла *.exe) в TNewIconImage.
Долго уже ковыряю функции LoadIcon и LoadImage, но реализовать не получается.
Задача в следующем:
на странице есть некое количество кнопок, по нажатию которых должны запускаться определенные исполняемые файлы.
Выбираются эти исполняемые файлы через форму настроек каждой кнопки.
Так вот, настраивая исполняемый файл кнопки, после выбора файла необходимо показать значок этого исполняемого файла рядом с кнопкой его запуска.
Прошу помощи, никак не разберусь с этими функциями...
Код:
[Setup]
AppName=Моя программа
AppVersion=1.0
DefaultDirName={pf}\Моя программа
DisableWelcomePage=yes

;[Files]
;DestName: "IconImage.ico"; Source: "Icon.ico"; Flags: dontcopy solidbreak

[code]
var
  ToolsPage: TWizardPage;
  AddProgForm: TSetupForm;
  OKButton, CancelButton, BrowseButton: TNewButton;
  BrowseEdit, NameEdit: TNewEdit;
  ProgBtn: array[0..7] of TNewButton;
  IconImg: array[0..7] of TNewIconImage;
  SettingBtn: array[0..7] of TNewButton;
  i: Integer;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  Confirm:=false;
end;

procedure FileChoose(Sender: TObject);
var
  SelFileNameStr: String;
begin
 if GetOpenFileName('', SelFileNameStr, ExpandConstant('{src}'),
 'Исполняемые файлы (*.exe;*.bat;*.cmd;*.vbs)|*.exe;*.bat;*.cmd;*.vbs|Все файлы (*.*)|*.*', 'exe') then
  BrowseEdit.Text:= SelFileNameStr;
end;

procedure ShowCustomForm(Sender: TObject);
begin
  AddProgForm := CreateCustomForm();
  try
    AddProgForm.BorderStyle := bsDialog;
    AddProgForm.ClientWidth := ScaleX(380);
    AddProgForm.ClientHeight := ScaleY(337);
    AddProgForm.Caption := 'Настройка';
    AddProgForm.CenterInsideControl(WizardForm, False);

  OKButton := TNewButton.Create(AddProgForm);
    OKButton.Parent := AddProgForm;
    OKButton.SetBounds(ScaleX(205),ScaleY(305),ScaleX(75),ScaleY(23));
    OKButton.Caption := SetupMessage(msgButtonOK);
    OKButton.ModalResult:= mrOk;

  CancelButton := TNewButton.Create(AddProgForm);
    CancelButton.Parent := AddProgForm;
    CancelButton.SetBounds(ScaleX(290),ScaleY(305),ScaleX(75),ScaleY(23));
    CancelButton.Caption := SetupMessage(msgButtonCancel);
    CancelButton.ModalResult := mrCancel;

  BrowseButton := TNewButton.Create(AddProgForm);
    BrowseButton.Parent := AddProgForm;
    BrowseButton.SetBounds(ScaleX(290),ScaleY(35),ScaleX(75),ScaleY(22));
    BrowseButton.Caption := SetupMessage(msgButtonBrowse);
    BrowseButton.OnClick := @FileChoose;

  BrowseEdit:= TNewEdit.Create(AddProgForm);
    BrowseEdit.SetBounds(ScaleX(15),ScaleY(36),ScaleX(265),ScaleY(30));
    BrowseEdit.AutoSelect:=False;
    BrowseEdit.Parent:= AddProgForm;

  NameEdit:= TNewEdit.Create(AddProgForm);
    NameEdit.SetBounds(ScaleX(15),ScaleY(66),ScaleX(350),ScaleY(30));
    NameEdit.AutoSelect:=False;
    NameEdit.Parent:= AddProgForm;

  if AddProgForm.ShowModal() = mrOk then
    AddProgForm.Close;
    //ProgBtn[0].Caption := NameEdit.Text;
  finally
    AddProgForm.Free();
  end;
end;

procedure InitializeWizard();
begin
  begin
  WizardForm.Caption := '';
  WizardForm.MainPanel.Hide;
  WizardForm.InnerPage.Color := $00ffffff;
  WizardForm.BorderStyle := bsDialog;
  WizardForm.ClientHeight := ScaleY(360);
  WizardForm.ClientWidth := ScaleX(500);
  WizardForm.OuterNotebook.Width := ScaleX(500);
  WizardForm.OuterNotebook.Height := ScaleY(360);
  WizardForm.InnerNotebook.SetBounds(ScaleX(0),ScaleY(0),ScaleX(500),ScaleY(500));
  end;
  begin
  ToolsPage := CreateCustomPage(wpWelcome, '', '');
  end;
  //******************\\
  for i:=0 to 7 do begin
  SettingBtn[i]:=TNewButton.Create(nil);
  with SettingBtn[i] do begin
    SetBounds(ScaleX(464), ScaleY(110+30*i), ScaleX(25), ScaleY(25));
    Parent:=ToolsPage.Surface;
    Caption := '...';
    OnClick:=@ShowCustomForm;
  end;
  end;
  //******************\\
  for i:=0 to 7 do begin
  ProgBtn[i]:=TNewButton.Create(nil);
  with ProgBtn[i] do begin
    SetBounds(ScaleX(45), ScaleY(110+30*i), ScaleX(411), ScaleY(25));
    Parent:=ToolsPage.Surface;
    Caption :='Кнопка' + #32 + IntToStr(i);
  end;
  end;
  //******************\\
  for i:=0 to 7 do begin
  IconImg[i]:=TNewIconImage.Create(nil);
  with IconImg[i] do begin
    SetBounds(ScaleX(10), ScaleY(110+30*i), ScaleX(25), ScaleY(25));
    Parent:=ToolsPage.Surface;
//    ExtractTemporaryFile('IconImage.ico');
//    Icon.LoadFromFile(ExpandConstant('{tmp}\IconImage.ico'));
  end;
  end;
end;
Example.png
 

AlexS

Новичок
Вопрос снимаю.
Нашел решение функцией ExtractIcon.
Может и есть другие способы, но я пока их не знаю...
Выкладываю пример(сырой конечно, но всё же...), может кому и пригодится.
Код:
[Setup]
AppName=Моя программа
AppVersion=1.0
CreateAppDir=no
DisableWelcomePage=yes
OutputDir=.

[code]
var
  ToolsPage: TWizardPage;
  ProgBtn, SettingBtn: TNewButton;
  IconImg: TBitmapImage;

function GetModuleHandle(lpModuleName: LongInt): LongInt;
external 'GetModuleHandleA@kernel32.dll stdcall';

function ExtractIcon(hInst: LongInt; lpszExeFileName: PChar; nIconIndex: LongInt): LongInt;
external 'ExtractIconA@shell32.dll stdcall';

function DrawIconEx(hdc: LongInt; xLeft, yTop: Integer; hIcon: LongInt; cxWidth, cyWidth: Integer; istepIfAniCur, hbrFlickerFreeDraw, diFlags: LongInt): LongInt;
external 'DrawIconEx@user32.dll stdcall';

procedure FileChoose(Sender: TObject);
var
  SelFileNameStr: String;
begin
 if GetOpenFileName('', SelFileNameStr, ExpandConstant('{src}'),
 'Исполняемые файлы (*.exe;*.bat;*.cmd;*.vbs)|*.exe;*.bat;*.cmd;*.vbs|Все файлы (*.*)|*.*', 'exe') then
    SetIniString('Setting','Program_1', SelFileNameStr, ExpandConstant('{src}\Setting.ini'));
    MsgBox('Чтобы увидеть изменения, перезапустите программу.', mbInformation, MB_OK);
end;

procedure RunPrgm(Sender: TObject);
var
  ResultCode: Integer;
  ProgramAdres: string;
begin
  ProgramAdres := GetIniString('Setting','Program_1', '', ExpandConstant('{src}\Setting.ini'));
  If ProgramAdres <> '' then begin
    Exec(ProgramAdres,'','',SW_SHOW,ewNoWait, ResultCode);
  end;
end;

procedure InitializeWizard();
var
Rect: TRect;
hIcon: LongInt;

begin
  hIcon:= ExtractIcon(GetModuleHandle(0), GetIniString('Setting','Program_1', '', ExpandConstant('{src}\Setting.ini')), 0);
  begin
  WizardForm.Caption := '';
  WizardForm.MainPanel.Hide;
  WizardForm.InnerPage.Color := $00ffffff;
  WizardForm.BorderStyle := bsDialog;
  WizardForm.ClientHeight := ScaleY(360);
  WizardForm.ClientWidth := ScaleX(500);
  WizardForm.OuterNotebook.Width := ScaleX(500);
  WizardForm.OuterNotebook.Height := ScaleY(360);
  WizardForm.InnerNotebook.SetBounds(ScaleX(0),ScaleY(0),ScaleX(500),ScaleY(500));
  end;
  begin
  ToolsPage := CreateCustomPage(wpWelcome, '', '');
  //******************\\
  SettingBtn:=TNewButton.Create(nil);
  with SettingBtn do begin
    SetBounds(ScaleX(464), ScaleY(110), ScaleX(25), ScaleY(25));
    Parent:=ToolsPage.Surface;
    Caption := '...';
    OnClick := @FileChoose;
  end;
  //******************\\
  ProgBtn:=TNewButton.Create(nil);
  with ProgBtn do begin
    SetBounds(ScaleX(45), ScaleY(110), ScaleX(411), ScaleY(25));
    Parent:=ToolsPage.Surface;
    Caption :='Кнопка';
    OnClick := @RunPrgm;
  end;
  //******************\\
  IconImg:=TBitmapImage.Create(nil);
  with IconImg do begin
    SetBounds(ScaleX(10), ScaleY(110), ScaleX(25), ScaleY(25));
    Parent:=ToolsPage.Surface;
    with Bitmap do
    begin
     Width:= ScaleX(24);
     Height:= ScaleY(24);
     Rect.Right:= ScaleX(24);
     Rect.Bottom:= ScaleY(24);
     Rect.Left:= ScaleX(10);
     Rect.Top:= ScaleY(110);
     Canvas.Brush.Color:= clBtnFace;
     Canvas.FillRect(Rect);
     DrawIconEx(Canvas.Handle, 0, 0, HIcon, 24, 24, 0, 0, 3);
    end;
  end;
  end;
end;
 
Сверху