wails icon indicating copy to clipboard operation
wails copied to clipboard

[v3] Windows - Custom dialog icon not working

Open leaanthony opened this issue 9 months ago • 4 comments

Description

The custom icons for windows dialogs do not work.

To Reproduce

  1. Run the v3/examples/dialogs example
  2. Select the Info->Info (custom icon) menu option

Expected behaviour

dialog to show

Screenshots

Image

leaanthony avatar Apr 24 '25 07:04 leaanthony

@leaanthony This issue needs to be evaluated. Wails uses embed to embed resources (for example: icons.ApplicationLightMode256), and when reading a resource file, the result is a []byte.
Unfortunately, whether using the raw []byte or converting it to a HICON, it is not possible to directly use it in a MessageBox.
It may be necessary to consider replacing MessageBox with TaskDialogIndirect, although support for TaskDialogIndirect is limited on certain systems.

Here are the technical requirements summarized:

Requirement Value
Minimum supported client Windows Vista (desktop apps only)
Minimum supported server Windows Server 2008 (desktop apps only)
Target platform Windows
Header commctrl.h (include Commctrl.h)
Library Comctl32.lib
DLL Comctl32.dll (version 6)

superDingda avatar Apr 28 '25 02:04 superDingda

@leaanthony This issue needs to be evaluated. Wails uses embed to embed resources (for example: icons.ApplicationLightMode256), and when reading a resource file, the result is a []byte. Unfortunately, whether using the raw []byte or converting it to a HICON, it is not possible to directly use it in a MessageBox. It may be necessary to consider replacing MessageBox with TaskDialogIndirect, although support for TaskDialogIndirect is limited on certain systems.

Here are the technical requirements summarized:

Requirement Value Minimum supported client Windows Vista (desktop apps only) Minimum supported server Windows Server 2008 (desktop apps only) Target platform Windows Header commctrl.h (include Commctrl.h) Library Comctl32.lib DLL Comctl32.dll (version 6)

Yeah, I actually started down the TaskDialogIndirect route but kept getting COM errors that I couldn't get around. If you know of a better solution I'd be open to it. I wondered whether extracting the icon to a temp directory and then using a load resource call might work.

leaanthony avatar Apr 28 '25 12:04 leaanthony

I actually started down the TaskDialogIndirect route but kept getting COM errors that I couldn't get around.

The idea of "extracting the icon to a temporary directory and then using a load resource call" doesn't seem to be feasible.

According to Microsoft's description of MSGBOXPARAMSA for the lpszIcon parameter:

Type: LPCTSTR

Identifies an icon resource. This parameter can be either a null-terminated string or an integer resource identifier passed to the MAKEINTRESOURCE macro.

To load one of the standard system-defined icons, set the hInstance member to NULL and set lpszIcon to one of the values listed with the LoadIcon function.

This member is ignored if the dwStyle member does not specify the MB_USERICON flag.

And combined with the description of LoadIcon:

Type: LPCTSTR

If hInstance is non-NULL, lpIconName specifies the icon resource either by name or ordinal. This ordinal must be packaged by using the MAKEINTRESOURCE macro.

If hInstance is NULL, lpIconName specifies the identifier (beginning with the IDI_ prefix) of a predefined system icon to load.

The following conclusions can be drawn:

  1. The icon for MessageBox can only be either a system-defined icon (such as IDI_ERROR), or a custom icon explicitly declared in the program's .rc resource script during the compilation phase. The latter must be processed by the resource compiler and ultimately linked into the program's .rsrc (resource section). At runtime, MessageBox can only load these resources via resource IDs or predefined strings, and it cannot dynamically specify an icon file on disk or pass an HICON handle.

  2. As for the current API, MessageBox does not provide a way to directly pass an HICON handle (unless using some unofficial methods like hooking or DLL injection, but these are clearly outside the scope of current design considerations).

Therefore, I personally prefer using TaskDialogIndirect, as it supports custom icons via HICON. You mentioned that you encountered COM errors when trying this method. Do you have any related code branches that I could take a look at? I’d like to learn more about the specific usage and potential pitfalls. Thank you!

superDingda avatar Apr 29 '25 06:04 superDingda

@superDingda - I've tried many times to get TaskDialogIndirect working properly and I've had no luck at all.

leaanthony avatar Nov 09 '25 11:11 leaanthony