ReactOS  0.4.15-dev-5130-gc1c1279
kbswitch.c File Reference
#include "kbswitch.h"
Include dependency graph for kbswitch.c:

Go to the source code of this file.

Macros

#define WM_NOTIFYICONMSG   (WM_USER + 248)
 

Functions

static BOOL GetLayoutID (LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
 
static BOOL GetLayoutName (LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
 
static HICON CreateTrayIcon (LPTSTR szLCID)
 
static VOID AddTrayIcon (HWND hwnd)
 
static VOID DeleteTrayIcon (HWND hwnd)
 
static VOID UpdateTrayIcon (HWND hwnd, LPTSTR szLCID, LPTSTR szName)
 
static VOID GetLayoutIDByHkl (HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength)
 
static BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
 
static VOID ActivateLayout (HWND hwnd, ULONG uLayoutNum)
 
static HMENU BuildLeftPopupMenu (VOID)
 
static ULONG GetMaxLayoutNum (VOID)
 
BOOL SetHooks (VOID)
 
VOID DeleteHooks (VOID)
 
ULONG GetNextLayout (VOID)
 
LRESULT UpdateLanguageDisplay (HWND hwnd, HKL hKl)
 
LRESULT UpdateLanguageDisplayCurrent (HWND hwnd, WPARAM wParam)
 
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
 
ULONG ulCurrentLayoutNum = 1
 
HICON g_hTrayIcon = NULL
 

Macro Definition Documentation

◆ WM_NOTIFYICONMSG

#define WM_NOTIFYICONMSG   (WM_USER + 248)

Definition at line 12 of file kbswitch.c.

Function Documentation

◆ _tWinMain()

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

Definition at line 613 of file kbswitch.c.

614 {
616  MSG msg;
617  HANDLE hMutex;
618  HWND hwnd;
619 
620  switch (GetUserDefaultUILanguage())
621  {
624  break;
625  default:
626  break;
627  }
628 
630  if (!hMutex)
631  return 1;
632 
634  {
636  return 1;
637  }
638 
639  hInst = hInstance;
641 
642  ZeroMemory(&WndClass, sizeof(WndClass));
643  WndClass.lpfnWndProc = WndProc;
644  WndClass.hInstance = hInstance;
645  WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
646  WndClass.lpszClassName = szKbSwitcherName;
647  if (!RegisterClass(&WndClass))
648  {
650  return 1;
651  }
652 
656 
657  while (GetMessage(&msg, NULL, 0, 0))
658  {
661  }
662 
664  return 0;
665 }
#define DispatchMessage
Definition: winuser.h:5755
LANGID WINAPI GetUserDefaultUILanguage(void)
Definition: lang.c:810
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define CloseHandle
Definition: compat.h:598
#define LAYOUT_RTL
Definition: wingdi.h:1371
#define CreateWindow
Definition: winuser.h:5744
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define SUBLANG_DEFAULT
Definition: nls.h:168
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1667
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:462
#define LANG_HEBREW
Definition: nls.h:67
HINSTANCE hInstance
Definition: charmap.c:20
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
HANDLE hMutex
Definition: mutex.c:11
HINSTANCE hInst
Definition: kbswitch.c:18
BOOL WINAPI SetProcessDefaultLayout(DWORD dwDefaultLayout)
Definition: window.c:1720
#define GetProcessHeap()
Definition: compat.h:595
#define CreateMutex
Definition: winbase.h:3617
BOOL WINAPI RegisterShellHookWindow(_In_ HWND)
#define LoadCursor
Definition: winuser.h:5802
#define RegisterWindowMessage
Definition: winuser.h:5830
UINT ShellHookMessage
Definition: kbswitch.c:16
TCHAR szKbSwitcherName[]
Definition: kbswitch.h:30
#define HWND_DESKTOP
Definition: winuser.h:1199
#define NULL
Definition: types.h:112
#define GetMessage
Definition: winuser.h:5780
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define MAKELANGID(p, s)
Definition: nls.h:15
#define RegisterClass
Definition: winuser.h:5826
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
WCHAR WndClass[]
Definition: capicon.c:23
HANDLE hProcessHeap
Definition: kbswitch.c:19

◆ ActivateLayout()

static VOID ActivateLayout ( HWND  hwnd,
ULONG  uLayoutNum 
)
static

Definition at line 297 of file kbswitch.c.

298 {
299  HKL hKl;
300  TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szLCID[CCH_LAYOUT_ID + 1], szLangName[MAX_PATH];
301  LANGID LangID;
302 
303  /* The layout number starts from one. Zero is invalid */
304  if (uLayoutNum == 0 || uLayoutNum > 0xFF) /* Invalid */
305  return;
306 
307  _ultot(uLayoutNum, szLayoutNum, 10);
308  GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID));
309  LangID = (LANGID)_tcstoul(szLCID, NULL, 16);
310 
311  /* Switch to the new keyboard layout */
312  GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
313  UpdateTrayIcon(hwnd, szLCID, szLangName);
314  hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
315 
316  /* Post WM_INPUTLANGCHANGEREQUEST to every top-level window */
318 
319  ulCurrentLayoutNum = uLayoutNum;
320 }
static BOOL GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
Definition: kbswitch.c:25
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
#define LOCALE_SLANGUAGE
Definition: winnls.h:26
#define KLF_ACTIVATE
Definition: winuser.h:111
#define GetLocaleInfo
Definition: winnls.h:1186
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
WORD LANGID
Definition: typedefs.h:81
#define LoadKeyboardLayout
Definition: winuser.h:5806
#define CCH_ULONG_DEC
Definition: kbswitch.h:20
LONG_PTR LPARAM
Definition: windef.h:208
char TCHAR
Definition: xmlstorage.h:189
static VOID UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
Definition: kbswitch.c:268
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define _tcstoul
Definition: tchar.h:595
UINT_PTR HKL
Definition: msctf.idl:101
ULONG ulCurrentLayoutNum
Definition: kbswitch.c:21
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: kbswitch.c:290
#define NULL
Definition: types.h:112
#define _ultot
Definition: tchar.h:610
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
_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:1075

