CtrlCore: Fixed problems with Win11 ignoring WM_SETICON in taskbar if window does not process messages

This commit is contained in:
Mirek Fidler 2025-10-31 12:30:00 +01:00
parent 74169935dd
commit f6f0ecc8fa
4 changed files with 39 additions and 14 deletions

View file

@ -79,17 +79,6 @@ void TopWindow::SyncTitle()
::SetWindowTextW(hwnd, ToSystemCharsetW(title));
}
void TopWindow::DeleteIco()
{
GuiLock __;
LLOG("TopWindow::DeleteIco " << UPP::Name(this));
if(ico)
DestroyIcon(ico);
if(lico)
DestroyIcon(lico);
ico = lico = NULL;
}
String WindowStyleAsString(dword style, dword exstyle)
{
String r1;
@ -192,14 +181,41 @@ void TopWindow::SyncCaption()
FlashWindowEx(&fi);
}
}
SetIco();
Ptr<TopWindow> ptr = this;
PostCallback([=] { // windows 11 ignores icon if Window does not start processing messages within ~200ms
if(ptr) ptr->SetIco(); // set it again when we are processing events
});
}
void TopWindow::SetIco()
{
HWND hwnd = GetHWND();
if(hwnd) {
HICON new_ico = SystemDraw::IconWin32(Nvl(icon, largeicon));
HICON new_lico = SystemDraw::IconWin32(Nvl(largeicon, icon));
::SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)(new_ico));
::SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)(new_lico));
DeleteIco();
if(hwnd) {
::SendMessage(hwnd, WM_SETICON, false, (LPARAM)(ico = SystemDraw::IconWin32(icon)));
::SendMessage(hwnd, WM_SETICON, true, (LPARAM)(lico = SystemDraw::IconWin32(largeicon)));
ico = new_ico;
lico = new_lico;
}
}
void TopWindow::DeleteIco()
{
GuiLock __;
LLOG("TopWindow::DeleteIco " << UPP::Name(this));
if(ico)
DestroyIcon(ico);
if(lico)
DestroyIcon(lico);
ico = lico = NULL;
}
void TopWindow::CenterRect(HWND hwnd, int center)
{
GuiLock __;

View file

@ -9,6 +9,8 @@ x_MSG(WM_SETFOCUS)
x_MSG(WM_KILLFOCUS)
x_MSG(WM_ENABLE)
x_MSG(WM_SETREDRAW)
x_MSG(WM_SETICON)
x_MSG(WM_GETICON)
x_MSG(WM_SETTEXT)
x_MSG(WM_GETTEXT)
x_MSG(WM_GETTEXTLENGTH)

View file

@ -7,6 +7,7 @@ private:
HICON ico, lico;
void DeleteIco();
void SetIco();
void CenterRect(HWND owner, int center);
public:

View file

@ -13,6 +13,12 @@ using namespace Upp;
GUI_APP_MAIN
{
TopWindow win;
win.Title("TEST");
win.LargeIcon(TestImg::Icon());
DLOG("*********** OPEN MAIN");
win.OpenMain();
DLOG("*********** SLEEP 500");
Sleep(5000);
DLOG("*********** RUN");
win.Run();
}