ReactOS 0.4.15-dev-7196-g0fe0b40
kbswitch.c File Reference
#include "kbswitch.h"
#include <shlobj.h>
#include <shlwapi_undoc.h>
#include <imm.h>
Include dependency graph for kbswitch.c:

Go to the source code of this file.

Classes

struct  SPECIAL_ID
 
struct  tagLOAD_ICON
 

Macros

#define IME_MASK   (0xE0000000UL)
 
#define SPECIAL_MASK   (0xF0000000UL)
 
#define IS_IME_HKL(hKL)   ((((ULONG_PTR)(hKL)) & 0xF0000000) == IME_MASK)
 
#define IS_SPECIAL_HKL(hKL)   ((((ULONG_PTR)(hKL)) & 0xF0000000) == SPECIAL_MASK)
 
#define SPECIALIDFROMHKL(hKL)   ((WORD)(HIWORD(hKL) & 0x0FFF))
 
#define WM_NOTIFYICONMSG   (WM_USER + 248)
 

Typedefs

typedef struct SPECIAL_IDPSPECIAL_ID
 
typedef struct tagLOAD_ICON LOAD_ICON
 
typedef struct tagLOAD_ICONPLOAD_ICON
 

Functions

static VOID LoadSpecialIds (VOID)
 
static VOID GetKLIDFromHKL (HKL hKL, LPTSTR szKLID, SIZE_T KLIDLength)
 
static VOID UpdateLayoutList (HKL hKL OPTIONAL)
 
static HKL GetHKLFromLayoutNum (INT nLayoutNum)
 
static VOID GetKLIDFromLayoutNum (INT nLayoutNum, LPTSTR szKLID, SIZE_T KLIDLength)
 