Referenced by WndProc().

◆ AddTrayIcon()

static VOID AddTrayIcon ( HWND  hwnd)
static

Definition at line 235 of file kbswitch.c.

236 {
237  NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
238  TCHAR szLCID[CCH_LAYOUT_ID + 1], szName[MAX_PATH];
239 
240  GetLayoutID(_T("1"), szLCID, ARRAYSIZE(szLCID));
242 
244  tnid.hIcon = CreateTrayIcon(szLCID);
245  StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
246 
247  Shell_NotifyIcon(NIM_ADD, &tnid);
248 
249  if (g_hTrayIcon)
251  g_hTrayIcon = tnid.hIcon;
252 }
static HICON CreateTrayIcon(LPTSTR szLCID)
Definition: kbswitch.c:145
#define NIF_MESSAGE
Definition: shellapi.h:102
static const WCHAR szName[]
Definition: powrprof.c:45
static BOOL GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
Definition: kbswitch.c:25
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:12
CHAR szTip[128]
Definition: shellapi.h:235
#define NIF_TIP
Definition: shellapi.h:104
#define NIF_ICON
Definition: shellapi.h:103
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define MAX_PATH
Definition: compat.h:34
HICON g_hTrayIcon
Definition: kbswitch.c:22
#define StringCchCopy
Definition: strsafe.h:139
UINT uCallbackMessage
Definition: shellapi.h:229
static BOOL GetLayoutName(LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
Definition: kbswitch.c:69
#define NIM_ADD
Definition: shellapi.h:91
#define Shell_NotifyIcon
Definition: shellapi.h:689
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022

Referenced by WndProc().

◆ BuildLeftPopupMenu()

static HMENU BuildLeftPopupMenu ( VOID  )
static

Definition at line 323 of file kbswitch.c.

324 {
325  HMENU hMenu = CreatePopupMenu();
326  HKEY hKey;
327  DWORD dwIndex, dwSize;
328  TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szName[MAX_PATH];
329 
330  /* Add the keyboard layouts to the popup menu */
331  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
333  {
334  for (dwIndex = 0; ; dwIndex++)
335  {
336  dwSize = sizeof(szLayoutNum);
337  if (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL,
338  NULL, NULL) != ERROR_SUCCESS)
339  {
340  break;
341  }
342 
343  if (!GetLayoutName(szLayoutNum, szName, ARRAYSIZE(szName)))
344  break;
345 
346  AppendMenu(hMenu, MF_STRING, _ttoi(szLayoutNum), szName);
347  }
348 
350 
351  RegCloseKey(hKey);
352  }
353 
354  return hMenu;
355 }
static const WCHAR szName[]
Definition: powrprof.c:45
#define ERROR_SUCCESS
Definition: deptool.c:10
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define MF_STRING
Definition: winuser.h:138
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CCH_ULONG_DEC
Definition: kbswitch.h:20
#define MF_CHECKED
Definition: winuser.h:132
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define AppendMenu
Definition: winuser.h:5721
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
ULONG ulCurrentLayoutNum
Definition: kbswitch.c:21
#define RegOpenKeyEx
Definition: winreg.h:520
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
int CDECL _ttoi(const _TCHAR *str)
Definition: atoi.c:10
static BOOL GetLayoutName(LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
Definition: kbswitch.c:69
#define NULL
Definition: types.h:112
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:846
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define RegEnumValue
Definition: winreg.h:511
#define RegCloseKey(hKey)
Definition: registry.h:47
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56

Referenced by WndProc().

◆ CreateTrayIcon()

static HICON CreateTrayIcon ( LPTSTR  szLCID)
static

Definition at line 145 of file kbswitch.c.

146 {
147  LANGID LangID;
148  TCHAR szBuf[4];
149  HDC hdcScreen, hdc;
150  HBITMAP hbmColor, hbmMono, hBmpOld;
151  HFONT hFont, hFontOld;
152  LOGFONT lf;
153  RECT rect;
155  HICON hIcon;
156  INT cxIcon = GetSystemMetrics(SM_CXSMICON);
157  INT cyIcon = GetSystemMetrics(SM_CYSMICON);
158 
159  /* Getting "EN", "FR", etc. from English, French, ... */
160  LangID = LANGIDFROMLCID(_tcstoul(szLCID, NULL, 16));
161  if (GetLocaleInfo(LangID,
163  szBuf,
164  ARRAYSIZE(szBuf)) == 0)
165  {
166  szBuf[0] = szBuf[1] = _T('?');
167  }
168  szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
169 
170  /* Create hdc, hbmColor and hbmMono */
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);
176 
177  /* Checking NULL */
178  if (!hdc || !hbmColor || !hbmMono)
179  {
180  if (hbmMono)
181  DeleteObject(hbmMono);
182  if (hbmColor)
183  DeleteObject(hbmColor);
184  if (hdc)
185  DeleteDC(hdc);
186  return NULL;
187  }
188 
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)
200 
201  SetRect(&rect, 0, 0, cxIcon, cyIcon);
202 
203  /* Draw hbmColor */
204  hBmpOld = SelectObject(hdc, hbmColor);
206  FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
207  hFontOld = SelectObject(hdc, hFont);
211  SelectObject(hdc, hFontOld);
212 
213  /* Fill hbmMono with black */
214  SelectObject(hdc, hbmMono);
215  PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
216  SelectObject(hdc, hBmpOld);
217 
218  /* Create an icon from hbmColor and hbmMono */
219  IconInfo.fIcon = TRUE;
221  IconInfo.hbmColor = hbmColor;
222  IconInfo.hbmMask = hbmMono;
224 
225  /* Clean up */
227  DeleteObject(hbmMono);
228  DeleteObject(hbmColor);
229  DeleteDC(hdc);
230 
231  return hIcon;
232 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
static HICON
Definition: imagelist.c:84
#define COLOR_HIGHLIGHT
Definition: winuser.h:920
HDC WINAPI GetDC(_In_opt_ HWND)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define TRUE
Definition: types.h:120
DWORD yHotspot
Definition: winuser.h:3115
static HDC
Definition: imagelist.c:92
#define GetLocaleInfo
Definition: winnls.h:1186
#define SystemParametersInfo
Definition: winuser.h:5848
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define SM_CYSMICON
Definition: winuser.h:1007
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
WORD LANGID
Definition: typedefs.h:81
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetSysColor(_In_ int)
& rect
Definition: startmenu.cpp:1413
HFONT hFont
Definition: main.c:53
#define DrawText
Definition: winuser.h:5761
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
COLORREF WINAPI SetDCBrushColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: dc.c:905
LONG lfHeight
Definition: dimm.idl:42
HBITMAP hbmMask
Definition: winuser.h:3116
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define TRANSPARENT
Definition: wingdi.h:950
HBITMAP hbmColor
Definition: winuser.h:3117
#define DT_VCENTER
Definition: winuser.h:543
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:921
char TCHAR
Definition: xmlstorage.h:189
BOOL fIcon
Definition: winuser.h:3113
#define _T(x)
Definition: vfdio.h:22
DWORD xHotspot
Definition: winuser.h:3114
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:28
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2550
int WINAPI GetSystemMetrics(_In_ int)
LONG lfWidth
Definition: dimm.idl:43
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
#define SM_CXSMICON
Definition: winuser.h:1006
#define _tcstoul
Definition: tchar.h:595
HDC hdc
Definition: main.c:9
#define LANGIDFROMLCID(l)
Definition: nls.h:18
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define DT_SINGLELINE
Definition: winuser.h:540
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define BLACKNESS
Definition: wingdi.h:323
BOOL WINAPI DeleteDC(_In_ HDC)
HICON hIcon
Definition: msconfig.c:44
#define CreateFontIndirect
Definition: wingdi.h:4444
#define NULL
Definition: types.h:112
#define SPI_GETICONTITLELOGFONT
Definition: winuser.h:1370
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define DT_CENTER
Definition: winuser.h:527
static HBITMAP
Definition: button.c:44
_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:1075
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
_Out_opt_ PICONINFO IconInfo
Definition: ntuser.h:2389
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)

