Missing definitions and declarations
To be able to set a custom thumbnail, the following functions are required:
- DwmSetIconicThumbnail
- DwmSetWindowAttribute
- DwmSetIconicLivePreviewBitmap
These functions can be found in the Dwmapi.h header file. Unfortunately this file is not present in MINGW.
The solution is to call them directly from Dwmapi.dll.
Firstly it is needed to typedef a function pointer type to these functions.
extern "C" { typedef HRESULT (WINAPI *t_DwmSetIconicThumbnail)(HWND hwnd, HBITMAP hbmp, DWORD dwSITFlags); typedef HRESULT (WINAPI *t_DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); typedef HRESULT (WINAPI *t_DwmSetIconicLivePreviewBitmap)(HWND hwnd, HBITMAP hbmp, POINT *pptClient, DWORD dwSITFlags); }
Then, make wrappers which will call these functions directly from the dll.
void DwmSetIconicThumbnail(HWND hwnd, HBITMAP hbmp, DWORD dwSITFlags) { HMODULE shell; shell = LoadLibrary(L"dwmapi.dll"); if (shell) { t_DwmSetIconicThumbnail set_iconic_thumbnail = reinterpret_cast<t_DwmSetIconicThumbnail>(GetProcAddress (shell, "DwmSetIconicThumbnail")); set_iconic_thumbnail(hwnd, hbmp, dwSITFlags); FreeLibrary (shell); } } void DwmSetWindowAttribute(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) { HMODULE shell; shell = LoadLibrary(L"dwmapi.dll"); if (shell) { t_DwmSetWindowAttribute set_window_attribute = reinterpret_cast<t_DwmSetWindowAttribute>(GetProcAddress (shell, "DwmSetWindowAttribute")); set_window_attribute(hwnd, dwAttribute, pvAttribute, cbAttribute); FreeLibrary (shell); } } void DwmSetIconicLivePreviewBitmap(HWND hwnd, HBITMAP hbmp, POINT *pptClient, DWORD dwSITFlags) { HMODULE shell; shell = LoadLibrary(L"dwmapi.dll"); if (shell) { t_DwmSetIconicLivePreviewBitmap set_live_preview = reinterpret_cast<t_DwmSetIconicLivePreviewBitmap>(GetProcAddress (shell, "DwmSetIconicLivePreviewBitmap")); set_live_preview(hwnd, hbmp, pptClient, dwSITFlags); FreeLibrary (shell); } }
Project settings
It is needed to add extra linkage libraries options to the linker.
LIBS += libgdi32
Setting the thumbnail
You need to do the following:
1) Call the DwmSetWindowAttribute function to set window attributes for non-client rendering to DWMWA_FORCE_ICONIC_REPRESENTATION and DWMWA_HAS_ICONIC_BITMAP
2) Catch WM_DWMSENDICONICTHUMBNAIL and WM_DWMSENDICONICLIVEPREVIEWBITMAP Windows events
3) Call DwmSetIconicThumbnail, on WM_DWMSENDICONICTHUMBNAIL event, to set thumbnail bitmap
4) Call DwmSetIconicLivePreviewBitmap, on DWMSENDICONICLIVEPREVIEWBITMAP event, to set the window live preview bitmap
Firslty, set window attributes:
void MainWindow::EnableIconicPreview(bool enable) { BOOL fForceIconic = enable ? TRUE : FALSE; BOOL fHasIconicBitmap = enable ? TRUE : FALSE; DwmSetWindowAttribute( this->winId(), DWMWA_FORCE_ICONIC_REPRESENTATION, &fForceIconic, sizeof(fForceIconic)); DwmSetWindowAttribute( this->winId(), DWMWA_HAS_ICONIC_BITMAP, &fHasIconicBitmap, sizeof(fHasIconicBitmap)); }
Secondly, re-implement the QMainWindow winEvent protected function:
class MainWindow : public QMainWindow { //.. protected: bool winEvent(MSG * message, long * result); //.. }; bool MainWindow::winEvent(MSG * message, long * result) { switch (message->message) { case WM_DWMSENDICONICTHUMBNAIL: //call DwmSetIconicThumbnail break; case WM_DWMSENDICONICLIVEPREVIEWBITMAP: //call DwmSetIconicLivePreviewBitmap break; default: return false; } return false; }
On WM_DWMSENDICONICTHUMBNAIL event
Convert a QPixmap image to HBITMAP, and call DwmSetIconicThumbnail for this window:
QPixmap image(":/qtlogo.png"); HBITMAP hbitmap = m_image.toWinHBITMAP(); DwmSetIconicThumbnail(this->winId(), hbitmap, 0); DeleteObject(hbitmap);
On WM_DWMSENDICONICLIVEPREVIEWBITMAP event
In this case it is required to provide the taskbar with a custom image of the selected window:
HBITMAP hbitmap = QPixmap::grabWidget(this).scaled(this->size(), Qt::KeepAspectRatio).toWinHBITMAP(); DwmSetIconicLivePreviewBitmap(this->winId(), hbitmap, 0, 0); DeleteObject(hbitmap);
The result:
The code can be downloaded from here.
Useful link.
No comments:
Post a Comment