22// @id fix-legacy-taskbar-tray-input-indicator
33// @name Fix language indicator in Win10 taskbar under Win11 24H2+
44// @description Fixes text orientation in the keyboard layout indicator in Win10 taskbar running under Win11 24H2+
5- // @version 1.4.0
5+ // @version 1.5
66// @author Anixx
77// @github https://github.com/Anixx
88// @include explorer.exe
@@ -32,13 +32,15 @@ Windows 11 taskbar.
3232#include < windows.h>
3333
3434static wchar_t g_text[8 ] = {};
35+ static wchar_t g_lastDrawnText[8 ] = {};
3536static LOGFONTW g_font = {};
3637static int g_srcW = 0 ;
3738static int g_srcH = 0 ;
3839static bool g_pending = false ;
3940static DWORD g_threadId = 0 ;
4041static COLORREF g_lastGoodBg = CLR_INVALID ;
4142static bool g_firstBltDone = false ;
43+ static bool g_alreadyDrawn = false ;
4244
4345static bool LooksLikeLayoutText (LPCWSTR s, int len) {
4446 if (!s || len < 2 || len > 4 ) return false ;
@@ -66,6 +68,17 @@ BOOL WINAPI ExtTextOutW_Hook(HDC hdc, int x, int y, UINT options,
6668 LOGFONTW lf = {};
6769
6870 if (LooksLikeLayoutText (lpString, len) && IsRotatedFont (hdc, &lf)) {
71+
72+ wchar_t newText[8 ] = {};
73+ wcsncpy_s (newText, lpString, len);
74+ newText[len] = 0 ;
75+
76+ bool textChanged = (wcscmp (newText, g_lastDrawnText) != 0 );
77+
78+ if (textChanged) {
79+ g_alreadyDrawn = false ;
80+ }
81+
6982 HBITMAP hbm = (HBITMAP )GetCurrentObject (hdc, OBJ_BITMAP );
7083 BITMAP bm = {};
7184 if (hbm && GetObject (hbm, sizeof (bm), &bm)) {
@@ -114,7 +127,6 @@ BOOL WINAPI BitBlt_Hook(HDC hdcDest, int xDest, int yDest, int w, int h,
114127 return result;
115128 }
116129
117- // BitBlt #1: точное совпадение с исходным размером — пропускаем
118130 bool isFirstBlit = (w == g_srcW && h == g_srcH);
119131 if (isFirstBlit) {
120132 g_firstBltDone = true ;
@@ -125,15 +137,38 @@ BOOL WINAPI BitBlt_Hook(HDC hdcDest, int xDest, int yDest, int w, int h,
125137 return result;
126138 }
127139
128- // BitBlt #2: первый после #1, размер БОЛЬШЕ исходного
129- // (индикатор всегда больше чем маленький bitmap с текстом)
130- // Ширина должна быть >= srcH (текст был повёрнут, теперь горизонтальный)
131140 bool isIndicator = (w > g_srcW || h > g_srcH) && (w >= g_srcH);
132141
133142 if (!isIndicator) {
134143 return result;
135144 }
136145
146+ // Если уже был нарисован (это hover) — рисуем поверх того что уже есть
147+ // не очищая фон, чтобы сохранить hover-эффект Windows
148+ if (g_alreadyDrawn) {
149+ RECT rc = { 0 , 0 , w, h };
150+
151+ LOGFONTW lfH = g_font;
152+ lfH.lfEscapement = 0 ;
153+ lfH.lfOrientation = 0 ;
154+
155+ HFONT hFont = CreateFontIndirectW (&lfH);
156+ if (hFont) {
157+ HFONT hOld = (HFONT )SelectObject (hdcDest, hFont);
158+ SetBkMode (hdcDest, TRANSPARENT );
159+ SetTextColor (hdcDest, GetSysColor (COLOR_BTNTEXT ));
160+
161+ DrawTextW (hdcDest, g_text, -1 , &rc,
162+ DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX );
163+
164+ SelectObject (hdcDest, hOld);
165+ DeleteObject (hFont);
166+ }
167+
168+ g_pending = false ;
169+ return result;
170+ }
171+
137172 COLORREF bgColor = GetPixel (hdcDest, w - 1 , h - 1 );
138173
139174 if (bgColor != CLR_INVALID && bgColor != 0x000000 ) {
@@ -167,6 +202,8 @@ BOOL WINAPI BitBlt_Hook(HDC hdcDest, int xDest, int yDest, int w, int h,
167202 DeleteObject (hFont);
168203 }
169204
205+ wcscpy_s (g_lastDrawnText, g_text);
206+ g_alreadyDrawn = true ;
170207 g_pending = false ;
171208
172209 return result;
@@ -182,4 +219,3 @@ BOOL Wh_ModInit() {
182219 (void **)&BitBlt_Original);
183220 return TRUE ;
184221}
185-
0 commit comments