Referenced by AddTrayIcon(), and UpdateTrayIcon().

◆ DeleteHooks()

VOID DeleteHooks ( VOID  )

Definition at line 412 of file kbswitch.c.

413 {
416 }
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks
Definition: kbswitch.c:15
HMODULE g_hHookDLL
Definition: kbswitch.c:20
#define FreeLibrary(x)
Definition: compat.h:607

Referenced by WndProc().

◆ DeleteTrayIcon()

static VOID DeleteTrayIcon ( HWND  hwnd)
static

Definition at line 255 of file kbswitch.c.

256 {
257  NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1 };
259 
260  if (g_hTrayIcon)
261  {
263  g_hTrayIcon = NULL;
264  }
265 }
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define NIM_DELETE
Definition: shellapi.h:93
HICON g_hTrayIcon
Definition: kbswitch.c:22
#define NULL
Definition: types.h:112
#define Shell_NotifyIcon
Definition: shellapi.h:689
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022

Referenced by WndProc().

◆ EnumWindowsProc()

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

Definition at line 290 of file kbswitch.c.

291 {
292  PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, lParam);
293  return TRUE;
294 }
#define TRUE
Definition: types.h:120
#define PostMessage
Definition: winuser.h:5822
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
LPARAM lParam
Definition: combotst.c:139

