https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dbe4abab4f25e7883d7c9b6012a730a842a54614

commit dbe4abab4f25e7883d7c9b6012a730a842a54614
Author:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
AuthorDate: Thu Sep 29 04:06:17 2022 +0200
Commit:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
CommitDate: Thu Sep 29 04:06:17 2022 +0200

    [KBSWITCH][INPUT.CPL] Correctly do the input language indicator.
    
    Addendum to commits 5f4bb73e and c6ccb92b.
    
    - 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 
https://github.com/reactos/reactos/pull/4723#discussion_r981331634
      was meant to discover that CreateDIBSection() was unnecessary, since
      the very original code (before commit 0991cedc) 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.
---
 base/applications/kbswitch/kbswitch.c | 86 +++++++++++++++++------------------
 dll/cpl/input/settings_page.c         | 71 ++++++++++++++---------------
 2 files changed, 78 insertions(+), 79 deletions(-)

diff --git a/base/applications/kbswitch/kbswitch.c 
b/base/applications/kbswitch/kbswitch.c
index d6d2a513e8d..356209d0c6a 100644
--- a/base/applications/kbswitch/kbswitch.c
+++ b/base/applications/kbswitch/kbswitch.c
@@ -10,8 +10,6 @@
 #include "kbswitch.h"
 
 #define WM_NOTIFYICONMSG (WM_USER + 248)
-#define CX_ICON 16
-#define CY_ICON 16
 
 PKBSWITCHSETHOOKS    KbSwitchSetHooks    = NULL;
 PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL;
