Skip to content

Commit dbe4aba

Browse files
committed
[KBSWITCH][INPUT.CPL] Correctly do the input language indicator.
Addendum to commits 5f4bb73 and c6ccb92. - GetLocaleInfo() returns an int, not a bool: makes it clear in the test. - No need to use StringCchCopy() to just initialize two chars to the same value. - The question about the test in reactos#4723 (comment) was meant to discover that CreateDIBSection() was unnecessary, since the very original code (before commit 0991ced) did not use it and was working fine in that regard. The simple fix was to use GetDC(NULL). - Use SM_CXSMICON/SM_CYSMICON metrics for the KBSWITCH indicator as well. - Override the font size obtained from SPI_GETICONTITLELOGFONT with a known one (allows to get a correct indicator even if the user font is very large). - Do the initialization in such a way that in case SPI_GETICONTITLELOGFONT or CreateFontIndirect fails, we always fall back to the default stock font that is ensured to always exist. - Initialize *all* the fields of the IconInfo structure.
1 parent c6ccb92 commit dbe4aba

File tree

2 files changed

+78
-79
lines changed

2 files changed

+78
-79
lines changed

base/applications/kbswitch/kbswitch.c

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#include "kbswitch.h"
1111

1212
#define WM_NOTIFYICONMSG (WM_USER + 248)
13-
#define CX_ICON 16
14-
#define CY_ICON 16
1513