Referenced by ActivateLayout().

◆ GetLayoutID()

static BOOL GetLayoutID ( LPCTSTR  szLayoutNum,
LPTSTR  szLCID,
SIZE_T  LCIDLength 
)
static

Definition at line 25 of file kbswitch.c.

26 {
27  DWORD dwBufLen, dwRes;
28  HKEY hKey;
29  TCHAR szTempLCID[CCH_LAYOUT_ID + 1];
30 
31  /* Get the Layout ID */
32  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE,
33  &hKey) == ERROR_SUCCESS)
34  {
35  dwBufLen = sizeof(szTempLCID);
36  dwRes = RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szTempLCID, &dwBufLen);
37  if (dwRes != ERROR_SUCCESS)
38  {
40  return FALSE;
41  }
42 
44  }
45 
46  /* Look for a substitute of this layout */
47  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0,
49  {
50  dwBufLen = sizeof(szTempLCID);
51  if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
52  {
53  /* No substitute found, then use the old LCID */
54  StringCchCopy(szLCID, LCIDLength, szTempLCID);
55  }
56 
58  }
59  else
60  {
61  /* Substitutes key couldn't be opened, so use the old LCID */
62  StringCchCopy(szLCID, LCIDLength, szTempLCID);
63  }
64 
65  return TRUE;
66 }
#define RegQueryValueEx
Definition: winreg.h:524
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
#define TRUE
Definition: types.h:120
#define HKEY_CURRENT_USER
Definition: winreg.h:11
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4245
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
unsigned long DWORD
Definition: ntddk_ex.h:95
#define StringCchCopy
Definition: strsafe.h:139
#define RegOpenKeyEx
Definition: winreg.h:520
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define NULL
Definition: types.h:112
#define RegCloseKey(hKey)
Definition: registry.h:47

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

◆ GetLayoutIDByHkl()

static VOID GetLayoutIDByHkl ( HKL  hKl,
LPTSTR  szLayoutID,
SIZE_T  LayoutIDLength 
)
static

Definition at line 284 of file kbswitch.c.

285 {
286  StringCchPrintf(szLayoutID, LayoutIDLength, _T("%08lx"), (DWORD)(DWORD_PTR)(hKl));
287 }
#define StringCchPrintf
Definition: strsafe.h:517
#define _T(x)
Definition: vfdio.h:22
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by UpdateLanguageDisplay().

◆ GetLayoutName()

static BOOL GetLayoutName ( LPCTSTR  szLayoutNum,
LPTSTR  szName,
SIZE_T  NameLength 
)
static

Definition at line 69 of file kbswitch.c.