static BOOL GetSystemLibraryPath (LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
 
static BOOL GetLayoutName (INT nLayoutNum, LPTSTR szName, SIZE_T NameLength)
 
static BOOL GetImeFile (LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szKLID)
 
static BOOL CALLBACK EnumResNameProc (HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LPARAM lParam)
 
static HICON FakeExtractIcon (LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
 
static HBITMAP BitmapFromIcon (HICON hIcon)
 
static HICON CreateTrayIcon (LPTSTR szKLID, LPCTSTR szImeFile OPTIONAL)
 
static VOID AddTrayIcon (HWND hwnd)
 
static VOID DeleteTrayIcon (HWND hwnd)
 
static VOID UpdateTrayIcon (HWND hwnd, LPTSTR szKLID, LPTSTR szName)
 
static BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
 
static VOID ActivateLayout (HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
 
static HMENU BuildLeftPopupMenu (VOID)
 
BOOL SetHooks (VOID)
 
VOID DeleteHooks (VOID)
 
static UINT GetLayoutNum (HKL hKL)
 
ULONG GetNextLayout (VOID)
 
UINT UpdateLanguageDisplay (HWND hwnd, HKL hKL)
 
HWND GetTargetWindow (HWND hwndFore)
 
UINT UpdateLanguageDisplayCurrent (HWND hwnd, HWND hwndFore)
 
static BOOL RememberLastActive (HWND hwnd, HWND hwndFore)
 
LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
 
INT WINAPI _tWinMain (HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
 

Variables

PKBSWITCHSETHOOKS KbSwitchSetHooks = NULL
 
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL
 
UINT ShellHookMessage = 0
 
HINSTANCE hInst
 
HANDLE hProcessHeap
 
HMODULE g_hHookDLL = NULL
 
INT g_nCurrentLayoutNum = 1
 
HICON g_hTrayIcon = NULL
 
HWND g_hwndLastActive = NULL
 
INT g_cKLs = 0
 
HKL g_ahKLs [64]
 
SPECIAL_ID g_SpecialIds [80]
 
INT g_cSpecialIds = 0
 

Macro Definition Documentation

◆ IME_MASK

#define IME_MASK   (0xE0000000UL)

Definition at line 29 of file kbswitch.c.

◆ IS_IME_HKL

#define IS_IME_HKL (   hKL)    ((((ULONG_PTR)(hKL)) & 0xF0000000) == IME_MASK)

Definition at line 32 of file kbswitch.c.

◆ IS_SPECIAL_HKL

#define IS_SPECIAL_HKL (   hKL)    ((((ULONG_PTR)(hKL)) & 0xF0000000) == SPECIAL_MASK)

Definition at line 33 of file kbswitch.c.

◆ SPECIAL_MASK

#define SPECIAL_MASK   (0xF0000000UL)

Definition at line 30 of file kbswitch.c.

◆ SPECIALIDFROMHKL

#define SPECIALIDFROMHKL (   hKL)    ((WORD)(HIWORD(hKL) & 0x0FFF))

Definition at line 34 of file kbswitch.c.

◆ WM_NOTIFYICONMSG

#define WM_NOTIFYICONMSG   (WM_USER + 248)

Definition at line 36 of file kbswitch.c.

Typedef Documentation

◆ LOAD_ICON

◆ PLOAD_ICON

◆ PSPECIAL_ID

Function Documentation

◆ _tWinMain()

INT WINAPI _tWinMain ( HINSTANCE  hInstance,
HINSTANCE  hPrevInst,
LPTSTR  lpCmdLine,
INT  nCmdShow 
)

Definition at line 880 of file kbswitch.c.

881{
883 MSG msg;
885 HWND hwnd;
886
887 switch (GetUserDefaultUILanguage())
888 {
891 break;
892 default:
893 break;
894 }
895
897 if (!hMutex)
898 return 1;
899
901 {
903 return 1;
904 }
905
908
909 ZeroMemory(&WndClass, sizeof(WndClass));
910 WndClass.lpfnWndProc = WndProc;
911 WndClass.hInstance = hInstance;
912 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
913 WndClass.lpszClassName = szKbSwitcherName;
914 if (!RegisterClass(&WndClass))
915 {
917 return 1;
918 }
919
923
924 while (GetMessage(&msg, NULL, 0, 0))
925 {
928 }
929
931 return 0;
932}
#define msg(x)
Definition: auth_time.c:54
WCHAR WndClass[]
Definition: capicon.c:23
HINSTANCE hInstance
Definition: charmap.c:19
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
UINT ShellHookMessage
Definition: kbswitch.c:40
HINSTANCE hInst
Definition: kbswitch.c:42
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:684
HANDLE hProcessHeap
Definition: kbswitch.c:43
TCHAR szKbSwitcherName[]
Definition: kbswitch.h:29
LANGID WINAPI GetUserDefaultUILanguage(void)
Definition: lang.c:816
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
HANDLE hMutex
Definition: mutex.c:11
#define L(x)
Definition: ntvdm.h:50
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_HEBREW
Definition: nls.h:67
#define SUBLANG_DEFAULT
Definition: nls.h:168
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
BOOL WINAPI SetProcessDefaultLayout(DWORD dwDefaultLayout)
Definition: window.c:1719
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CreateMutex
Definition: winbase.h:3691
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define LAYOUT_RTL
Definition: wingdi.h:1371
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI RegisterShellHookWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:687
#define CreateWindow
Definition: winuser.h:5753
#define HWND_DESKTOP
Definition: winuser.h:1208
#define GetMessage
Definition: winuser.h:5789
#define RegisterWindowMessage
Definition: winuser.h:5839
#define LoadCursor
Definition: winuser.h:5811
#define RegisterClass
Definition: winuser.h:5835
#define DispatchMessage
Definition: winuser.h:5764

◆ ActivateLayout()

static VOID ActivateLayout ( HWND  hwnd,
ULONG  uLayoutNum,
HWND hwndTarget  OPTIONAL,
BOOL  bNoActivate 
)
static

Definition at line 485 of file kbswitch.c.

486{
487 HKL hKl;
488 TCHAR szKLID[CCH_LAYOUT_ID + 1], szLangName[MAX_PATH];
490
491 /* The layout number starts from one. Zero is invalid */
492 if (uLayoutNum == 0 || uLayoutNum > 0xFF) /* Invalid */
493 return;
494
495 GetKLIDFromLayoutNum(uLayoutNum, szKLID, ARRAYSIZE(szKLID));
496 LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
497
498 /* Switch to the new keyboard layout */
499 GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
500 UpdateTrayIcon(hwnd, szKLID, szLangName);
501
502 if (hwndTarget && !bNoActivate)
503 SetForegroundWindow(hwndTarget);
504
505 hKl = LoadKeyboardLayout(szKLID, KLF_ACTIVATE);
506 if (hKl)
508
509 /* Post WM_INPUTLANGCHANGEREQUEST */
510 if (hwndTarget)
511 {
512 PostMessage(hwndTarget, WM_INPUTLANGCHANGEREQUEST,
513 INPUTLANGCHANGE_SYSCHARSET, (LPARAM)hKl);
514 }
515 else
516 {
518 }
519
520 g_nCurrentLayoutNum = uLayoutNum;
521}
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
#define _tcstoul
Definition: tchar.h:595
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: kbswitch.c:478
static VOID UpdateTrayIcon(HWND hwnd, LPTSTR szKLID, LPTSTR szName)
Definition: kbswitch.c:459
static VOID GetKLIDFromLayoutNum(INT nLayoutNum, LPTSTR szKLID, SIZE_T KLIDLength)
Definition: kbswitch.c:187
INT g_nCurrentLayoutNum
Definition: kbswitch.c:45
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
UINT_PTR HKL
Definition: msctf.idl:104
WORD LANGID
Definition: typedefs.h:81
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
LONG_PTR LPARAM
Definition: windef.h:208
#define GetLocaleInfo
Definition: winnls.h:1186
#define LOCALE_SLANGUAGE
Definition: winnls.h:26
#define KLF_SETFORPROCESS
Definition: winuser.h:117
#define KLF_ACTIVATE
Definition: winuser.h:111
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define LoadKeyboardLayout
Definition: winuser.h:5815
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define PostMessage
Definition: winuser.h:5831
HKL WINAPI ActivateKeyboardLayout(_In_ HKL, _In_ UINT)
char TCHAR
Definition: xmlstorage.h:189

Referenced by WndProc().

◆ AddTrayIcon()

static VOID AddTrayIcon ( HWND  hwnd)
static

Definition at line 425 of file kbswitch.c.

426{
427 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
428 TCHAR szKLID[CCH_LAYOUT_ID + 1], szName[MAX_PATH], szImeFile[80];
429
432 GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szKLID);
433
435 tnid.hIcon = CreateTrayIcon(szKLID, szImeFile);
437
439
440 if (g_hTrayIcon)
442 g_hTrayIcon = tnid.hIcon;
443}
static BOOL GetLayoutName(INT nLayoutNum, LPTSTR szName, SIZE_T NameLength)
Definition: kbswitch.c:204
static HICON CreateTrayIcon(LPTSTR szKLID, LPCTSTR szImeFile OPTIONAL)
Definition: kbswitch.c:328
static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szKLID)
Definition: kbswitch.c:240
HICON g_hTrayIcon
Definition: kbswitch.c:46
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:36
static const WCHAR szName[]
Definition: powrprof.c:45
#define NIF_ICON
Definition: shellapi.h:103
#define NIF_MESSAGE
Definition: shellapi.h:102
#define NIM_ADD
Definition: shellapi.h:91
#define Shell_NotifyIcon
Definition: shellapi.h:688
#define NIF_TIP
Definition: shellapi.h:104
#define StringCchCopy
Definition: strsafe.h:139
UINT uCallbackMessage
Definition: shellapi.h:228
CHAR szTip[128]
Definition: shellapi.h:234
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022

Referenced by WndProc().

◆ BitmapFromIcon()

static HBITMAP BitmapFromIcon ( HICON  hIcon)
static

Definition at line 306 of file kbswitch.c.

307{
308 HDC hdcScreen = GetDC(NULL);
309 HDC hdc = CreateCompatibleDC(hdcScreen);
312 HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
313 HGDIOBJ hbmOld;
314
315 if (hbm != NULL)
316 {
317 hbmOld = SelectObject(hdc, hbm);
318 DrawIconEx(hdc, 0, 0, hIcon, cxIcon, cyIcon, 0, GetSysColorBrush(COLOR_MENU), DI_NORMAL);
319 SelectObject(hdc, hbmOld);
320 }
321
322 DeleteDC(hdc);
323 ReleaseDC(NULL, hdcScreen);
324 return hbm;
325}
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
HICON hIcon
Definition: msconfig.c:44
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
int32_t INT
Definition: typedefs.h:58
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define DI_NORMAL
Definition: wingdi.h:72
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
BOOL WINAPI DeleteDC(_In_ HDC)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define COLOR_MENU
Definition: winuser.h:916
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define SM_CYSMICON
Definition: winuser.h:1012
#define SM_CXSMICON
Definition: winuser.h:1011
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:1997
HDC WINAPI GetDC(_In_opt_ HWND)
int WINAPI GetSystemMetrics(_In_ int)

Referenced by BuildLeftPopupMenu(), and FileTypesDlg_OnItemChanging().

◆ BuildLeftPopupMenu()

static HMENU BuildLeftPopupMenu ( VOID  )
static

Definition at line 524 of file kbswitch.c.

525{
526 HMENU hMenu = CreatePopupMenu();
527 TCHAR szName[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1], szImeFile[80];
528 HICON hIcon;
529 MENUITEMINFO mii = { sizeof(mii) };
530 INT iKL;
531
532 for (iKL = 0; iKL < g_cKLs; ++iKL)
533 {
534 GetKLIDFromHKL(g_ahKLs[iKL], szKLID, ARRAYSIZE(szKLID));
535 GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szKLID);
536
537 if (!GetLayoutName(iKL + 1, szName, ARRAYSIZE(szName)))
538 continue;
539
540 mii.fMask = MIIM_ID | MIIM_STRING;
541 mii.wID = iKL + 1;
542 mii.dwTypeData = szName;
543
544 hIcon = CreateTrayIcon(szKLID, szImeFile);
545 if (hIcon)
546 {
547 mii.hbmpItem = BitmapFromIcon(hIcon);
548 if (mii.hbmpItem)
549 mii.fMask |= MIIM_BITMAP;
550 }
551
552 InsertMenuItem(hMenu, -1, TRUE, &mii);
554 }
555
557
558 return hMenu;
559}
#define TRUE
Definition: types.h:120
static HBITMAP BitmapFromIcon(HICON hIcon)
Definition: kbswitch.c:306
static VOID GetKLIDFromHKL(HKL hKL, LPTSTR szKLID, SIZE_T KLIDLength)
Definition: kbswitch.c:114
HKL g_ahKLs[64]
Definition: kbswitch.c:49
INT g_cKLs
Definition: kbswitch.c:48
static HICON
Definition: imagelist.c:84
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
LPSTR dwTypeData
Definition: winuser.h:3250
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define MIIM_STRING
Definition: winuser.h:727
#define MIIM_ID
Definition: winuser.h:722
#define InsertMenuItem
Definition: winuser.h:5803
#define MF_CHECKED
Definition: winuser.h:132
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define MIIM_BITMAP
Definition: winuser.h:728

Referenced by WndProc().

◆ CreateTrayIcon()

static HICON CreateTrayIcon ( LPTSTR  szKLID,
LPCTSTR szImeFile  OPTIONAL 
)
static

Definition at line 328 of file kbswitch.c.

329{
331 TCHAR szBuf[4];
332 HDC hdcScreen, hdc;
333 HBITMAP hbmColor, hbmMono, hBmpOld;
334 HFONT hFont, hFontOld;
335 LOGFONT lf;
336 RECT rect;
338 HICON hIcon;
342
343 if (szImeFile && szImeFile[0])
344 {
346 return FakeExtractIcon(szPath, cxIcon, cyIcon);
347 }
348
349 /* Getting "EN", "FR", etc. from English, French, ... */
350 LangID = LANGIDFROMLCID(_tcstoul(szKLID, NULL, 16));
353 szBuf,
354 ARRAYSIZE(szBuf)) == 0)
355 {
356 szBuf[0] = szBuf[1] = _T('?');
357 }
358 szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
359
360 /* Create hdc, hbmColor and hbmMono */
361 hdcScreen = GetDC(NULL);
362 hdc = CreateCompatibleDC(hdcScreen);
363 hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
364 ReleaseDC(NULL, hdcScreen);
365 hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
366
367 /* Checking NULL */
368 if (!hdc || !hbmColor || !hbmMono)
369 {
370 if (hbmMono)
371 DeleteObject(hbmMono);
372 if (hbmColor)
373 DeleteObject(hbmColor);
374 if (hdc)
375 DeleteDC(hdc);
376 return NULL;
377 }
378
379 /* Create a font */
380 hFont = NULL;
381 if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
382 {
383 /* Override the current size with something manageable */
384 lf.lfHeight = -11;
385 lf.lfWidth = 0;
387 }
388 if (!hFont)
390
391 SetRect(&rect, 0, 0, cxIcon, cyIcon);
392
393 /* Draw hbmColor */
394 hBmpOld = SelectObject(hdc, hbmColor);
396 FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
397 hFontOld = SelectObject(hdc, hFont);
401 SelectObject(hdc, hFontOld);
402
403 /* Fill hbmMono with black */
404 SelectObject(hdc, hbmMono);
405 PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
406 SelectObject(hdc, hBmpOld);
407
408 /* Create an icon from hbmColor and hbmMono */
411 IconInfo.hbmColor = hbmColor;
412 IconInfo.hbmMask = hbmMono;
414
415 /* Clean up */
417 DeleteObject(hbmMono);
418 DeleteObject(hbmColor);
419 DeleteDC(hdc);
420
421 return hIcon;
422}
HFONT hFont
Definition: main.c:53
pKey DeleteObject()
_Out_opt_ PICONINFO IconInfo
Definition: ntuser.h:2321
static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
Definition: kbswitch.c:294
static BOOL GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
Definition: kbswitch.c:193
LPCWSTR szPath
Definition: env.c:37
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define LANGIDFROMLCID(l)
Definition: nls.h:18
& rect
Definition: startmenu.cpp:1413
LONG lfHeight
Definition: dimm.idl:42
LONG lfWidth
Definition: dimm.idl:43
DWORD yHotspot
Definition: winuser.h:3124
BOOL fIcon
Definition: winuser.h:3122
DWORD xHotspot
Definition: winuser.h:3123
HBITMAP hbmColor
Definition: winuser.h:3126
HBITMAP hbmMask
Definition: winuser.h:3125
#define _T(x)
Definition: vfdio.h:22
COLORREF WINAPI SetDCBrushColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: dc.c:905
#define BLACKNESS
Definition: wingdi.h:323
HGDIOBJ WINAPI GetStockObject(_In_ int)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
#define TRANSPARENT
Definition: wingdi.h:950
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define CreateFontIndirect
Definition: wingdi.h:4444
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:28
DWORD WINAPI GetSysColor(_In_ int)
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2550
#define DT_CENTER
Definition: winuser.h:527
#define COLOR_HIGHLIGHT
Definition: winuser.h:925
#define DT_SINGLELINE
Definition: winuser.h:540
#define SPI_GETICONTITLELOGFONT
Definition: winuser.h:1379
#define DrawText
Definition: winuser.h:5770
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:926
#define DT_VCENTER
Definition: winuser.h:543
#define SystemParametersInfo
Definition: winuser.h:5857
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)