1614
PKBSWITCHSETHOOKS KbSwitchSetHooks = NULL;
1715
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL;
@@ -148,58 +146,59 @@ CreateTrayIcon(LPTSTR szLCID)
148146
{
149147
LANGID LangID;
150148
TCHAR szBuf[4];
151-
HDC hdc;
149+
HDC hdcScreen, hdc;
152150
HBITMAP hbmColor, hbmMono, hBmpOld;
151+
HFONT hFont, hFontOld;
152+
LOGFONT lf;
153153
RECT rect;
154-
HFONT hFontOld, hFont;
155154
ICONINFO IconInfo;
156155
HICON hIcon;
157-
LOGFONT lf;
158-
BITMAPINFO bmi;
156+
INT cxIcon = GetSystemMetrics(SM_CXSMICON);
157+
INT cyIcon = GetSystemMetrics(SM_CYSMICON);
159158

160159
/* Getting "EN", "FR", etc. from English, French, ... */
161-
LangID = LOWORD(_tcstoul(szLCID, NULL, 16));
162-
if (!GetLocaleInfo(LangID, LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
163-
szBuf, ARRAYSIZE(szBuf)))
160+
LangID = LANGIDFROMLCID(_tcstoul(szLCID, NULL, 16));
161+
if (GetLocaleInfo(LangID,
162+
LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
163+
szBuf,
164+
ARRAYSIZE(szBuf)) == 0)
164165
{
165-
StringCchCopy(szBuf, ARRAYSIZE(szBuf), _T("??"));
166+
szBuf[0] = szBuf[1] = _T('?');
166167
}
167-
szBuf[2] = 0; /* Truncate the identifiers to two characters: "ENG" --> "EN" etc. */
168-
169-
/* Prepare for DIB (device-independent bitmap) */
170-
ZeroMemory(&bmi, sizeof(bmi));
171-
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
172-
bmi.bmiHeader.biWidth = CX_ICON;
173-
bmi.bmiHeader.biHeight = CY_ICON;
174-
bmi.bmiHeader.biPlanes = 1;
175-
bmi.bmiHeader.biBitCount = 24;
168+
szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
176169

177170
/* Create hdc, hbmColor and hbmMono */
178-
hdc = CreateCompatibleDC(NULL);
179-
hbmColor = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
180-
hbmMono = CreateBitmap(CX_ICON, CY_ICON, 1, 1, NULL);
181-
182-
/* Create a font */
183-
if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
184-
hFont = CreateFontIndirect(&lf);
185-
else
186-
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
171+
hdcScreen = GetDC(NULL);
172+
hdc = CreateCompatibleDC(hdcScreen);
173+
hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
174+
ReleaseDC(NULL, hdcScreen);
175+
hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
187176

188177
/* Checking NULL */
189-
if (!hdc || !hbmColor || !hbmMono || !hFont)
178+
if (!hdc || !hbmColor || !hbmMono)
190179
{
191-
if (hdc)
192-
DeleteDC(hdc);
193-
if (hbmColor)
194-
DeleteObject(hbmColor);
195180
if (hbmMono)
196181
DeleteObject(hbmMono);
197-
if (hFont)
198-
DeleteObject(hFont);
182+
if (hbmColor)
183+
DeleteObject(hbmColor);
184+
if (hdc)
185+
DeleteDC(hdc);
199186
return NULL;
200187
}
201188

202-
SetRect(&rect, 0, 0, CX_ICON, CY_ICON);
189+
/* Create a font */
190+
hFont = NULL;
191+
if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
192+
{
193+
/* Override the current size with something manageable */
194+
lf.lfHeight = -11;
195+
lf.lfWidth = 0;
196+
hFont = CreateFontIndirect(&lf);
197+
}
198+
if (!hFont)
199+
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
200+
201+
SetRect(&rect, 0, 0, cxIcon, cyIcon);
203202

204203
/* Draw hbmColor */
205204
hBmpOld = SelectObject(hdc, hbmColor);
@@ -210,23 +209,23 @@ CreateTrayIcon(LPTSTR szLCID)
210209
SetBkMode(hdc, TRANSPARENT);
211210
DrawText(hdc, szBuf, 2, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
212211
SelectObject(hdc, hFontOld);
213-
SelectObject(hdc, hBmpOld);
214212

215-
/* Fill hbmMono by black */
216-
hBmpOld = SelectObject(hdc, hbmMono);
217-
PatBlt(hdc, 0, 0, CX_ICON, CY_ICON, BLACKNESS);
213+
/* Fill hbmMono with black */
214+
SelectObject(hdc, hbmMono);
215+
PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
218216
SelectObject(hdc, hBmpOld);
219217

220218
/* Create an icon from hbmColor and hbmMono */
219+
IconInfo.fIcon = TRUE;
220+
IconInfo.xHotspot = IconInfo.yHotspot = 0;
221221
IconInfo.hbmColor = hbmColor;
222222
IconInfo.hbmMask = hbmMono;
223-
IconInfo.fIcon = TRUE;
224223
hIcon = CreateIconIndirect(&IconInfo);
225224

226225
/* Clean up */
227-
DeleteObject(hbmColor);
228-
DeleteObject(hbmMono);
229226
DeleteObject(hFont);
227+
DeleteObject(hbmMono);
228+
DeleteObject(hbmColor);
230229
DeleteDC(hdc);
231230

232231
return hIcon;
@@ -269,6 +268,7 @@ static VOID
269268
UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
270269
{
271270
NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
271+
272272
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
273273
tnid.hIcon = CreateTrayIcon(szLCID);
274274
StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);

dll/cpl/input/settings_page.c

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,58 +21,57 @@ static HICON
2121
CreateLayoutIcon(LANGID LangID)
2222
{
2323
WCHAR szBuf[4];
24-
HDC hdc;
24+
HDC hdcScreen, hdc;
2525
HBITMAP hbmColor, hbmMono, hBmpOld;
26+
HFONT hFont, hFontOld;
27+
LOGFONTW lf;
2628
RECT rect;
27-
HFONT hFontOld, hFont;
2829
ICONINFO IconInfo;
2930
HICON hIcon;
30-
LOGFONTW lf;
31-
BITMAPINFO bmi;
3231
INT cxIcon = GetSystemMetrics(SM_CXSMICON);
3332
INT cyIcon = GetSystemMetrics(SM_CYSMICON);
3433

3534
/* Getting "EN", "FR", etc. from English, French, ... */
36-
if (!GetLocaleInfoW(LangID, LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
37-
szBuf, ARRAYSIZE(szBuf)))
35+
if (GetLocaleInfoW(LangID,
36+
LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
37+
szBuf,
38+
ARRAYSIZE(szBuf)) == 0)
3839
{
39-
StringCchCopyW(szBuf, ARRAYSIZE(szBuf), L"??");
40+
szBuf[0] = szBuf[1] = L'?';
4041
}
4142
szBuf[2] = UNICODE_NULL; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
4243

43-
/* Prepare for DIB (device-independent bitmap) */
44-
ZeroMemory(&bmi, sizeof(bmi));
45-
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
46-
bmi.bmiHeader.biWidth = cxIcon;
47-
bmi.bmiHeader.biHeight = cyIcon;
48-
bmi.bmiHeader.biPlanes = 1;
49-
bmi.bmiHeader.biBitCount = 24;
50-
5144
/* Create hdc, hbmColor and hbmMono */
52-
hdc = CreateCompatibleDC(NULL);
53-
hbmColor = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
45+
hdcScreen = GetDC(NULL);
46+
hdc = CreateCompatibleDC(hdcScreen);
47+
hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
48+
ReleaseDC(NULL, hdcScreen);
5449
hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
5550

56-
/* Create a font */
57-
if (SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
58-
hFont = CreateFontIndirectW(&lf);
59-
else
60-
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
61-
6251
/* Checking NULL */
63-
if (!hdc || !hbmColor || !hbmMono || !hFont)
52+
if (!hdc || !hbmColor || !hbmMono)
6453
{
65-
if (hdc)
66-
DeleteDC(hdc);
67-
if (hbmColor)
68-
DeleteObject(hbmColor);
6954
if (hbmMono)
7055
DeleteObject(hbmMono);
71-
if (hFont)
72-
DeleteObject(hFont);
56+
if (hbmColor)
57+
DeleteObject(hbmColor);
58+
if (hdc)
59+
DeleteDC(hdc);
7360
return NULL;
7461
}
7562

63+
/* Create a font */
64+
hFont = NULL;
65+
if (SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
66+
{
67+
/* Override the current size with something manageable */
68+
lf.lfHeight = -11;
69+
lf.lfWidth = 0;
70+
hFont = CreateFontIndirectW(&lf);
71+
}
72+
if (!hFont)
73+
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
74+
7675
SetRect(&rect, 0, 0, cxIcon, cyIcon);
7776

7877
/* Draw hbmColor */
@@ -84,23 +83,23 @@ CreateLayoutIcon(LANGID LangID)
8483
SetBkMode(hdc, TRANSPARENT);
8584
DrawTextW(hdc, szBuf, 2, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
8685
SelectObject(hdc, hFontOld);
87-
SelectObject(hdc, hBmpOld);
8886

89-
/* Fill hbmMono by black */
90-
hBmpOld = SelectObject(hdc, hbmMono);
87+
/* Fill hbmMono with black */
88+
SelectObject(hdc, hbmMono);
9189
PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
9290
SelectObject(hdc, hBmpOld);
9391

9492
/* Create an icon from hbmColor and hbmMono */
93+
IconInfo.fIcon = TRUE;
94+
IconInfo.xHotspot = IconInfo.yHotspot = 0;
9595
IconInfo.hbmColor = hbmColor;
9696
IconInfo.hbmMask = hbmMono;
97-
IconInfo.fIcon = TRUE;
9897
hIcon = CreateIconIndirect(&IconInfo);
9998

10099
/* Clean up */
101-
DeleteObject(hbmColor);
102-
DeleteObject(hbmMono);
103100
DeleteObject(hFont);
101+
DeleteObject(hbmMono);
102+
DeleteObject(hbmColor);
104103
DeleteDC(hdc);
105104

106105
return hIcon;

0 commit comments

Comments
 (0)