@@ -148,58 +146,59 @@ CreateTrayIcon(LPTSTR szLCID)
 {
     LANGID LangID;
     TCHAR szBuf[4];
-    HDC hdc;
+    HDC hdcScreen, hdc;
     HBITMAP hbmColor, hbmMono, hBmpOld;
+    HFONT hFont, hFontOld;
+    LOGFONT lf;
     RECT rect;
-    HFONT hFontOld, hFont;
     ICONINFO IconInfo;
     HICON hIcon;
-    LOGFONT lf;
-    BITMAPINFO bmi;
+    INT cxIcon = GetSystemMetrics(SM_CXSMICON);
+    INT cyIcon = GetSystemMetrics(SM_CYSMICON);
 
     /* Getting "EN", "FR", etc. from English, French, ... */
-    LangID = LOWORD(_tcstoul(szLCID, NULL, 16));
-    if (!GetLocaleInfo(LangID, LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
-                       szBuf, ARRAYSIZE(szBuf)))
+    LangID = LANGIDFROMLCID(_tcstoul(szLCID, NULL, 16));
+    if (GetLocaleInfo(LangID,
+                      LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
+                      szBuf,
+                      ARRAYSIZE(szBuf)) == 0)
     {
-        StringCchCopy(szBuf, ARRAYSIZE(szBuf), _T("??"));
+        szBuf[0] = szBuf[1] = _T('?');
     }
-    szBuf[2] = 0; /* Truncate the identifiers to two characters: "ENG" --> 
"EN" etc. */
-
-    /* Prepare for DIB (device-independent bitmap) */
-    ZeroMemory(&bmi, sizeof(bmi));
-    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
-    bmi.bmiHeader.biWidth = CX_ICON;
-    bmi.bmiHeader.biHeight = CY_ICON;
-    bmi.bmiHeader.biPlanes = 1;
-    bmi.bmiHeader.biBitCount = 24;
+    szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" 
etc. */
 
     /* Create hdc, hbmColor and hbmMono */
-    hdc = CreateCompatibleDC(NULL);
-    hbmColor = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
-    hbmMono = CreateBitmap(CX_ICON, CY_ICON, 1, 1, NULL);
-
-    /* Create a font */
-    if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
-        hFont = CreateFontIndirect(&lf);
-    else
-        hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+    hdcScreen = GetDC(NULL);
+    hdc = CreateCompatibleDC(hdcScreen);
+    hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
+    ReleaseDC(NULL, hdcScreen);
+    hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
 
     /* Checking NULL */
-    if (!hdc || !hbmColor || !hbmMono || !hFont)
+    if (!hdc || !hbmColor || !hbmMono)
     {
-        if (hdc)
-            DeleteDC(hdc);
-        if (hbmColor)
-            DeleteObject(hbmColor);
         if (hbmMono)
             DeleteObject(hbmMono);
-        if (hFont)
-            DeleteObject(hFont);
+        if (hbmColor)
+            DeleteObject(hbmColor);
+        if (hdc)
+            DeleteDC(hdc);
         return NULL;
     }
 
-    SetRect(&rect, 0, 0, CX_ICON, CY_ICON);
+    /* Create a font */
+    hFont = NULL;
+    if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
+    {
+        /* Override the current size with something manageable */
+        lf.lfHeight = -11;
+        lf.lfWidth = 0;
+        hFont = CreateFontIndirect(&lf);
+    }
+    if (!hFont)
+        hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+
+    SetRect(&rect, 0, 0, cxIcon, cyIcon);
 
     /* Draw hbmColor */
     hBmpOld = SelectObject(hdc, hbmColor);
@@ -210,23 +209,23 @@ CreateTrayIcon(LPTSTR szLCID)
     SetBkMode(hdc, TRANSPARENT);
     DrawText(hdc, szBuf, 2, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
     SelectObject(hdc, hFontOld);
-    SelectObject(hdc, hBmpOld);
 
-    /* Fill hbmMono by black */
-    hBmpOld = SelectObject(hdc, hbmMono);
-    PatBlt(hdc, 0, 0, CX_ICON, CY_ICON, BLACKNESS);
+    /* Fill hbmMono with black */
+    SelectObject(hdc, hbmMono);
+    PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
     SelectObject(hdc, hBmpOld);
 
     /* Create an icon from hbmColor and hbmMono */
+    IconInfo.fIcon = TRUE;
+    IconInfo.xHotspot = IconInfo.yHotspot = 0;
     IconInfo.hbmColor = hbmColor;
     IconInfo.hbmMask = hbmMono;
-    IconInfo.fIcon = TRUE;
     hIcon = CreateIconIndirect(&IconInfo);
 
     /* Clean up */
-    DeleteObject(hbmColor);
-    DeleteObject(hbmMono);
     DeleteObject(hFont);
+    DeleteObject(hbmMono);
+    DeleteObject(hbmColor);
     DeleteDC(hdc);
 
     return hIcon;
@@ -269,6 +268,7 @@ static VOID
 UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
 {
     NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | 
NIF_TIP };
+
     tnid.uCallbackMessage = WM_NOTIFYICONMSG;
     tnid.hIcon = CreateTrayIcon(szLCID);
     StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
diff --git a/dll/cpl/input/settings_page.c b/dll/cpl/input/settings_page.c
index c49e25d9b29..a100cfcd3d9 100644
--- a/dll/cpl/input/settings_page.c
+++ b/dll/cpl/input/settings_page.c
@@ -21,58 +21,57 @@ static HICON
 CreateLayoutIcon(LANGID LangID)
 {
     WCHAR szBuf[4];
-    HDC hdc;
+    HDC hdcScreen, hdc;
     HBITMAP hbmColor, hbmMono, hBmpOld;
+    HFONT hFont, hFontOld;
+    LOGFONTW lf;
     RECT rect;
-    HFONT hFontOld, hFont;
     ICONINFO IconInfo;
     HICON hIcon;
-    LOGFONTW lf;
-    BITMAPINFO bmi;
     INT cxIcon = GetSystemMetrics(SM_CXSMICON);
     INT cyIcon = GetSystemMetrics(SM_CYSMICON);
 
     /* Getting "EN", "FR", etc. from English, French, ... */
-    if (!GetLocaleInfoW(LangID, LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
-                        szBuf, ARRAYSIZE(szBuf)))
+    if (GetLocaleInfoW(LangID,
+                       LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
+                       szBuf,
+                       ARRAYSIZE(szBuf)) == 0)
     {
-        StringCchCopyW(szBuf, ARRAYSIZE(szBuf), L"??");
+        szBuf[0] = szBuf[1] = L'?';
     }
     szBuf[2] = UNICODE_NULL; /* Truncate the identifier to two characters: 
"ENG" --> "EN" etc. */
 
-    /* Prepare for DIB (device-independent bitmap) */
-    ZeroMemory(&bmi, sizeof(bmi));
-    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
-    bmi.bmiHeader.biWidth = cxIcon;
-    bmi.bmiHeader.biHeight = cyIcon;
-    bmi.bmiHeader.biPlanes = 1;
-    bmi.bmiHeader.biBitCount = 24;
-
     /* Create hdc, hbmColor and hbmMono */
-    hdc = CreateCompatibleDC(NULL);
-    hbmColor = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
+    hdcScreen = GetDC(NULL);
+    hdc = CreateCompatibleDC(hdcScreen);
+    hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
+    ReleaseDC(NULL, hdcScreen);
     hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
 
-    /* Create a font */
-    if (SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
-        hFont = CreateFontIndirectW(&lf);
-    else
-        hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
-
     /* Checking NULL */
-    if (!hdc || !hbmColor || !hbmMono || !hFont)
+    if (!hdc || !hbmColor || !hbmMono)
     {
-        if (hdc)
-            DeleteDC(hdc);
-        if (hbmColor)
-            DeleteObject(hbmColor);
         if (hbmMono)
             DeleteObject(hbmMono);
-        if (hFont)
-            DeleteObject(hFont);
+        if (hbmColor)
+            DeleteObject(hbmColor);
+        if (hdc)
+            DeleteDC(hdc);
         return NULL;
     }
 
+    /* Create a font */
+    hFont = NULL;
+    if (SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
+    {
+        /* Override the current size with something manageable */
+        lf.lfHeight = -11;
+        lf.lfWidth = 0;
+        hFont = CreateFontIndirectW(&lf);
+    }
+    if (!hFont)
+        hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+
     SetRect(&rect, 0, 0, cxIcon, cyIcon);
 
     /* Draw hbmColor */
@@ -84,23 +83,23 @@ CreateLayoutIcon(LANGID LangID)
     SetBkMode(hdc, TRANSPARENT);
     DrawTextW(hdc, szBuf, 2, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
     SelectObject(hdc, hFontOld);
-    SelectObject(hdc, hBmpOld);
 
-    /* Fill hbmMono by black */
-    hBmpOld = SelectObject(hdc, hbmMono);
+    /* Fill hbmMono with black */
+    SelectObject(hdc, hbmMono);
     PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
     SelectObject(hdc, hBmpOld);
 
     /* Create an icon from hbmColor and hbmMono */
+    IconInfo.fIcon = TRUE;
+    IconInfo.xHotspot = IconInfo.yHotspot = 0;
     IconInfo.hbmColor = hbmColor;
     IconInfo.hbmMask = hbmMono;
-    IconInfo.fIcon = TRUE;
     hIcon = CreateIconIndirect(&IconInfo);
 
     /* Clean up */
-    DeleteObject(hbmColor);
-    DeleteObject(hbmMono);
     DeleteObject(hFont);
+    DeleteObject(hbmMono);
+    DeleteObject(hbmColor);
     DeleteDC(hdc);
 
     return hIcon;

Reply via email to