Referenced by AddTrayIcon(), BuildLeftPopupMenu(), and UpdateTrayIcon().

◆ DeleteHooks()

VOID DeleteHooks ( VOID  )

Definition at line 582 of file kbswitch.c.

583{
585 {
588 }
589 if (g_hHookDLL)
590 {
593 }
594}
#define FreeLibrary(x)
Definition: compat.h:748
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks
Definition: kbswitch.c:39
HMODULE g_hHookDLL
Definition: kbswitch.c:44

Referenced by WndProc().

◆ DeleteTrayIcon()

static VOID DeleteTrayIcon ( HWND  hwnd)
static

Definition at line 446 of file kbswitch.c.

447{
448 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1 };
450
451 if (g_hTrayIcon)
452 {
455 }
456}
#define NIM_DELETE
Definition: shellapi.h:93

Referenced by WndProc().

◆ EnumResNameProc()

static BOOL CALLBACK EnumResNameProc ( HMODULE  hModule,
LPCTSTR  lpszType,
LPTSTR  lpszName,
LPARAM  lParam 
)
static

Definition at line 279 of file kbswitch.c.

284{
285 PLOAD_ICON pLoadIcon = (PLOAD_ICON)lParam;
286 pLoadIcon->hIcon = (HICON)LoadImage(hModule, lpszName, IMAGE_ICON,
287 pLoadIcon->cxIcon, pLoadIcon->cyIcon,
289 if (pLoadIcon->hIcon)
290 return FALSE; /* Stop enumeration */
291 return TRUE;
292}
LPARAM lParam
Definition: combotst.c:139
HMODULE hModule
Definition: animate.c:44
struct tagLOAD_ICON * PLOAD_ICON
HICON hIcon
Definition: kbswitch.c:275
#define IMAGE_ICON
Definition: winuser.h:212
#define LoadImage
Definition: winuser.h:5814
#define LR_DEFAULTCOLOR
Definition: winuser.h:1086

Referenced by FakeExtractIcon().

◆ EnumWindowsProc()

static BOOL CALLBACK EnumWindowsProc ( HWND  hwnd,
LPARAM  lParam 
)
static

Definition at line 478 of file kbswitch.c.

479{
480 PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET, lParam);
481 return TRUE;
482}

