2

I'm trying to load icons used by Delphi's task dialogs into a TImage control. As I've learned here, I'm using LoadImage function but icons appear lightly different from the ones which are used by the MessageDlg function.

example form

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.Icon.Handle := LoadImage( 0, IDI_WARNING, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE or LR_SHARED );
  MessageDlg('mtWarning', mtWarning, [mbOk], 0);

  Image1.Picture.Icon.Handle := LoadImage( 0, IDI_ERROR, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE or LR_SHARED );
  MessageDlg('mtError', mtError, [mbOk], 0);

  Image1.Picture.Icon.Handle := LoadImage( 0, IDI_INFORMATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE or LR_SHARED );
  MessageDlg('mtInformation', mtInformation, [mbOk], 0);

  Image1.Picture.Icon.Handle := LoadImage( 0, IDI_QUESTION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE or LR_SHARED );
  MessageDlg('mtConfirmation', mtConfirmation, [mbOk], 0);
end;

end.

As you can see, the icons in the TImage are different from the corresponding icon used by the MessageDlg function.

mtWarning dialog mtError dialog mtInformation dialog mtConfirmation dialog

Further tests:

  1. I found out that MessageDlg function uses the same icons obtained by LoadImage when the Enable runtime themes flag is deactivated (in the Project Options).

  2. The MessageDlg function seems to use some constants defined in CommCtrl unit:

{ Task Dialog Common Icons }

{$EXTERNALSYM TD_WARNING_ICON}
TD_WARNING_ICON = MAKEINTRESOURCEW(Word(-1));
{$EXTERNALSYM TD_ERROR_ICON}
TD_ERROR_ICON = MAKEINTRESOURCEW(Word(-2));
{$EXTERNALSYM TD_INFORMATION_ICON} TD_INFORMATION_ICON = MAKEINTRESOURCEW(Word(-3));
{$EXTERNALSYM TD_SHIELD_ICON}
TD_SHIELD_ICON = MAKEINTRESOURCEW(Word(-4));

How can I get the same icons used by the task dialogs?

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
  • What Windows Version are you using? It looks like something post Win7 but the images from your dialogs are definitively Win XP. IIRC the TTaskDialog had to "modes" back in D2007. One worked on any Windows using built in ressources and the other only worked on windows that actually had the TaskDialog. – Sherlock70 Feb 22 '19 at 12:08
  • @Sherlock70: I'm using Windows 10 – Fabrizio Feb 22 '19 at 12:22
  • That's what I would have guessed. So obviously, your MessageDlg pulls some hard wired images from some Delphi resources. Considering it's D2007 that is the then current design scheme. – Sherlock70 Feb 22 '19 at 14:08
  • It's not Delphi. When OS > Vista, UseLatestCommonDialogs is set and themes are enabled, the VCL calls TaskDialogIndirect passing a resource id for the icon (TD_ERROR_ICON, etc..). Even, as seen on your captures, there's no question (confirmation) icon available as per the [docs](https://learn.microsoft.com/en-us/windows/desktop/api/commctrl/ns-commctrl-_taskdialogconfig)(scroll to pszMainIcon), so the VCL falls back to an exclamation. Anyway, so the question is why does TaskDialogIndirect behaves differently than LoadImage. Unfortunately I cannot be of further help, on W7 they don't. – Sertac Akyuz Feb 22 '19 at 14:33
  • @Fabrizio This resolved question may be helpful: https://stackoverflow.com/questions/60887975/getting-modern-system-icons-with-loadicon/60890009 – Jabberwocky Mar 27 '20 at 16:38

0 Answers0