[KBSWITCH] Refactor on layout numbers (#8052)

We believe the power of simplicity.
JIRA issue: CORE-20142
- Rename g_nCurrentLayoutNum as
  g_iKL for simplicity.
- Make g_iKL zero-based indexing.
- Add ID_LANG_BASE id for language
  menu items and adjust
  ID_EXIT/ID_PREFERENCES values.
- Fix KbSwitch_OnNotifyIconMsg
  function.
This commit is contained in:
Katayama Hirofumi MZ 2025-05-31 21:17:41 +09:00 committed by GitHub
parent c187cf8b9e
commit 51495b1b75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 61 deletions

View file

@ -38,12 +38,11 @@ FN_KbSwitchSetHooks KbSwitchSetHooks = NULL;
HINSTANCE g_hInst = NULL;
HMODULE g_hHookDLL = NULL;
INT g_nCurrentLayoutNum = 1;
HICON g_hTrayIcon = NULL;
HWND g_hwndLastActive = NULL;
INT g_cKLs = 0;
UINT g_iKL = 0;
UINT g_cKLs = 0;
HKL g_ahKLs[64];
HMENU g_hPopupMenu = NULL;
UINT g_uTaskbarRestartMsg = 0;
UINT g_uShellHookMessage = 0;
@ -150,42 +149,33 @@ static HKL GetActiveKL(VOID)
static VOID UpdateLayoutList(HKL hKL OPTIONAL)
{
INT iKL;
UINT iKL;
if (!hKL)
hKL = GetActiveKL();
g_cKLs = GetKeyboardLayoutList(_countof(g_ahKLs), g_ahKLs);
g_nCurrentLayoutNum = -1;
g_iKL = 0;
for (iKL = 0; iKL < g_cKLs; ++iKL)
{
if (g_ahKLs[iKL] == hKL)
{
g_nCurrentLayoutNum = iKL + 1;
g_iKL = iKL;
break;
}
}
if (g_nCurrentLayoutNum == -1 && g_cKLs < _countof(g_ahKLs))
{
g_nCurrentLayoutNum = g_cKLs;
g_ahKLs[g_cKLs++] = hKL;
}
}
static HKL GetHKLFromLayoutNum(INT nLayoutNum)
static HKL GetHKLFromLayoutNum(UINT iKL)
{
if (0 <= (nLayoutNum - 1) && (nLayoutNum - 1) < g_cKLs)
return g_ahKLs[nLayoutNum - 1];
else
return GetActiveKL();
return (iKL < g_cKLs) ? g_ahKLs[iKL] : GetActiveKL();
}
static VOID
GetKLIDFromLayoutNum(INT nLayoutNum, LPTSTR szKLID, SIZE_T KLIDLength)
GetKLIDFromLayoutNum(UINT iKL, LPTSTR szKLID, SIZE_T KLIDLength)
{
GetKLIDFromHKL(GetHKLFromLayoutNum(nLayoutNum), szKLID, KLIDLength);
GetKLIDFromHKL(GetHKLFromLayoutNum(iKL), szKLID, KLIDLength);
}
static BOOL
@ -200,14 +190,14 @@ GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
}
static BOOL
GetLayoutName(INT nLayoutNum, LPTSTR szName, SIZE_T NameLength)
GetLayoutName(UINT iKL, LPTSTR szName, SIZE_T NameLength)
{
HKEY hKey;
HRESULT hr;
DWORD dwBufLen;
TCHAR szBuf[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1];
GetKLIDFromLayoutNum(nLayoutNum, szKLID, _countof(szKLID));
GetKLIDFromLayoutNum(iKL, szKLID, _countof(szKLID));
StringCchPrintf(szBuf, _countof(szBuf),
_T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
@ -426,8 +416,8 @@ AddTrayIcon(HWND hwnd)
NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
TCHAR szKLID[CCH_LAYOUT_ID + 1], szName[MAX_PATH], szImeFile[80];
GetKLIDFromLayoutNum(g_nCurrentLayoutNum, szKLID, _countof(szKLID));
GetLayoutName(g_nCurrentLayoutNum, szName, _countof(szName));
GetKLIDFromLayoutNum(g_iKL, szKLID, _countof(szKLID));
GetLayoutName(g_iKL, szName, _countof(szName));
GetImeFile(szImeFile, _countof(szImeFile), szKLID);
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
@ -481,17 +471,16 @@ EnumWindowsProc(HWND hwnd, LPARAM lParam)
}
static VOID
ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
ActivateLayout(HWND hwnd, UINT iKL, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
{
HKL hKl;
TCHAR szKLID[CCH_LAYOUT_ID + 1], szLangName[MAX_PATH];
LANGID LangID;
/* The layout number starts from one. Zero is invalid */
if (uLayoutNum == 0 || uLayoutNum > 0xFF) /* Invalid */
if (iKL >= g_cKLs) /* Invalid */
return;
GetKLIDFromLayoutNum(uLayoutNum, szKLID, _countof(szKLID));
GetKLIDFromLayoutNum(iKL, szKLID, _countof(szKLID));
LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
/* Switch to the new keyboard layout */
@ -516,7 +505,7 @@ ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoAc
EnumWindows(EnumWindowsProc, (LPARAM) hKl);
}
g_nCurrentLayoutNum = uLayoutNum;
g_iKL = iKL;
}
static HMENU
@ -526,18 +515,18 @@ BuildLeftPopupMenu(VOID)
TCHAR szName[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1], szImeFile[80];
HICON hIcon;
MENUITEMINFO mii = { sizeof(mii) };
INT iKL;
UINT iKL;
for (iKL = 0; iKL < g_cKLs; ++iKL)
{
GetKLIDFromHKL(g_ahKLs[iKL], szKLID, _countof(szKLID));
GetImeFile(szImeFile, _countof(szImeFile), szKLID);
if (!GetLayoutName(iKL + 1, szName, _countof(szName)))
if (!GetLayoutName(iKL, szName, _countof(szName)))
continue;
mii.fMask = MIIM_ID | MIIM_STRING;
mii.wID = iKL + 1;
mii.wID = ID_LANG_BASE + iKL;
mii.dwTypeData = szName;
hIcon = CreateTrayIcon(szKLID, szImeFile);
@ -552,12 +541,12 @@ BuildLeftPopupMenu(VOID)
DestroyIcon(hIcon);
}
CheckMenuItem(hMenu, g_nCurrentLayoutNum, MF_CHECKED);
CheckMenuItem(hMenu, ID_LANG_BASE + g_iKL, MF_CHECKED);
return hMenu;
}
BOOL
static BOOL
SetHooks(VOID)
{
g_hHookDLL = LoadLibrary(_T("kbsdll.dll"));
@ -579,7 +568,7 @@ SetHooks(VOID)
return TRUE;
}
VOID
static VOID
DeleteHooks(VOID)
{
if (KbSwitchSetHooks)
@ -599,23 +588,17 @@ DeleteHooks(VOID)
static UINT GetLayoutNum(HKL hKL)
{
INT iKL;
UINT iKL;
for (iKL = 0; iKL < g_cKLs; ++iKL)
{
if (g_ahKLs[iKL] == hKL)
return iKL + 1;
return iKL;
}
return 0;
}
ULONG
GetNextLayout(VOID)
{
return (g_nCurrentLayoutNum % g_cKLs) + 1;
}
UINT
UpdateLanguageDisplay(HWND hwnd, HKL hKL)
{
@ -626,7 +609,7 @@ UpdateLanguageDisplay(HWND hwnd, HKL hKL)
LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, _countof(szLangName));
UpdateTrayIcon(hwnd, szKLID, szLangName);
g_nCurrentLayoutNum = GetLayoutNum(hKL);
g_iKL = GetLayoutNum(hKL);
return 0;
}
@ -682,7 +665,7 @@ KbSwitch_OnCreate(HWND hwnd)
UpdateLayoutList(NULL);
AddTrayIcon(hwnd);
ActivateLayout(hwnd, g_nCurrentLayoutNum, NULL, TRUE);
ActivateLayout(hwnd, g_iKL, NULL, TRUE);
g_uTaskbarRestartMsg = RegisterWindowMessage(TEXT("TaskbarCreated"));
return 0; /* Success */
@ -694,8 +677,6 @@ KbSwitch_OnDestroy(HWND hwnd)
{
KillTimer(hwnd, TIMER_ID_LANG_CHANGED_DELAYED);
DeleteHooks();
if (g_hPopupMenu)
DestroyMenu(g_hPopupMenu);
DeleteTrayIcon(hwnd);
PostQuitMessage(0);
}
@ -717,7 +698,7 @@ KbSwitch_OnTimer(HWND hwnd, UINT_PTR nTimerID)
static void
KbSwitch_OnNotifyIconMsg(HWND hwnd, UINT uMouseMsg)
{
if (uMouseMsg != WM_LBUTTONUP && uMouseMsg != WM_RBUTTONUP)
if (uMouseMsg != WM_LBUTTONUP && uMouseMsg != WM_RBUTTONUP && uMouseMsg != WM_CONTEXTMENU)
return;
UpdateLayoutList(NULL);
@ -731,17 +712,18 @@ KbSwitch_OnNotifyIconMsg(HWND hwnd, UINT uMouseMsg)
if (uMouseMsg == WM_LBUTTONUP)
{
/* Rebuild the left popup menu on every click to take care of keyboard layout changes */
HMENU hLeftPopupMenu = BuildLeftPopupMenu();
nID = TrackPopupMenu(hLeftPopupMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);
DestroyMenu(hLeftPopupMenu);
HMENU hPopupMenu = BuildLeftPopupMenu();
nID = TrackPopupMenuEx(hPopupMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON,
pt.x, pt.y, hwnd, NULL);
DestroyMenu(hPopupMenu);
}
else /* WM_RBUTTONUP */
else /* WM_RBUTTONUP or WM_CONTEXTMENU */
{
if (!g_hPopupMenu)
g_hPopupMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_POPUP));
HMENU hSubMenu = GetSubMenu(g_hPopupMenu, 0);
nID = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);
HMENU hPopupMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_POPUP));
HMENU hSubMenu = GetSubMenu(hPopupMenu, 0);
nID = TrackPopupMenuEx(hSubMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
pt.x, pt.y, hwnd, NULL);
DestroyMenu(hPopupMenu);
}
PostMessage(hwnd, WM_NULL, 0, 0);
@ -772,13 +754,13 @@ KbSwitch_OnCommand(HWND hwnd, UINT nID)
default:
{
if (1 <= nID && nID <= 1000)
if (nID >= ID_LANG_BASE)
{
if (!IsWindow(g_hwndLastActive))
{
g_hwndLastActive = NULL;
}
ActivateLayout(hwnd, nID, g_hwndLastActive, FALSE);
ActivateLayout(hwnd, nID - ID_LANG_BASE, g_hwndLastActive, FALSE);
}
break;
}

View file

@ -4,8 +4,9 @@
#define IDI_MAIN 100
/* Menus */
#define IDR_POPUP 12000
#define IDR_POPUP 100
/* Menu items */
#define ID_EXIT 10001
#define ID_PREFERENCES 10002
#define ID_EXIT 100
#define ID_PREFERENCES 101
#define ID_LANG_BASE 1000