1
votes

In Delphi 10.1.2 Berlin, I need to extract either the LARGE icon (32x32) or the SMALL icon (16x16) from an.EXE file, using a specific IconIndex:

function GetIconFromExecutableFile(const AFileName: string; const Large: Boolean; const AIconIndex: Integer): TIcon;
var
  Icon: HICON;
  ExtractedIconCount: UINT;
  ThisIconIdx: Integer;
  F: string; 
begin
  Result := nil;
  try
    ThisIconIdx := AIconIndex;

    F := AFileName;
    if Large then
    begin
      // error on nil: [dcc32 Error]: E2033 Types of actual and formal var parameters must be identical
      ExtractedIconCount := ExtractIconEx(PChar(F), ThisIconIdx, Icon, nil, 1);
    end
    else
    begin
      // error on nil: [dcc32 Error]: E2033 Types of actual and formal var parameters must be identical
      ExtractedIconCount := ExtractIconEx(PChar(F), ThisIconIdx, nil, Icon, 1);
    end;

    Win32Check(ExtractedIconCount = 1);

    Result := TIcon.Create;
    Result.Handle := Icon;
  except
    Result.Free;
    raise;
  end;
end;

Using nil for the excluded icon size creates a compiler error.

So how can I get the desired icon?

1
That works well.user1580348
The source (in WinAPI.ShellAPI.pas) shows the declaration as function ExtractIconEx(lpszFile: LPCWSTR; nIconIndex: Integer; var phiconLarge, phiconSmall: HICON; nIcons: UINT): UINT; stdcall;, and clearly nil can't be passed as a var parameter.Ken White

1 Answers

1
votes

One way is to fix the declaration of the API function:

type
  PHICON = ^HICON;
function ExtractIconEx(lpszFile: LPCWSTR; nIconIndex: int; phiconLarge, phiconSmall: PHICON; nIcons: UINT): UINT; stdcall; external shell32 name 'ExtractIconExW' delayed;

then use like:

procedure TForm1.FormCreate(Sender: TObject);
var
  Icon : HICON;
begin
  if ExtractIconEx(Pchar(ParamStr(0)), 0, @Icon, nil, 1) = 1 then begin
    self.Icon.Handle := Icon;
    DestroyIcon(Icon);
  end;