Referenced by ActivateLayout().

◆ FakeExtractIcon()

static HICON FakeExtractIcon ( LPCTSTR  szIconPath,
INT  cxIcon,
INT  cyIcon 
)
static

Definition at line 294 of file kbswitch.c.

295{
296 LOAD_ICON LoadIcon = { cxIcon, cyIcon, NULL };
297 HMODULE hImeDLL = LoadLibraryEx(szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
298 if (hImeDLL)
299 {
301 FreeLibrary(hImeDLL);
302 }
303 return LoadIcon.hIcon;
304}
static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LPARAM lParam)
Definition: kbswitch.c:279
#define RT_GROUP_ICON
Definition: pedump.c:375
#define LoadLibraryEx
Definition: winbase.h:3798
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:342
#define EnumResourceNames
Definition: winbase.h:3707
#define LoadIcon
Definition: winuser.h:5812

Referenced by CreateTrayIcon().

◆ GetHKLFromLayoutNum()

static HKL GetHKLFromLayoutNum ( INT  nLayoutNum)
static

Definition at line 172 of file kbswitch.c.

173{
174 if (0 <= (nLayoutNum - 1) && (nLayoutNum - 1) < g_cKLs)
175 {
176 return g_ahKLs[nLayoutNum - 1];
177 }
178 else
179 {
181 DWORD dwTID = GetWindowThreadProcessId(hwndTarget, NULL);
182 return GetKeyboardLayout(dwTID);
183 }
184}
unsigned long DWORD
Definition: ntddk_ex.h:95
HWND g_hwndLastActive
Definition: kbswitch.c:47
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392

