How to re-use Window icons?
-
My project need to custom File Dialog/Folder Dialog follow project style. However, we still want to re-use Window icons.
I know that most of Window icons are store in .dll file. Ex: %SystemRoot%\System32\SHELL32.dll
My project is using Qt6 6.5.2I found this topic, https://forum.qt.io/topic/67590/icons-from-dll-file
Icon Extractor example configed in Qt5.15. They used winextras but I cannot add QT += winextras1: error: Project ERROR: Unknown module(s) in QT: winextras
Does anyone have an solution to get icon in .dll file?
-
@Trung-FPT On Windows you can use ExtractIcon() function to get a HICON resource from a module (exe or dll). There is no winextras module in Qt6 anymore. Its functionality was incorporated into various core classes. You can convert HICON into QImage using QImage::fromHICON(). Don't forget to delete the HICON resource afer loading and converting it using DestroyIcon() or you will leak memory.
Keep in mind that extracting icons from system libraries directly is not a very sustainable approach. These resources are internal and are not meant to be used like that. They can be rearranged, renamed, moved between files or removed in any future version of Windows.
The supported way of getting system icons is through the shell API. SHGetStockIconInfo will retrieve information about a system icon (including optionally the resource's HICON). The list of available system icons IDs is here.
-
@Trung-FPT
All you need is a little reading:https://learn.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-loadimagea
QPixmap QtWin::fromHICON(HICON icon)
This function is obsolete.
Use QImage::fromHICON() instead.QImage QImage::fromHICON(HICON icon)
This function was introduced in Qt 6.0.)
Complete example: Convert HICON to QIcon in Qt 6
[BTW @Chris-Kawa's approach of going via the Shell API is the correct way to go.]
-
Here's a little wrapper to make it easier:
QImage getSystemIcon(SHSTOCKICONID id, UINT extraFlags) { SHSTOCKICONINFO info {}; info.cbSize = sizeof (SHSTOCKICONINFO); if (SUCCEEDED(SHGetStockIconInfo(id, SHGSI_ICON | extraFlags, &info))) { QImage img = QImage::fromHICON(info.hIcon); DestroyIcon(info.hIcon); return img; } return {}; }
If you wanted, for example, the large version of system folder icon with a shortcut overlay, you would use it like this:
QImage img = getSystemIcon(SIID_FOLDER, SHGSI_LARGEICON | SHGSI_LINKOVERLAY); if (!img.isNull()) ...
-
@Chris-Kawa Thanks for guide.
I'm trying your solution.
Follow https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shgetstockiconinfo#requirements
I have added LIBS += -luser32 and #include<shellapi.h>
But my QtCreator does not know shellapi.h
I'm using mingw1120_64
What should I do to use SHGetStockIconInfo and SHSTOCKICONID? -
@Trung-FPT
The directory containingshellapi.h
must be on yourINCLUDEPATH
.
That file must be installed. I believe you have to actually install the Windows SDK to get it, I don't think it comes with Windows without that. Have you done this?
I do not know whether it works OK with MinGW as opposed to MSVC (but I would guess it does/can be made to work). E.g. https://learn.microsoft.com/en-us/windows/win32/desktop-programming
@Chris-Kawa may know exact steps for MinGW. -
@Trung-FPT Your LIBS and include are correct. These are part of Windows SDK. MinGW has its own version of Windows SDK libraries included in its installation. If it's the MinGW bundled with Qt Installer then they should be already available for you in the MinGW installation dir. It does work for me out of the box.
Is it just Creator not seeing the header (i.e. shows red squiggles) or doesn't it compile? Can you verify that the shellapi.h file is present in
<your MinGW install dir>\x86_64-w64-mingw32\
? Have you re-run qmake after modifying it (Build ->run qmake)?@JonB said:
That file must be installed. I believe you have to actually install the Windows SDK to get it,
That is the case for MSVC, but OP is using MinGW, which has its own version of these files bundled with the compiler.
-
-
@Chris-Kawa said in How to re-use Window icons?:
That is the case for MSVC, but OP is using MinGW, which has its own version of these files bundled with the compiler.
Prefect :) My Windows machine has neither MSVC nor MinGW and has no
shellapi.h
, that's all I know :)So MingGW comes with all the Windows header files which might be wanted already included in the distro?
-
@JonB said in How to re-use Window icons?:
So MingGW comes with all the Windows header files which might be wanted already included in the distro?
I'm guessing it's optional if you're building and deploying MinGW yourself, but it is included in the Qt distributed version (and all the major ones otherwise). I'm not sure which version of the SDK it specifically mimics and it's certainly not all of it, but most of the usual stuff is there.