70 {
71  HKEY hKey;
73  TCHAR szBuf[MAX_PATH], szDispName[MAX_PATH], szIndex[MAX_PATH], szPath[MAX_PATH];
74  TCHAR szLCID[CCH_LAYOUT_ID + 1];
75  HANDLE hLib;
76  UINT i, j, k;
77 
78  if (!GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID)))
79  return FALSE;
80 
81  StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
82  _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
83 
85  {
86  return FALSE;
87  }
88 
89  /* Use "Layout Display Name" value as an entry name if possible */
90  dwBufLen = sizeof(szDispName);
91  if (RegQueryValueEx(hKey, _T("Layout Display Name"), NULL, NULL,
92  (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
93  {
94  /* FIXME: Use shlwapi!SHLoadRegUIStringW instead if it was implemented */
95  if (szDispName[0] == '@')
96  {
97  size_t len = _tcslen(szDispName);
98 
99  for (i = 0; i < len; i++)
100  {
101  if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
102  {
103  for (j = i + 2, k = 0; j < _tcslen(szDispName)+1; j++, k++)
104  {
105  szIndex[k] = szDispName[j];
106  }
107  szDispName[i - 1] = '\0';
108  break;
109  }
110  else szDispName[i] = szDispName[i + 1];
111  }
112 
113  if (ExpandEnvironmentStrings(szDispName, szPath, ARRAYSIZE(szPath)))
114  {
115  hLib = LoadLibrary(szPath);
116  if (hLib)
117  {
118  if (LoadString(hLib, _ttoi(szIndex), szPath, ARRAYSIZE(szPath)))
119  {
120  StringCchCopy(szName, NameLength, szPath);
121  RegCloseKey(hKey);
122  FreeLibrary(hLib);
123  return TRUE;
124  }
125  FreeLibrary(hLib);
126  }
127  }
128  }
129  }
130 
131  /* Otherwise, use "Layout Text" value as an entry name */
132  dwBufLen = NameLength * sizeof(TCHAR);
133  if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL,
135  {
136  RegCloseKey(hKey);
137  return TRUE;
138  }
139 
140  RegCloseKey(hKey);
141  return FALSE;
142 }
#define RegQueryValueEx
Definition: winreg.h:524
static const WCHAR szName[]
Definition: powrprof.c:45
static BOOL GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
Definition: kbswitch.c:25
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
#define LoadLibrary
Definition: winbase.h:3723
#define TRUE
Definition: types.h:120
#define ExpandEnvironmentStrings
Definition: winbase.h:3635
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4245
unsigned char * LPBYTE
Definition: typedefs.h:53
#define StringCchPrintf
Definition: strsafe.h:517
#define FALSE
Definition: types.h:117
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
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 GLint GLint j
Definition: glfuncs.h:250
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define FreeLibrary(x)
Definition: compat.h:607
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
#define StringCchCopy
Definition: strsafe.h:139
GLenum GLsizei len
Definition: glext.h:6722
#define RegOpenKeyEx
Definition: winreg.h:520
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
FxAutoRegKey hKey
LPCWSTR szPath
Definition: env.c:37
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
int CDECL _ttoi(const _TCHAR *str)
Definition: atoi.c:10
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
int k
Definition: mpi.c:3369
#define RegCloseKey(hKey)
Definition: registry.h:47
#define LoadString
Definition: winuser.h:5809
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by AddTrayIcon(), and BuildLeftPopupMenu().

◆ GetMaxLayoutNum()

static ULONG GetMaxLayoutNum ( VOID  )
static

Definition at line 358 of file kbswitch.c.

359 {
360  HKEY hKey;
361  ULONG dwIndex, dwSize, uLayoutNum, uMaxLayoutNum = 0;
362  TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szLayoutID[CCH_LAYOUT_ID + 1];
363 
364  /* Get the maximum layout number in the Preload key */
365  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
367  {
368  for (dwIndex = 0; ; dwIndex++)
369  {
370  dwSize = sizeof(szLayoutNum);
371  if (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL,
372  NULL, NULL) != ERROR_SUCCESS)
373  {
374  break;
375  }
376 
377  if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
378  {
379  uLayoutNum = _ttoi(szLayoutNum);
380  if (uMaxLayoutNum < uLayoutNum)
381  uMaxLayoutNum = uLayoutNum;
382  }
383  }
384 
385  RegCloseKey(hKey);
386  }
387 
388  return uMaxLayoutNum;
389 }
static BOOL GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
Definition: kbswitch.c:25
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CCH_ULONG_DEC
Definition: kbswitch.h:20
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define RegOpenKeyEx
Definition: winreg.h:520
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
int CDECL _ttoi(const _TCHAR *str)
Definition: atoi.c:10
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RegEnumValue
Definition: winreg.h:511
#define RegCloseKey(hKey)
Definition: registry.h:47
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56

Referenced by GetNextLayout().

◆ GetNextLayout()

ULONG GetNextLayout ( VOID  )

Definition at line 419 of file kbswitch.c.

420 {
421  TCHAR szLayoutNum[3 + 1], szLayoutID[CCH_LAYOUT_ID + 1];
422  ULONG uLayoutNum, uMaxNum = GetMaxLayoutNum();
423 
424  for (uLayoutNum = ulCurrentLayoutNum + 1; ; ++uLayoutNum)
425  {
426  if (uLayoutNum > uMaxNum)
427  uLayoutNum = 1;
428  if (uLayoutNum == ulCurrentLayoutNum)
429  break;
430 
431  _ultot(uLayoutNum, szLayoutNum, 10);
432  if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
433  return uLayoutNum;
434  }
435 
436  return ulCurrentLayoutNum;
437 }
static BOOL GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
Definition: kbswitch.c:25
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
char TCHAR
Definition: xmlstorage.h:189
ULONG ulCurrentLayoutNum
Definition: kbswitch.c:21
static ULONG GetMaxLayoutNum(VOID)
Definition: kbswitch.c:358
#define _ultot
Definition: tchar.h:610
unsigned int ULONG
Definition: retypes.h:1

Referenced by WndProc().

◆ SetHooks()

BOOL SetHooks ( VOID  )

Definition at line 392 of file kbswitch.c.

393 {
394  g_hHookDLL = LoadLibrary(_T("kbsdll.dll"));
395  if (!g_hHookDLL)
396  {
397  return FALSE;
398  }
399 
402 
404  {
405  return FALSE;
406  }
407 
408  return KbSwitchSetHooks();
409 }
#define LoadLibrary
Definition: winbase.h:3723
BOOL(WINAPI * PKBSWITCHSETHOOKS)(VOID)
Definition: kbswitch.h:27
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks
Definition: kbswitch.c:15
#define FALSE
Definition: types.h:117
HMODULE g_hHookDLL
Definition: kbswitch.c:20
VOID(WINAPI * PKBSWITCHDELETEHOOKS)(VOID)
Definition: kbswitch.h:28
#define _T(x)
Definition: vfdio.h:22
PKBSWITCHSETHOOKS KbSwitchSetHooks
Definition: kbswitch.c:14
#define NULL
Definition: types.h:112
#define GetProcAddress(x, y)
Definition: compat.h:612

Referenced by WndProc().

◆ UpdateLanguageDisplay()

LRESULT UpdateLanguageDisplay ( HWND  hwnd,
HKL  hKl 
)

Definition at line 440 of file kbswitch.c.

441 {
442  TCHAR szLCID[MAX_PATH], szLangName[MAX_PATH];
443  LANGID LangID;
444 
445  GetLayoutIDByHkl(hKl, szLCID, ARRAYSIZE(szLCID));
446  LangID = (LANGID)_tcstoul(szLCID, NULL, 16);
447  GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
448  UpdateTrayIcon(hwnd, szLCID, szLangName);
449 
450  return 0;
451 }
#define LOCALE_SLANGUAGE
Definition: winnls.h:26
#define GetLocaleInfo
Definition: winnls.h:1186
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
WORD LANGID
Definition: typedefs.h:81
static VOID GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength)
Definition: kbswitch.c:284
char TCHAR
Definition: xmlstorage.h:189
static VOID UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
Definition: kbswitch.c:268
#define MAX_PATH
Definition: compat.h:34
#define _tcstoul
Definition: tchar.h:595
#define NULL
Definition: types.h:112
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
_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:1075