Referenced by GetKLIDFromLayoutNum().

◆ GetImeFile()

static BOOL GetImeFile ( LPTSTR  szImeFile,
SIZE_T  cchImeFile,
LPCTSTR  szKLID 
)
static

Definition at line 240 of file kbswitch.c.

241{
242 HKEY hKey;
244 TCHAR szBuf[MAX_PATH];
245
246 szImeFile[0] = UNICODE_NULL;
247
248 if (_tcslen(szKLID) != CCH_LAYOUT_ID)
249 return FALSE; /* Invalid LCID */
250
251 if (szKLID[0] != TEXT('E') && szKLID[0] != TEXT('e'))
252 return FALSE; /* Not an IME HKL */
253
254 StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
255 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
256
258 return FALSE;
259
260 dwBufLen = cchImeFile * sizeof(TCHAR);
261 if (RegQueryValueEx(hKey, _T("IME File"), NULL, NULL,
262 (LPBYTE)szImeFile, &dwBufLen) != ERROR_SUCCESS)
263 {
264 szImeFile[0] = UNICODE_NULL;
265 }
266
268
269 return (szImeFile[0] != UNICODE_NULL);
270}
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
FxAutoRegKey hKey
#define TEXT(s)
Definition: k32.h:26
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define UNICODE_NULL
#define StringCchPrintf
Definition: strsafe.h:517
unsigned char * LPBYTE
Definition: typedefs.h:53
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4246
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RegOpenKeyEx
Definition: winreg.h:520
#define RegQueryValueEx
Definition: winreg.h:524
#define _tcslen
Definition: xmlstorage.h:198

Referenced by AddTrayIcon(), BuildLeftPopupMenu(), and UpdateTrayIcon().

◆ GetKLIDFromHKL()

static VOID GetKLIDFromHKL ( HKL  hKL,
LPTSTR  szKLID,
SIZE_T  KLIDLength 
)
static

Definition at line 114 of file kbswitch.c.

115{
116 szKLID[0] = 0;
117
118 if (IS_IME_HKL(hKL))
119 {
120 StringCchPrintf(szKLID, KLIDLength, _T("%08lx"), (DWORD)(DWORD_PTR)hKL);
121 return;
122 }
123
124 if (IS_SPECIAL_HKL(hKL))
125 {
126 INT i;
127 for (i = 0; i < g_cSpecialIds; ++i)
128 {
129 if (g_SpecialIds[i].hKL == hKL)
130 {
131 StringCchCopy(szKLID, KLIDLength, g_SpecialIds[i].szKLID);
132 return;
133 }
134 }
135 }
136 else
137 {
138 StringCchPrintf(szKLID, KLIDLength, _T("%08lx"), LOWORD(hKL));
139 }
140}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
INT g_cSpecialIds
Definition: kbswitch.c:59
#define IS_SPECIAL_HKL(hKL)
Definition: kbswitch.c:33
SPECIAL_ID g_SpecialIds[80]
Definition: kbswitch.c:58
#define IS_IME_HKL(hKL)
Definition: kbswitch.c:32
#define LOWORD(l)
Definition: pedump.c:82
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by BuildLeftPopupMenu(), GetKLIDFromLayoutNum(), and UpdateLanguageDisplay().

◆ GetKLIDFromLayoutNum()

static VOID GetKLIDFromLayoutNum ( INT  nLayoutNum,
LPTSTR  szKLID,
SIZE_T  KLIDLength 
)
static

Definition at line 187 of file kbswitch.c.

188{
189 GetKLIDFromHKL(GetHKLFromLayoutNum(nLayoutNum), szKLID, KLIDLength);
190}
static HKL GetHKLFromLayoutNum(INT nLayoutNum)
Definition: kbswitch.c:172

Referenced by ActivateLayout(), AddTrayIcon(), and GetLayoutName().

◆ GetLayoutName()

static BOOL GetLayoutName ( INT  nLayoutNum,
LPTSTR  szName,
SIZE_T  NameLength 
)
static

Definition at line 204 of file kbswitch.c.

205{
206 HKEY hKey;
207 HRESULT hr;
209 TCHAR szBuf[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1];
210
211 GetKLIDFromLayoutNum(nLayoutNum, szKLID, ARRAYSIZE(szKLID));
212
213 StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
214 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
215
217 return FALSE;
218
219 /* Use "Layout Display Name" value as an entry name if possible */
220 hr = SHLoadRegUIString(hKey, _T("Layout Display Name"), szName, NameLength);
221 if (SUCCEEDED(hr))
222 {
224 return TRUE;
225 }
226
227 /* Otherwise, use "Layout Text" value as an entry name */
228 dwBufLen = NameLength * sizeof(TCHAR);
229 if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL,
231 {
233 return TRUE;
234 }
235
237 return FALSE;
238}
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define KEY_READ
Definition: nt_native.h:1023
HRESULT hr
Definition: shlfolder.c:183
#define SHLoadRegUIString

Referenced by AddTrayIcon(), and BuildLeftPopupMenu().

◆ GetLayoutNum()

static UINT GetLayoutNum ( HKL  hKL)
static

Definition at line 596 of file kbswitch.c.

597{
598 INT iKL;
599
600 for (iKL = 0; iKL < g_cKLs; ++iKL)
601 {
602 if (g_ahKLs[iKL] == hKL)
603 return iKL + 1;
604 }
605
606 return 0;
607}

Referenced by UpdateLanguageDisplay(), and WndProc().

◆ GetNextLayout()

ULONG GetNextLayout ( VOID  )

Definition at line 610 of file kbswitch.c.

611{
612 return (g_nCurrentLayoutNum % g_cKLs) + 1;
613}

Referenced by WndProc().

◆ GetSystemLibraryPath()

static BOOL GetSystemLibraryPath ( LPTSTR  szPath,
SIZE_T  cchPath,
LPCTSTR  FileName 
)
static

