Jump to content
Sign in to follow this  
KodeZwerg

ShlObj -> PickIconDlg() - strange behaviour

Recommended Posts

Hello, i did not find much information about this function but i would like to use it (or does delphi bring own dialog with that ability?)

 

Here is wrapper i use:

uses
  ShlObj;

...

function PickIconDialog( IconHandle: HWND; var Filename: string; var IconIndex: Integer ): Boolean;
var
  tmp : String;
  idx: Integer;
begin
  Result := False;
  tmp := Filename;
  idx := IconIndex;
  if ( PickIconDlg( IconHandle, PWideChar( tmp ), 1023, idx ) <> 0 ) then
    begin
      Filename := String( tmp );
      IconIndex := idx;
      Result := True;
    end;
end;

This is how i call it:

 

procedure TfrmMain.btnGetIconClick(Sender: TObject);
var
  IconFile: String;
  IconIndex: LongInt;
begin
  IconFile := '';
  IconIndex := 0;
  try
    IconIndex := StrToInt( edIconIndex.Text );
  except
    IconIndex := 0;
  end;
  if ( PickIconDialog( Handle, IconFile, IconIndex ) = True ) then
    begin
      edIconLocation.Text := IconFile;
      try
        edIconIndex.Text := IntToStr( IconIndex );
      except
        edIconIndex.Text := '0';
      end;
      Image1.Picture.Icon.Handle := ExtractIcon( hInstance, PWideChar( IconFile ), Cardinal( IconIndex ) );
    end;
end;

What happen is, i get correct Icon displayed but...

Iconfilename often is invisible.

Other edit fields are invisible overwritten with Value of Iconfilename,

Most of time, every field that has no value on start will be invisible overwritten. (ATM i do by workaround, i fill every field before operation with any data)

 

Do i use it wrong? Does better ways exists to have such dialog?

Share this post


Link to post

Hmm..

 

the buffer for pszIconPath 'must' be have the size of MAX_PATH..

 

https://docs.microsoft.com/en-us/windows/desktop/api/shlobj_core/nf-shlobj_core-pickicondlg

 

function PickIconDlg(AHwnd : HWND; pszIconPath : PWideString; cchIconPath : DWORD; var piIconIndex : integer):integer; stdcall; external 'Shell32.dll' name 'PickIconDlg';

function PickIconDialog(var Filename: WideString; var IconIndex: Integer ): Boolean;
var
  tmp : Array[0..MAX_PATH-1] of WideChar;  // Min Size of pszIconPath must be MAX_PATH
begin
  Result := False;
  FillChar(tmp[0], MAX_PATH * SizeOf(WideChar),0);
  Move(FileName[1],tmp[0],Length(FileName)* SizeOf(WideChar));
  if ( PickIconDlg( 0, @tmp[0], MAX_PATH, IconIndex ) <> 0 ) then
  begin
    Filename := Widestring(tmp);
    Result := True;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  tmpIdx : integer;
  tmpFile : WideString;
begin
  tmpFile := ParamStr(0);
  PickIconDialog(tmpFile, tmpIdx);
  ShowMessage(tmpFile + ' - ' + IntToStr(tmpIdx));
end;

 

  • Thanks 1

Share this post


Link to post

@HolgerX

I will test out your modification and tell if it works that no fields get hidden values 🙂

 

Thank you for sample and link, i really appreciate it.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×