Referenced by UpdateLanguageDisplayCurrent(), and WndProc().

◆ UpdateLanguageDisplayCurrent()

LRESULT UpdateLanguageDisplayCurrent ( HWND  hwnd,
WPARAM  wParam 
)

Definition at line 454 of file kbswitch.c.

455 {
456  DWORD dwThreadID = GetWindowThreadProcessId((HWND)wParam, 0);
457  HKL hKL = GetKeyboardLayout(dwThreadID);
458  return UpdateLanguageDisplay(hwnd, hKL);
459 }
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
WPARAM wParam
Definition: combotst.c:138
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT_PTR HKL
Definition: msctf.idl:101
PKEYBOARD_LAYOUT GetKeyboardLayout()
Definition: utils.c:194
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
LRESULT UpdateLanguageDisplay(HWND hwnd, HKL hKl)
Definition: kbswitch.c:440

Referenced by WndProc().

◆ UpdateTrayIcon()

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

Definition at line 268 of file kbswitch.c.

269 {
270  NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
271 
273  tnid.hIcon = CreateTrayIcon(szLCID);
274  StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
275 
277 
278  if (g_hTrayIcon)
280  g_hTrayIcon = tnid.hIcon;
281 }
static HICON CreateTrayIcon(LPTSTR szLCID)
Definition: kbswitch.c:145
#define NIF_MESSAGE
Definition: shellapi.h:102
static const WCHAR szName[]
Definition: powrprof.c:45
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:12
CHAR szTip[128]
Definition: shellapi.h:235
#define NIF_TIP
Definition: shellapi.h:104
#define NIF_ICON
Definition: shellapi.h:103
HICON g_hTrayIcon
Definition: kbswitch.c:22
#define StringCchCopy
Definition: strsafe.h:139
UINT uCallbackMessage
Definition: shellapi.h:229
#define Shell_NotifyIcon
Definition: shellapi.h:689
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#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 462 of file kbswitch.c.