Definition at line 193 of file kbswitch.c.

194{
195 if (!GetSystemDirectory(szPath, cchPath))
196 return FALSE;
197
198 StringCchCat(szPath, cchPath, TEXT("\\"));
199 StringCchCat(szPath, cchPath, FileName);
200 return TRUE;
201}
#define StringCchCat
Definition: strsafe.h:317
#define GetSystemDirectory
Definition: winbase.h:3777

Referenced by CreateTrayIcon(), and LayoutList_ReadLayout().

◆ GetTargetWindow()

HWND GetTargetWindow ( HWND  hwndFore)

Definition at line 631 of file kbswitch.c.

632{
633 TCHAR szClass[64];
634 HWND hwndIME;
635 HWND hwndTarget = hwndFore;
636 if (hwndTarget == NULL)
637 hwndTarget = GetForegroundWindow();
638
639 GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass));
640 if (_tcsicmp(szClass, szKbSwitcherName) == 0)
641 hwndTarget = g_hwndLastActive;
642
643 hwndIME = ImmGetDefaultIMEWnd(hwndTarget);
644 return (hwndIME ? hwndIME : hwndTarget);
645}
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
Definition: ime.c:890
#define GetClassName
Definition: winuser.h:5782
#define _tcsicmp
Definition: xmlstorage.h:205

Referenced by UpdateLanguageDisplayCurrent().

◆ LoadSpecialIds()

static VOID LoadSpecialIds ( VOID  )
static

Definition at line 61 of file kbswitch.c.

62{
63 TCHAR szKLID[KL_NAMELENGTH], szLayoutId[16];
64 DWORD dwSize, dwIndex;
65 HKEY hKey, hLayoutKey;
66
67 g_cSpecialIds = 0;
68
70 TEXT("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"),
72 {
73 return;
74 }
75
76 for (dwIndex = 0; dwIndex < 1000; ++dwIndex)
77 {
78 dwSize = ARRAYSIZE(szKLID);
79 if (RegEnumKeyEx(hKey, dwIndex, szKLID, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
80 break;
81
82 if (RegOpenKeyEx(hKey, szKLID, 0, KEY_READ, &hLayoutKey) != ERROR_SUCCESS)
83 continue;
84
85 dwSize = sizeof(szLayoutId);
86 if (RegQueryValueEx(hLayoutKey, TEXT("Layout Id"), NULL, NULL,
87 (LPBYTE)szLayoutId, &dwSize) == ERROR_SUCCESS)
88 {
89 DWORD dwKLID = _tcstoul(szKLID, NULL, 16);
90 WORD wLangId = LOWORD(dwKLID), wLayoutId = LOWORD(_tcstoul(szLayoutId, NULL, 16));
91 HKL hKL = (HKL)(LONG_PTR)(SPECIAL_MASK | MAKELONG(wLangId, wLayoutId));
92
93 /* Add a special ID */
97 ARRAYSIZE(g_SpecialIds[g_cSpecialIds].szKLID), szKLID);
99 }
100
101 RegCloseKey(hLayoutKey);
102
104 {
105 OutputDebugStringA("g_SpecialIds is full!");
106 break;
107 }
108 }
109
111}
unsigned short WORD
Definition: ntddk_ex.h:93
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
#define SPECIAL_MASK
Definition: kbswitch.c:30
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
DWORD dwLayoutId
Definition: kbswitch.c:53
HKL hKL
Definition: kbswitch.c:54
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define RegEnumKeyEx
Definition: winreg.h:510
#define KL_NAMELENGTH
Definition: winuser.h:122

Referenced by WndProc().

◆ RememberLastActive()

static BOOL RememberLastActive ( HWND  hwnd,
HWND  hwndFore 
)
static

Definition at line 657 of file kbswitch.c.

658{
659 TCHAR szClass[64];
660
661 hwndFore = GetAncestor(hwndFore, GA_ROOT);
662
663 if (!IsWindowVisible(hwndFore) || !GetClassName(hwndFore, szClass, ARRAYSIZE(szClass)))
664 return FALSE;
665
666 if (_tcsicmp(szClass, szKbSwitcherName) == 0 ||
667 _tcsicmp(szClass, TEXT("Shell_TrayWnd")) == 0)
668 {
669 return FALSE; /* Special window */
670 }
671
672 /* FIXME: CONWND needs special handling */
673 if (_tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
674 {
675 HKL hKL = GetKeyboardLayout(0);
677 }
678
679 g_hwndLastActive = hwndFore;
680 return TRUE;
681}
UINT UpdateLanguageDisplay(HWND hwnd, HKL hKL)
Definition: kbswitch.c:616
#define GA_ROOT
Definition: winuser.h:2788
BOOL WINAPI IsWindowVisible(_In_ HWND)
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)

Referenced by WndProc().

◆ SetHooks()

BOOL SetHooks ( VOID  )

Definition at line 562 of file kbswitch.c.

563{
564 g_hHookDLL = LoadLibrary(_T("kbsdll.dll"));
565 if (!g_hHookDLL)
566 {
567 return FALSE;
568 }
569
572
574 {
575 return FALSE;
576 }
577
578 return KbSwitchSetHooks();
579}
#define GetProcAddress(x, y)
Definition: compat.h:753
PKBSWITCHSETHOOKS KbSwitchSetHooks
Definition: kbswitch.c:38
BOOL(WINAPI * PKBSWITCHSETHOOKS)(VOID)
Definition: kbswitch.h:26
VOID(WINAPI * PKBSWITCHDELETEHOOKS)(VOID)
Definition: kbswitch.h:27
#define LoadLibrary
Definition: winbase.h:3797

Referenced by WndProc().

◆ UpdateLanguageDisplay()

UINT UpdateLanguageDisplay ( HWND  hwnd,
HKL  hKL 
)

Definition at line 616 of file kbswitch.c.

617{
618 TCHAR szKLID[MAX_PATH], szLangName[MAX_PATH];
620
621 GetKLIDFromHKL(hKL, szKLID, ARRAYSIZE(szKLID));
622 LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
623 GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
624 UpdateTrayIcon(hwnd, szKLID, szLangName);
626
627 return 0;
628}
static UINT GetLayoutNum(HKL hKL)
Definition: kbswitch.c:596

Referenced by RememberLastActive(), UpdateLanguageDisplayCurrent(), and WndProc().

◆ UpdateLanguageDisplayCurrent()

UINT UpdateLanguageDisplayCurrent ( HWND  hwnd,
HWND  hwndFore 
)

Definition at line 648 of file kbswitch.c.

649{
650 DWORD dwThreadID = GetWindowThreadProcessId(GetTargetWindow(hwndFore), NULL);
651 HKL hKL = GetKeyboardLayout(dwThreadID);
653
654 return 0;
655}
HWND GetTargetWindow(HWND hwndFore)
Definition: kbswitch.c:631

Referenced by WndProc().

◆ UpdateLayoutList()

static VOID UpdateLayoutList ( HKL hKL  OPTIONAL)
static

Definition at line 142 of file kbswitch.c.

143{
144 INT iKL;
145
146 if (!hKL)
147 {
149 DWORD dwTID = GetWindowThreadProcessId(hwndTarget, NULL);
150 hKL = GetKeyboardLayout(dwTID);
151 }
152
154
156 for (iKL = 0; iKL < g_cKLs; ++iKL)
157 {
158 if (g_ahKLs[iKL] == hKL)
159 {
160 g_nCurrentLayoutNum = iKL + 1;
161 break;
162 }
163 }
164
166 {
168 g_ahKLs[g_cKLs++] = hKL;
169 }
170}
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)