463 {
464  static HMENU s_hMenu = NULL, s_hRightPopupMenu = NULL;
465  static UINT s_uTaskbarRestart;
466  POINT pt;
467  HMENU hLeftPopupMenu;
468 
469  switch (Message)
470  {
471  case WM_CREATE:
472  {
473  if (!SetHooks())
474  return -1;
475 
476  AddTrayIcon(hwnd);
477 
479  s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
480  break;
481  }
482 
483  case WM_LANG_CHANGED:
484  {
486  }
487 
488  case WM_LOAD_LAYOUT:
489  {
490  ULONG uNextNum = GetNextLayout();
491  if (ulCurrentLayoutNum != uNextNum)
492  ActivateLayout(hwnd, uNextNum);
493  break;
494  }
495 
496  case WM_WINDOW_ACTIVATE:
497  {
499  }
500 
501  case WM_NOTIFYICONMSG:
502  {
503  switch (lParam)
504  {
505  case WM_RBUTTONUP:
506  case WM_LBUTTONUP:
507  {
508  GetCursorPos(&pt);
510 
511  if (lParam == WM_LBUTTONUP)
512  {
513  /* Rebuild the left popup menu on every click to take care of keyboard layout changes */
514  hLeftPopupMenu = BuildLeftPopupMenu();
515  TrackPopupMenu(hLeftPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
516  DestroyMenu(hLeftPopupMenu);
517  }
518  else
519  {
520  if (!s_hRightPopupMenu)
521  {
523  s_hRightPopupMenu = GetSubMenu(s_hMenu, 0);
524  }
525  TrackPopupMenu(s_hRightPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
526  }
527 
528  PostMessage(hwnd, WM_NULL, 0, 0);
529  break;
530  }
531  }
532  break;
533  }
534 
535  case WM_COMMAND:
536  switch (LOWORD(wParam))
537  {
538  case ID_EXIT:
539  {
540  SendMessage(hwnd, WM_CLOSE, 0, 0);
541  break;
542  }
543 
544  case ID_PREFERENCES:
545  {
546  SHELLEXECUTEINFO shInputDll = { sizeof(shInputDll) };
547  shInputDll.hwnd = hwnd;
548  shInputDll.lpVerb = _T("open");
549  shInputDll.lpFile = _T("rundll32.exe");
550  shInputDll.lpParameters = _T("shell32.dll,Control_RunDLL input.dll");
551  if (!ShellExecuteEx(&shInputDll))
552  MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_OK | MB_ICONERROR);
553 
554  break;
555  }
556 
557  case ID_NEXTLAYOUT:
558  {
560  break;
561  }
562 
563  default:
564  {
566  break;
567  }
568  }
569  break;
570 
571  case WM_SETTINGCHANGE:
572  {
573  if (wParam == SPI_SETDEFAULTINPUTLANG)
574  {
575  //FIXME: Should detect default language changes by CPL applet or by other tools and update UI
576  }
577  if (wParam == SPI_SETNONCLIENTMETRICS)
578  {
580  }
581  }
582  break;
583 
584  case WM_DESTROY:
585  {
586  DeleteHooks();
587  DestroyMenu(s_hMenu);
589  PostQuitMessage(0);
590  break;
591  }
592 
593  default:
594  {
595  if (Message == s_uTaskbarRestart)
596  {
597  AddTrayIcon(hwnd);
598  break;
599  }
600  else if (Message == ShellHookMessage && wParam == HSHELL_LANGUAGE)
601  {
603  break;
604  }
606  }
607  }
608 
609  return 0;
610 }
#define WM_NULL
Definition: winuser.h:1597
#define ShellExecuteEx
Definition: shellapi.h:692
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define pt(x, y)
Definition: drawing.c:79
LRESULT UpdateLanguageDisplayCurrent(HWND hwnd, WPARAM wParam)
Definition: kbswitch.c:454
static VOID AddTrayIcon(HWND hwnd)
Definition: kbswitch.c:235
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2639
WPARAM wParam
Definition: combotst.c:138
#define WM_SETTINGCHANGE
Definition: winuser.h:1619
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:12
#define IDR_POPUP
Definition: resource.h:7
#define WM_LANG_CHANGED
Definition: kbswitch.h:23
#define DefWindowProc
Definition: ros2win.h:31
HINSTANCE hInst
Definition: kbswitch.c:18
#define WM_DESTROY
Definition: winuser.h:1599
#define PostMessage
Definition: winuser.h:5822
VOID DeleteHooks(VOID)
Definition: kbswitch.c:412
#define _T(x)
Definition: vfdio.h:22
LPCSTR lpParameters
Definition: shellapi.h:314
#define WM_CLOSE
Definition: winuser.h:1611
#define WM_WINDOW_ACTIVATE
Definition: kbswitch.h:24
#define WM_RBUTTONUP
Definition: winuser.h:1770
CHAR Message[80]
Definition: alive.c:5
#define MB_ICONERROR
Definition: winuser.h:781
#define MessageBox
Definition: winuser.h:5812
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define WM_COMMAND
Definition: winuser.h:1730
UINT_PTR HKL
Definition: msctf.idl:101
#define ID_EXIT
Definition: resource.h:10
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define RegisterWindowMessage
Definition: winuser.h:5830
static VOID ActivateLayout(HWND hwnd, ULONG uLayoutNum)
Definition: kbswitch.c:297
ULONG ulCurrentLayoutNum
Definition: kbswitch.c:21
UINT ShellHookMessage
Definition: kbswitch.c:16
#define TEXT(s)
Definition: k32.h:26
#define LoadMenu
Definition: winuser.h:5807
#define WM_LBUTTONUP
Definition: winuser.h:1767
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define MB_OK
Definition: winuser.h:784
#define ID_NEXTLAYOUT
Definition: resource.h:12
static HMENU BuildLeftPopupMenu(VOID)
Definition: kbswitch.c:323
#define SendMessage
Definition: winuser.h:5833
#define WM_CREATE
Definition: winuser.h:1598
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define WM_LOAD_LAYOUT
Definition: kbswitch.h:25
BOOL SetHooks(VOID)
Definition: kbswitch.c:392
#define ID_PREFERENCES
Definition: resource.h:11
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
LPARAM lParam
Definition: combotst.c:139
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define LOWORD(l)
Definition: pedump.c:82
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
LRESULT UpdateLanguageDisplay(HWND hwnd, HKL hKl)
Definition: kbswitch.c:440
static VOID DeleteTrayIcon(HWND hwnd)
Definition: kbswitch.c:255
ULONG GetNextLayout(VOID)
Definition: kbswitch.c:419

Referenced by _tWinMain().

Variable Documentation

◆ g_hHookDLL

HMODULE g_hHookDLL = NULL

Definition at line 20 of file kbswitch.c.

Referenced by DeleteHooks(), and SetHooks().

◆ g_hTrayIcon

HICON g_hTrayIcon = NULL

Definition at line 22 of file kbswitch.c.

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

◆ hInst

HINSTANCE hInst

Definition at line 18 of file kbswitch.c.

Referenced by _tWinMain(), and WndProc().

◆ hProcessHeap

◆ KbSwitchDeleteHooks

PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL

Definition at line 15 of file kbswitch.c.

Referenced by DeleteHooks(), and SetHooks().

◆ KbSwitchSetHooks

PKBSWITCHSETHOOKS KbSwitchSetHooks = NULL

Definition at line 14 of file kbswitch.c.

Referenced by SetHooks().

◆ ShellHookMessage

UINT ShellHookMessage = 0

Definition at line 16 of file kbswitch.c.

Referenced by _tWinMain(), and WndProc().

◆ ulCurrentLayoutNum

ULONG ulCurrentLayoutNum = 1

Definition at line 21 of file kbswitch.c.

Referenced by ActivateLayout(), BuildLeftPopupMenu(), GetNextLayout(), and WndProc().