Referenced by WndProc().

◆ UpdateTrayIcon()

static VOID UpdateTrayIcon ( HWND  hwnd,
LPTSTR  szKLID,
LPTSTR  szName 
)
static

Definition at line 459 of file kbswitch.c.

460{
461 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
462 TCHAR szImeFile[80];
463
464 GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szKLID);
465
467 tnid.hIcon = CreateTrayIcon(szKLID, szImeFile);
469
471
472 if (g_hTrayIcon)
474 g_hTrayIcon = tnid.hIcon;
475}
#define NIM_MODIFY
Definition: shellapi.h:92

Referenced by ActivateLayout(), AddJobW(), StartDocPrinterW(), and UpdateLanguageDisplay().

◆ WndProc()

LRESULT CALLBACK WndProc ( HWND  hwnd,
UINT  Message,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 684 of file kbswitch.c.

685{
686 static HMENU s_hMenu = NULL, s_hRightPopupMenu = NULL;
687 static UINT s_uTaskbarRestart;
688 POINT pt;
689 HMENU hLeftPopupMenu;
690
691 switch (Message)
692 {
693 case WM_CREATE:
694 {
695 if (!SetHooks())
696 {
697 MessageBox(NULL, TEXT("SetHooks failed."), NULL, MB_ICONERROR);
698 return -1;
699 }
700
702
705
707 s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
708 break;
709 }
710
711 case WM_LANG_CHANGED: /* Comes from kbsdll.dll and this module */
712 {
715 break;
716 }
717
718 case WM_WINDOW_ACTIVATE: /* Comes from kbsdll.dll and this module */
719 {
720 HWND hwndFore = GetForegroundWindow();
721 if (RememberLastActive(hwnd, hwndFore))
722 return UpdateLanguageDisplayCurrent(hwnd, hwndFore);
723 break;
724 }
725
726 case WM_NOTIFYICONMSG:
727 {
728 switch (lParam)
729 {
730 case WM_RBUTTONUP:
731 case WM_LBUTTONUP:
732 {
734
737
738 if (lParam == WM_LBUTTONUP)
739 {
740 /* Rebuild the left popup menu on every click to take care of keyboard layout changes */
741 hLeftPopupMenu = BuildLeftPopupMenu();
742 TrackPopupMenu(hLeftPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
743 DestroyMenu(hLeftPopupMenu);
744 }
745 else
746 {
747 if (!s_hRightPopupMenu)
748 {
750 s_hRightPopupMenu = GetSubMenu(s_hMenu, 0);
751 }
752 TrackPopupMenu(s_hRightPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
753 }
754
755 PostMessage(hwnd, WM_NULL, 0, 0);
756 break;
757 }
758 }
759 break;
760 }
761
762 case WM_COMMAND:
763 switch (LOWORD(wParam))
764 {
765 case ID_EXIT:
766 {
767 PostMessage(hwnd, WM_CLOSE, 0, 0);
768 break;
769 }
770
771 case ID_PREFERENCES:
772 {
774 TEXT("control.exe"), TEXT("input.dll"),
776 if (ret <= 32)
777 MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_ICONERROR);
778 break;
779 }
780
781 case ID_NEXTLAYOUT:
782 {
783 HWND hwndTarget = (HWND)lParam, hwndTargetSave = NULL;
784 DWORD dwThreadID;
785 HKL hKL;
786 UINT uNum;
787 TCHAR szClass[64];
788 BOOL bCONWND = FALSE;
789
790 if (hwndTarget == NULL)
791 hwndTarget = g_hwndLastActive;
792
793 /* FIXME: CONWND needs special handling */
794 if (hwndTarget &&
795 GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass)) &&
796 _tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
797 {
798 bCONWND = TRUE;
799 hwndTargetSave = hwndTarget;
800 hwndTarget = NULL;
801 }
802
803 if (hwndTarget)
804 {
805 dwThreadID = GetWindowThreadProcessId(hwndTarget, NULL);
806 hKL = GetKeyboardLayout(dwThreadID);
807 uNum = GetLayoutNum(hKL);
808 if (uNum != 0)
809 g_nCurrentLayoutNum = uNum;
810 }
811
812 ActivateLayout(hwnd, GetNextLayout(), hwndTarget, TRUE);
813
814 /* FIXME: CONWND needs special handling */
815 if (bCONWND)
816 ActivateLayout(hwnd, g_nCurrentLayoutNum, hwndTargetSave, TRUE);
817
818 break;
819 }
820
821 default:
822 {
823 if (1 <= LOWORD(wParam) && LOWORD(wParam) <= 1000)
824 {
826 {
828 }
830 }
831 break;
832 }
833 }
834 break;
835
836 case WM_SETTINGCHANGE:
837 {
838 if (wParam == SPI_SETNONCLIENTMETRICS)
839 {
841 break;
842 }
843 }
844 break;
845
846 case WM_DESTROY:
847 {
848 DeleteHooks();
849 DestroyMenu(s_hMenu);
852 break;
853 }
854
855 default:
856 {
857 if (Message == s_uTaskbarRestart)
858 {
861 break;
862 }
863 else if (Message == ShellHookMessage)
864 {
865 if (wParam == HSHELL_LANGUAGE)
867 else if (wParam == HSHELL_WINDOWACTIVATED)
869
870 break;
871 }
873 }
874 }
875
876 return 0;
877}
#define ID_NEXTLAYOUT
Definition: resource.h:12
#define ID_EXIT
Definition: resource.h:10
#define ID_PREFERENCES
Definition: resource.h:11
#define IDR_POPUP
Definition: resource.h:7
WPARAM wParam
Definition: combotst.c:138
HANDLE HWND
Definition: compat.h:19
static const WCHAR Message[]
Definition: register.c:74
#define pt(x, y)
Definition: drawing.c:79
unsigned int BOOL
Definition: ntddk_ex.h:94
static VOID LoadSpecialIds(VOID)
Definition: kbswitch.c:61
static HMENU BuildLeftPopupMenu(VOID)
Definition: kbswitch.c:524
static BOOL RememberLastActive(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:657
static VOID UpdateLayoutList(HKL hKL OPTIONAL)
Definition: kbswitch.c:142
static VOID ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
Definition: kbswitch.c:485
ULONG GetNextLayout(VOID)
Definition: kbswitch.c:610
VOID DeleteHooks(VOID)
Definition: kbswitch.c:582
UINT UpdateLanguageDisplayCurrent(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:648
BOOL SetHooks(VOID)
Definition: kbswitch.c:562
static VOID AddTrayIcon(HWND hwnd)
Definition: kbswitch.c:425
static VOID DeleteTrayIcon(HWND hwnd)
Definition: kbswitch.c:446
#define WM_WINDOW_ACTIVATE
Definition: kbswitch.h:24
#define WM_LANG_CHANGED
Definition: kbswitch.h:23
unsigned int UINT
Definition: ndis.h:50
#define DefWindowProc
Definition: ros2win.h:31
#define ShellExecute
Definition: shellapi.h:690
int32_t INT_PTR
Definition: typedefs.h:64
int ret
#define SW_SHOWNORMAL
Definition: winuser.h:769
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_CLOSE
Definition: winuser.h:1620
#define WM_CREATE
Definition: winuser.h:1607
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define WM_COMMAND
Definition: winuser.h:1739
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2639
#define WM_RBUTTONUP
Definition: winuser.h:1779
#define MB_ICONERROR
Definition: winuser.h:786
#define WM_SETTINGCHANGE
Definition: winuser.h:1628
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define WM_NULL
Definition: winuser.h:1606
#define LoadMenu
Definition: winuser.h:5816
#define WM_LBUTTONUP
Definition: winuser.h:1776
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MessageBox
Definition: winuser.h:5821
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define WM_DESTROY
Definition: winuser.h:1608
#define MAKEINTRESOURCE
Definition: winuser.h:591

Referenced by _tWinMain().

Variable Documentation

◆ g_ahKLs

HKL g_ahKLs[64]

Definition at line 49 of file kbswitch.c.

Referenced by BuildLeftPopupMenu(), GetHKLFromLayoutNum(), GetLayoutNum(), and UpdateLayoutList().

◆ g_cKLs

INT g_cKLs = 0

◆ g_cSpecialIds

INT g_cSpecialIds = 0

Definition at line 59 of file kbswitch.c.

Referenced by GetKLIDFromHKL(), and LoadSpecialIds().

◆ g_hHookDLL

HMODULE g_hHookDLL = NULL

Definition at line 44 of file kbswitch.c.

Referenced by DeleteHooks(), and SetHooks().

◆ g_hTrayIcon

HICON g_hTrayIcon = NULL

Definition at line 46 of file kbswitch.c.

Referenced by AddTrayIcon(), DeleteTrayIcon(), and UpdateTrayIcon().

◆ g_hwndLastActive

HWND g_hwndLastActive = NULL

◆ g_nCurrentLayoutNum

INT g_nCurrentLayoutNum = 1

◆ g_SpecialIds

SPECIAL_ID g_SpecialIds[80]

Definition at line 58 of file kbswitch.c.

Referenced by GetKLIDFromHKL(), and LoadSpecialIds().

◆ hInst

HINSTANCE hInst

Definition at line 42 of file kbswitch.c.

Referenced by _tWinMain(), and WndProc().

◆ hProcessHeap

◆ KbSwitchDeleteHooks

PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL

Definition at line 39 of file kbswitch.c.

Referenced by DeleteHooks(), and SetHooks().

◆ KbSwitchSetHooks

PKBSWITCHSETHOOKS KbSwitchSetHooks = NULL

Definition at line 38 of file kbswitch.c.

Referenced by SetHooks().

◆ ShellHookMessage

UINT ShellHookMessage = 0

Definition at line 40 of file kbswitch.c.

Referenced by _tWinMain(), and WndProc().