ReactOS  0.4.15-dev-5608-gafb953a
kbswitch.c
Go to the documentation of this file.
1 /*
2  * PROJECT: Keyboard Layout Switcher
3  * FILE: base/applications/kbswitch/kbswitch.c
4  * PURPOSE: Switching Keyboard Layouts
5  * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
6  * Colin Finck (mail@colinfinck.de)
7  * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8  */
9 
10 #include "kbswitch.h"
11 #include <imm.h>
12 
13 /*
14  * This program kbswitch is a mimic of Win2k's internat.exe.
15  * However, there are some differences.
16  *
17  * Comparing with WinNT4 ActivateKeyboardLayout, WinXP ActivateKeyboardLayout has
18  * process boundary, so we cannot activate the IME keyboard layout from the outer process.
19  * It needs special care.
20  *
21  * We use global hook by our kbsdll.dll, to watch the shell and the windows.
22  *
23  * It might not work correctly on Vista+ because keyboard layout change notification
24  * won't be generated in Vista+.
25  */
26 
27 #define WM_NOTIFYICONMSG (WM_USER + 248)
28 
32 
39 
40 static BOOL
41 GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
42 {
43  DWORD dwBufLen, dwRes;
44  HKEY hKey;
45  TCHAR szTempLCID[CCH_LAYOUT_ID + 1];
46 
47  /* Get the Layout ID */
48  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE,
49  &hKey) == ERROR_SUCCESS)
50  {
51  dwBufLen = sizeof(szTempLCID);
52  dwRes = RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szTempLCID, &dwBufLen);
53  if (dwRes != ERROR_SUCCESS)
54  {
56  return FALSE;
57  }
58 
60  }
61 
62  /* Look for a substitute of this layout */
63  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0,
65  {
66  dwBufLen = sizeof(szTempLCID);
67  if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
68  {
69  /* No substitute found, then use the old LCID */
70  StringCchCopy(szLCID, LCIDLength, szTempLCID);
71  }
72 
74  }
75  else
76  {
77  /* Substitutes key couldn't be opened, so use the old LCID */
78  StringCchCopy(szLCID, LCIDLength, szTempLCID);
79  }
80 
81  return TRUE;
82 }
83 
84 static BOOL
86 {
87  if (!GetSystemDirectory(szPath, cchPath))
88  return FALSE;
89 
90  StringCchCat(szPath, cchPath, TEXT("\\"));
91  StringCchCat(szPath, cchPath, FileName);
92  return TRUE;
93 }
94 
95 static BOOL
96 GetLayoutName(LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
97 {
98  HKEY hKey;
100  TCHAR szBuf[MAX_PATH], szDispName[MAX_PATH], szIndex[MAX_PATH], szPath[MAX_PATH];
101  TCHAR szLCID[CCH_LAYOUT_ID + 1];
102  HANDLE hLib;
103  UINT i, j, k;
104 
105  if (!GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID)))
106  return FALSE;
107 
108  StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
109  _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
110 
112  {
113  return FALSE;
114  }
115 
116  /* Use "Layout Display Name" value as an entry name if possible */
117  dwBufLen = sizeof(szDispName);
118  if (RegQueryValueEx(hKey, _T("Layout Display Name"), NULL, NULL,
119  (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
120  {
121  /* FIXME: Use shlwapi!SHLoadRegUIStringW instead if it was implemented */
122  if (szDispName[0] == '@')
123  {
124  size_t len = _tcslen(szDispName);
125 
126  for (i = 0; i < len; i++)
127  {
128  if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
129  {
130  for (j = i + 2, k = 0; j < _tcslen(szDispName)+1; j++, k++)
131  {
132  szIndex[k] = szDispName[j];
133  }
134  szDispName[i - 1] = '\0';
135  break;
136  }
137  else szDispName[i] = szDispName[i + 1];
138  }
139 
140  if (ExpandEnvironmentStrings(szDispName, szPath, ARRAYSIZE(szPath)))
141  {
142  hLib = LoadLibrary(szPath);
143  if (hLib)
144  {
145  if (LoadString(hLib, _ttoi(szIndex), szPath, ARRAYSIZE(szPath)))
146  {
147  StringCchCopy(szName, NameLength, szPath);
148  RegCloseKey(hKey);
149  FreeLibrary(hLib);
150  return TRUE;
151  }
152  FreeLibrary(hLib);
153  }
154  }
155  }
156  }
157 
158  /* Otherwise, use "Layout Text" value as an entry name */
159  dwBufLen = NameLength * sizeof(TCHAR);
160  if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL,
162  {
163  RegCloseKey(hKey);
164  return FALSE;
165  }
166 
167  RegCloseKey(hKey);
168  return TRUE;
169 }
170 
171 static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szLCID)
172 {
173  HKEY hKey;
174  DWORD dwBufLen;
175  TCHAR szBuf[MAX_PATH];
176 
177  szImeFile[0] = UNICODE_NULL;
178 
179  if (_tcslen(szLCID) != CCH_LAYOUT_ID)
180  return FALSE; /* Invalid LCID */
181 
182  if (szLCID[0] != TEXT('E') && szLCID[0] != TEXT('e'))
183  return FALSE; /* Not an IME HKL */
184 
185  StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
186  _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
187 
189  {
190  return FALSE;
191  }
192 
193  dwBufLen = cchImeFile * sizeof(TCHAR);
194  if (RegQueryValueEx(hKey, _T("IME File"), NULL, NULL,
195  (LPBYTE)szImeFile, &dwBufLen) != ERROR_SUCCESS)
196  {
197  szImeFile[0] = UNICODE_NULL;
198  }
199 
200  RegCloseKey(hKey);
201 
202  return (szImeFile[0] != UNICODE_NULL);
203 }
204 
205 typedef struct tagLOAD_ICON
206 {
210 
211 static BOOL CALLBACK
214  LPCTSTR lpszType,
215  LPTSTR lpszName,
216  LPARAM lParam)
217 {
218  PLOAD_ICON pLoadIcon = (PLOAD_ICON)lParam;
219  pLoadIcon->hIcon = (HICON)LoadImage(hModule, lpszName, IMAGE_ICON,
220  pLoadIcon->cxIcon, pLoadIcon->cyIcon,
222  if (pLoadIcon->hIcon)
223  return FALSE; /* Stop enumeration */
224  return TRUE;
225 }
226 
227 static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
228 {
229  LOAD_ICON LoadIcon = { cxIcon, cyIcon, NULL };
230  HMODULE hImeDLL = LoadLibraryEx(szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
231  if (hImeDLL)
232  {
234  FreeLibrary(hImeDLL);
235  }
236  return LoadIcon.hIcon;
237 }
238 
240 {
241  HDC hdcScreen = GetDC(NULL);
242  HDC hdc = CreateCompatibleDC(hdcScreen);
243  INT cxIcon = GetSystemMetrics(SM_CXSMICON);
244  INT cyIcon = GetSystemMetrics(SM_CYSMICON);
245  HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
246  HGDIOBJ hbmOld;
247 
248  if (hbm != NULL)
249  {
250  hbmOld = SelectObject(hdc, hbm);
251  DrawIconEx(hdc, 0, 0, hIcon, cxIcon, cyIcon, 0, GetSysColorBrush(COLOR_MENU), DI_NORMAL);
252  SelectObject(hdc, hbmOld);
253  }
254 
255  DeleteDC(hdc);
256  ReleaseDC(NULL, hdcScreen);
257  return hbm;
258 }
259 
260 static HICON
262 {
263  LANGID LangID;
264  TCHAR szBuf[4];
265  HDC hdcScreen, hdc;
266  HBITMAP hbmColor, hbmMono, hBmpOld;
267  HFONT hFont, hFontOld;
268  LOGFONT lf;
269  RECT rect;
271  HICON hIcon;
272  INT cxIcon = GetSystemMetrics(SM_CXSMICON);
273  INT cyIcon = GetSystemMetrics(SM_CYSMICON);
275 
276  if (szImeFile && szImeFile[0])
277  {
278  if (GetSystemLibraryPath(szPath, ARRAYSIZE(szPath), szImeFile))
279  return FakeExtractIcon(szPath, cxIcon, cyIcon);
280  }
281 
282  /* Getting "EN", "FR", etc. from English, French, ... */
283  LangID = LANGIDFROMLCID(_tcstoul(szLCID, NULL, 16));
284  if (GetLocaleInfo(LangID,
286  szBuf,
287  ARRAYSIZE(szBuf)) == 0)
288  {
289  szBuf[0] = szBuf[1] = _T('?');
290  }
291  szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
292 
293  /* Create hdc, hbmColor and hbmMono */
294  hdcScreen = GetDC(NULL);
295  hdc = CreateCompatibleDC(hdcScreen);
296  hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
297  ReleaseDC(NULL, hdcScreen);
298  hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
299 
300  /* Checking NULL */
301  if (!hdc || !hbmColor || !hbmMono)
302  {
303  if (hbmMono)
304  DeleteObject(hbmMono);
305  if (hbmColor)
306  DeleteObject(hbmColor);
307  if (hdc)
308  DeleteDC(hdc);
309  return NULL;
310  }
311 
312  /* Create a font */
313  hFont = NULL;
314  if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
315  {
316  /* Override the current size with something manageable */
317  lf.lfHeight = -11;
318  lf.lfWidth = 0;
319  hFont = CreateFontIndirect(&lf);
320  }
321  if (!hFont)
323 
324  SetRect(&rect, 0, 0, cxIcon, cyIcon);
325 
326  /* Draw hbmColor */
327  hBmpOld = SelectObject(hdc, hbmColor);
329  FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
330  hFontOld = SelectObject(hdc, hFont);
334  SelectObject(hdc, hFontOld);
335 
336  /* Fill hbmMono with black */
337  SelectObject(hdc, hbmMono);
338  PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
339  SelectObject(hdc, hBmpOld);
340 
341  /* Create an icon from hbmColor and hbmMono */
342  IconInfo.fIcon = TRUE;
344  IconInfo.hbmColor = hbmColor;
345  IconInfo.hbmMask = hbmMono;
347 
348  /* Clean up */
350  DeleteObject(hbmMono);
351  DeleteObject(hbmColor);
352  DeleteDC(hdc);
353 
354  return hIcon;
355 }
356 
357 static VOID
359 {
360  NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
361  TCHAR szLCID[CCH_LAYOUT_ID + 1], szName[MAX_PATH];
362  TCHAR szImeFile[80];
363 
364  GetLayoutID(_T("1"), szLCID, ARRAYSIZE(szLCID));
366  GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szLCID);
367 
369  tnid.hIcon = CreateTrayIcon(szLCID, szImeFile);
370  StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
371 
372  Shell_NotifyIcon(NIM_ADD, &tnid);
373 
374  if (g_hTrayIcon)
376  g_hTrayIcon = tnid.hIcon;
377 }
378 
379 static VOID
381 {
382  NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1 };
384 
385  if (g_hTrayIcon)
386  {
388  g_hTrayIcon = NULL;
389  }
390 }
391 
392 static VOID
394 {
395  NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
396  TCHAR szImeFile[80];
397 
398  GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szLCID);
399 
401  tnid.hIcon = CreateTrayIcon(szLCID, szImeFile);
402  StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
403 
405 
406  if (g_hTrayIcon)
408  g_hTrayIcon = tnid.hIcon;
409 }
410 
411 static VOID
412 GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength)
413 {
414  StringCchPrintf(szLayoutID, LayoutIDLength, _T("%08lx"), (DWORD)(DWORD_PTR)(hKl));
415 }
416 
417 static BOOL CALLBACK
419 {
420  PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET, lParam);
421  return TRUE;
422 }
423 
424 static VOID
425 ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
426 {
427  HKL hKl;
428  TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szLCID[CCH_LAYOUT_ID + 1], szLangName[MAX_PATH];
429  LANGID LangID;
430 
431  /* The layout number starts from one. Zero is invalid */
432  if (uLayoutNum == 0 || uLayoutNum > 0xFF) /* Invalid */
433  return;
434 
435  _ultot(uLayoutNum, szLayoutNum, 10);
436  GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID));
437  LangID = (LANGID)_tcstoul(szLCID, NULL, 16);
438 
439  /* Switch to the new keyboard layout */
440  GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
441  UpdateTrayIcon(hwnd, szLCID, szLangName);
442 
443  if (hwndTarget && !bNoActivate)
444  SetForegroundWindow(hwndTarget);
445 
446  hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
447  if (hKl)
449 
450  /* Post WM_INPUTLANGCHANGEREQUEST */
451  if (hwndTarget)
452  {
453  PostMessage(hwndTarget, WM_INPUTLANGCHANGEREQUEST,
454  INPUTLANGCHANGE_SYSCHARSET, (LPARAM)hKl);
455  }
456  else
457  {
459  }
460 
461  ulCurrentLayoutNum = uLayoutNum;
462 }
463 
464 static HMENU
466 {
467  HMENU hMenu = CreatePopupMenu();
468  HKEY hKey;
469  DWORD dwIndex, dwSize;
470  TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szName[MAX_PATH];
471  TCHAR szLCID[CCH_LAYOUT_ID + 1], szImeFile[80];
472  HICON hIcon;
473  MENUITEMINFO mii = { sizeof(mii) };
474 
475  /* Add the keyboard layouts to the popup menu */
476  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
478  {
479  for (dwIndex = 0; ; dwIndex++)
480  {
481  dwSize = sizeof(szLayoutNum);
482  if (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL,
483  NULL, NULL) != ERROR_SUCCESS)
484  {
485  break;
486  }
487 
488  GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID));
489  GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szLCID);
490 
491  if (!GetLayoutName(szLayoutNum, szName, ARRAYSIZE(szName)))
492  continue;
493 
494  mii.fMask = MIIM_ID | MIIM_STRING;
495  mii.wID = _ttoi(szLayoutNum);
496  mii.dwTypeData = szName;
497 
498  hIcon = CreateTrayIcon(szLCID, szImeFile);
499  if (hIcon)
500  {
501  mii.hbmpItem = BitmapFromIcon(hIcon);
502  if (mii.hbmpItem)
503  mii.fMask |= MIIM_BITMAP;
504  }
505 
506  InsertMenuItem(hMenu, -1, TRUE, &mii);
508  }
509 
511 
512  RegCloseKey(hKey);
513  }
514 
515  return hMenu;
516 }
517 
518 static ULONG
520 {
521  HKEY hKey;
522  ULONG dwIndex, dwSize, uLayoutNum, uMaxLayoutNum = 0;
523  TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szLayoutID[CCH_LAYOUT_ID + 1];
524 
525  /* Get the maximum layout number in the Preload key */
526  if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0,
528  {
529  for (dwIndex = 0; ; dwIndex++)
530  {
531  dwSize = sizeof(szLayoutNum);
532  if (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL,
533  NULL, NULL) != ERROR_SUCCESS)
534  {
535  break;
536  }
537 
538  if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
539  {
540  uLayoutNum = _ttoi(szLayoutNum);
541  if (uMaxLayoutNum < uLayoutNum)
542  uMaxLayoutNum = uLayoutNum;
543  }
544  }
545 
546  RegCloseKey(hKey);
547  }
548 
549  return uMaxLayoutNum;
550 }
551 
552 BOOL
554 {
555  g_hHookDLL = LoadLibrary(_T("kbsdll.dll"));
556  if (!g_hHookDLL)
557  {
558  return FALSE;
559  }
560 
563 
565  {
566  return FALSE;
567  }
568 
569  return KbSwitchSetHooks();
570 }
571 
572 VOID
574 {
576  {
579  }
580  if (g_hHookDLL)
581  {
583  g_hHookDLL = NULL;
584  }
585 }
586 
587 ULONG
589 {
590  TCHAR szLayoutNum[3 + 1], szLayoutID[CCH_LAYOUT_ID + 1];
591  ULONG uLayoutNum, uMaxNum = GetMaxLayoutNum();
592 
593  for (uLayoutNum = ulCurrentLayoutNum + 1; ; ++uLayoutNum)
594  {
595  if (uLayoutNum > uMaxNum)
596  uLayoutNum = 1;
597  if (uLayoutNum == ulCurrentLayoutNum)
598  break;
599 
600  _ultot(uLayoutNum, szLayoutNum, 10);
601  if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
602  return uLayoutNum;
603  }
604 
605  return ulCurrentLayoutNum;
606 }
607 
608 UINT
610 {
611  TCHAR szLCID[MAX_PATH], szLangName[MAX_PATH];
612  LANGID LangID;
613 
614  GetLayoutIDByHkl(hKl, szLCID, ARRAYSIZE(szLCID));
615  LangID = (LANGID)_tcstoul(szLCID, NULL, 16);
616  GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
617  UpdateTrayIcon(hwnd, szLCID, szLangName);
618 
619  return 0;
620 }
621 
622 HWND
624 {
625  TCHAR szClass[64];
626  HWND hwndIME;
627  HWND hwndTarget = hwndFore;
628  if (hwndTarget == NULL)
629  hwndTarget = GetForegroundWindow();
630 
631  GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass));
632  if (_tcsicmp(szClass, szKbSwitcherName) == 0)
633  hwndTarget = g_hwndLastActive;
634 
635  hwndIME = ImmGetDefaultIMEWnd(hwndTarget);
636  return (hwndIME ? hwndIME : hwndTarget);
637 }
638 
639 UINT
641 {
642  DWORD dwThreadID = GetWindowThreadProcessId(GetTargetWindow(hwndFore), NULL);
643  HKL hKL = GetKeyboardLayout(dwThreadID);
645 
646  return 0;
647 }
648 
650 {
651  UINT i, nCount;
652  HKL ahKL[256];
653 
654  nCount = GetKeyboardLayoutList(ARRAYSIZE(ahKL), ahKL);
655  for (i = 0; i < nCount; ++i)
656  {
657  if (ahKL[i] == hKL)
658  return i + 1;
659  }
660 
661  return 0;
662 }
663 
665 {
666  TCHAR szClass[64];
667 
668  hwndFore = GetAncestor(hwndFore, GA_ROOT);
669 
670  if (!IsWindowVisible(hwndFore) || !GetClassName(hwndFore, szClass, ARRAYSIZE(szClass)))
671  return FALSE;
672 
673  if (_tcsicmp(szClass, szKbSwitcherName) == 0 ||
674  _tcsicmp(szClass, TEXT("Shell_TrayWnd")) == 0)
675  {
676  return FALSE; /* Special window */
677  }
678 
679  /* FIXME: CONWND is multithreaded but KLF_SETFORPROCESS and
680  DefWindowProc.WM_INPUTLANGCHANGEREQUEST won't work yet */
681  if (_tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
682  {
683  HKL hKL = GetKeyboardLayout(0);
685  }
686 
687  g_hwndLastActive = hwndFore;
688  return TRUE;
689 }
690 
693 {
694  static HMENU s_hMenu = NULL, s_hRightPopupMenu = NULL;
695  static UINT s_uTaskbarRestart;
696  POINT pt;
697  HMENU hLeftPopupMenu;
698 
699  switch (Message)
700  {
701  case WM_CREATE:
702  {
703  if (!SetHooks())
704  {
705  MessageBox(NULL, TEXT("SetHooks failed."), NULL, MB_ICONERROR);
706  return -1;
707  }
708 
709  AddTrayIcon(hwnd);
710 
712  s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
713  break;
714  }
715 
716  case WM_LANG_CHANGED: /* Comes from kbsdll.dll and this module */
717  {
719  break;
720  }
721 
722  case WM_WINDOW_ACTIVATE: /* Comes from kbsdll.dll and this module */
723  {
724  HWND hwndFore = GetForegroundWindow();
725  if (RememberLastActive(hwnd, hwndFore))
726  return UpdateLanguageDisplayCurrent(hwnd, hwndFore);
727  break;
728  }
729 
730  case WM_NOTIFYICONMSG:
731  {
732  switch (lParam)
733  {
734  case WM_RBUTTONUP:
735  case WM_LBUTTONUP:
736  {
737  GetCursorPos(&pt);
739 
740  if (lParam == WM_LBUTTONUP)
741  {
742  /* Rebuild the left popup menu on every click to take care of keyboard layout changes */
743  hLeftPopupMenu = BuildLeftPopupMenu();
744  TrackPopupMenu(hLeftPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
745  DestroyMenu(hLeftPopupMenu);
746  }
747  else
748  {
749  if (!s_hRightPopupMenu)
750  {
752  s_hRightPopupMenu = GetSubMenu(s_hMenu, 0);
753  }
754  TrackPopupMenu(s_hRightPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
755  }
756 
757  PostMessage(hwnd, WM_NULL, 0, 0);
758  break;
759  }
760  }
761  break;
762  }
763 
764  case WM_COMMAND:
765  switch (LOWORD(wParam))
766  {
767  case ID_EXIT:
768  {
769  PostMessage(hwnd, WM_CLOSE, 0, 0);
770  break;
771  }
772 
773  case ID_PREFERENCES:
774  {
776  TEXT("control.exe"), TEXT("input.dll"),
778  if (ret <= 32)
779  MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_ICONERROR);
780  break;
781  }
782 
783  case ID_NEXTLAYOUT:
784  {
785  HWND hwndTarget = (HWND)lParam, hwndTargetSave = NULL;
786  DWORD dwThreadID;
787  HKL hKL;
788  UINT uNum;
789  TCHAR szClass[64];
790  BOOL bCONWND = FALSE;
791 
792  if (hwndTarget == NULL)
793  hwndTarget = g_hwndLastActive;
794 
795  /* FIXME: CONWND is multithreaded but KLF_SETFORPROCESS and
796  DefWindowProc.WM_INPUTLANGCHANGEREQUEST won't work yet */
797  if (hwndTarget &&
798  GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass)) &&
799  _tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
800  {
801  bCONWND = TRUE;
802  hwndTargetSave = hwndTarget;
803  hwndTarget = NULL;
804  }
805 
806  if (hwndTarget)
807  {
808  dwThreadID = GetWindowThreadProcessId(hwndTarget, NULL);
809  hKL = GetKeyboardLayout(dwThreadID);
810  uNum = GetCurLayoutNum(hKL);
811  if (uNum != 0)
812  ulCurrentLayoutNum = uNum;
813  }
814 
815  ActivateLayout(hwnd, GetNextLayout(), hwndTarget, TRUE);
816 
817  /* FIXME: CONWND is multithreaded but KLF_SETFORPROCESS and
818  DefWindowProc.WM_INPUTLANGCHANGEREQUEST won't work yet */
819  if (bCONWND)
820  {
821  ActivateLayout(hwnd, ulCurrentLayoutNum, hwndTargetSave, TRUE);
822  }
823  break;
824  }
825 
826  default:
827  {
828  if (1 <= LOWORD(wParam) && LOWORD(wParam) <= 1000)
829  {
831  {
833  }
835  }
836  break;
837  }
838  }
839  break;
840 
841  case WM_SETTINGCHANGE:
842  {
843  if (wParam == SPI_SETNONCLIENTMETRICS)
844  {
846  break;
847  }
848  }
849  break;
850 
851  case WM_DESTROY:
852  {
853  DeleteHooks();
854  DestroyMenu(s_hMenu);
856  PostQuitMessage(0);
857  break;
858  }
859 
860  default:
861  {
862  if (Message == s_uTaskbarRestart)
863  {
864  AddTrayIcon(hwnd);
865  break;
866  }
867  else if (Message == ShellHookMessage)
868  {
869  if (wParam == HSHELL_LANGUAGE)
871  else if (wParam == HSHELL_WINDOWACTIVATED)
873 
874  break;
875  }
877  }
878  }
879 
880  return 0;
881 }
882 
883 INT WINAPI
884 _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
885 {
887  MSG msg;
888  HANDLE hMutex;
889  HWND hwnd;
890 
891  switch (GetUserDefaultUILanguage())
892  {
895  break;
896  default:
897  break;
898  }
899 
901  if (!hMutex)
902  return 1;
903 
905  {
907  return 1;
908  }
909 
910  hInst = hInstance;
912 
913  ZeroMemory(&WndClass, sizeof(WndClass));
914  WndClass.lpfnWndProc = WndProc;
915  WndClass.hInstance = hInstance;
916  WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
917  WndClass.lpszClassName = szKbSwitcherName;
918  if (!RegisterClass(&WndClass))
919  {
921  return 1;
922  }
923 
927 
928  while (GetMessage(&msg, NULL, 0, 0))
929  {
932  }
933 
935  return 0;
936 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define RegQueryValueEx
Definition: winreg.h:524
#define WM_NULL
Definition: winuser.h:1597
#define GA_ROOT
Definition: winuser.h:2779
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define NIF_MESSAGE
Definition: shellapi.h:102
static const WCHAR szName[]
Definition: powrprof.c:45
#define EnumResourceNames
Definition: winbase.h:3643
HKL WINAPI ActivateKeyboardLayout(_In_ HKL, _In_ UINT)
#define DispatchMessage
Definition: winuser.h:5755
LANGID WINAPI GetUserDefaultUILanguage(void)
Definition: lang.c:810
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define RT_GROUP_ICON
Definition: pedump.c:375
static HICON
Definition: imagelist.c:84
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
#define CloseHandle
Definition: compat.h:739
#define COLOR_HIGHLIGHT
Definition: winuser.h:920
#define IMAGE_ICON
Definition: winuser.h:212
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
static BOOL GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
Definition: kbswitch.c:41
#define LAYOUT_RTL
Definition: wingdi.h:1371
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
#define LOCALE_SLANGUAGE
Definition: winnls.h:26
#define CreateWindow
Definition: winuser.h:5744
#define LoadLibrary
Definition: winbase.h:3733
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define _tcsicmp
Definition: xmlstorage.h:205
HDC WINAPI GetDC(_In_opt_ HWND)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define KLF_ACTIVATE
Definition: winuser.h:111
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
HWND GetTargetWindow(HWND hwndFore)
Definition: kbswitch.c:623
DWORD yHotspot
Definition: winuser.h:3115
#define HKEY_CURRENT_USER
Definition: winreg.h:11
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define ExpandEnvironmentStrings
Definition: winbase.h:3645
#define SUBLANG_DEFAULT
Definition: nls.h:168
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
#define GetLocaleInfo
Definition: winnls.h:1186
#define SystemParametersInfo
Definition: winuser.h:5848
HANDLE HWND
Definition: compat.h:19
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1670
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define SM_CYSMICON
Definition: winuser.h:1007
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define StringCchCat
Definition: strsafe.h:317
static VOID AddTrayIcon(HWND hwnd)
Definition: kbswitch.c:358
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:692
UINT_PTR WPARAM
Definition: windef.h:207
WORD LANGID
Definition: typedefs.h:81
int32_t INT_PTR
Definition: typedefs.h:64
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2639
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4245
static HICON CreateTrayIcon(LPTSTR szLCID, LPCTSTR szImeFile OPTIONAL)
Definition: kbswitch.c:261
BOOL(WINAPI * PKBSWITCHSETHOOKS)(VOID)
Definition: kbswitch.h:26
static BOOL RememberLastActive(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:664
int32_t INT
Definition: typedefs.h:58
#define LANG_HEBREW
Definition: nls.h:67
DWORD WINAPI GetSysColor(_In_ int)
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
#define MIIM_BITMAP
Definition: winuser.h:723
HFONT hFont
Definition: main.c:53
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define WM_SETTINGCHANGE
Definition: winuser.h:1619
#define DrawText
Definition: winuser.h:5761
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks
Definition: kbswitch.c:30
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:27
#define LoadKeyboardLayout
Definition: winuser.h:5806
static VOID ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
Definition: kbswitch.c:425
#define CCH_ULONG_DEC
Definition: kbswitch.h:20
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
static HBITMAP BitmapFromIcon(HICON hIcon)
Definition: kbswitch.c:239
static BOOL GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
Definition: kbswitch.c:85
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
HINSTANCE hInstance
Definition: charmap.c:19
#define L(x)
Definition: ntvdm.h:50
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
unsigned char * LPBYTE
Definition: typedefs.h:53
COLORREF WINAPI SetDCBrushColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: dc.c:905
#define StringCchPrintf
Definition: strsafe.h:517
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
struct tagLOAD_ICON * PLOAD_ICON
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG lfHeight
Definition: dimm.idl:42
HBITMAP hbmMask
Definition: winuser.h:3116
#define ShellExecute
Definition: shellapi.h:691
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HMODULE g_hHookDLL
Definition: kbswitch.c:35
HWND g_hwndLastActive
Definition: kbswitch.c:38
CHAR szTip[128]
Definition: shellapi.h:235
#define TRANSPARENT
Definition: wingdi.h:950
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
#define NIF_TIP
Definition: shellapi.h:104
struct tagLOAD_ICON LOAD_ICON
#define IDR_POPUP
Definition: resource.h:7
#define COLOR_MENU
Definition: winuser.h:911
static VOID GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength)
Definition: kbswitch.c:412
LONG_PTR LPARAM
Definition: windef.h:208
HBITMAP hbmColor
Definition: winuser.h:3117
#define DT_VCENTER
Definition: winuser.h:543
HANDLE hMutex
Definition: mutex.c:11
static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
Definition: kbswitch.c:227
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:921
#define NIF_ICON
Definition: shellapi.h:103
#define WM_LANG_CHANGED
Definition: kbswitch.h:23
INT WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
Definition: kbswitch.c:884
#define DefWindowProc
Definition: ros2win.h:31
HINSTANCE hInst
Definition: kbswitch.c:33
#define WM_DESTROY
Definition: winuser.h:1599
#define MIIM_ID
Definition: winuser.h:717
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
#define PostMessage
Definition: winuser.h:5822
BOOL WINAPI SetProcessDefaultLayout(DWORD dwDefaultLayout)
Definition: window.c:1720
#define MF_CHECKED
Definition: winuser.h:132
VOID DeleteHooks(VOID)
Definition: kbswitch.c:573
char TCHAR
Definition: xmlstorage.h:189
BOOL fIcon
Definition: winuser.h:3113
VOID(WINAPI * PKBSWITCHDELETEHOOKS)(VOID)
Definition: kbswitch.h:27
#define _T(x)
Definition: vfdio.h:22
static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szLCID)
Definition: kbswitch.c:171
#define FreeLibrary(x)
Definition: compat.h:748
#define GetProcessHeap()
Definition: compat.h:736
#define CreateMutex
Definition: winbase.h:3627
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
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)
DWORD xHotspot
Definition: winuser.h:3114
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:28
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2550
#define WM_CLOSE
Definition: winuser.h:1611
#define WM_WINDOW_ACTIVATE
Definition: kbswitch.h:24
static VOID UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
Definition: kbswitch.c:393
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define NIM_DELETE
Definition: shellapi.h:93
LONG lfWidth
Definition: dimm.idl:43
#define WM_RBUTTONUP
Definition: winuser.h:1770
HICON g_hTrayIcon
Definition: kbswitch.c:37
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
#define SM_CXSMICON
Definition: winuser.h:1006
CHAR Message[80]
Definition: alive.c:5
int ret
#define _tcstoul
Definition: tchar.h:595
#define StringCchCopy
Definition: strsafe.h:139
HDC hdc
Definition: main.c:9
#define MB_ICONERROR
Definition: winuser.h:781
HICON hIcon
Definition: kbswitch.c:208
BOOL WINAPI RegisterShellHookWindow(_In_ HWND)
#define DI_NORMAL
Definition: wingdi.h:72
GLenum GLsizei len
Definition: glext.h:6722
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#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
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define GetSystemDirectory
Definition: winbase.h:3713
#define LoadCursor
Definition: winuser.h:5802
#define ID_EXIT
Definition: resource.h:10
BOOL WINAPI DestroyMenu(_In_ HMENU)
UINT uCallbackMessage
Definition: shellapi.h:229
#define RegisterWindowMessage
Definition: winuser.h:5830
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:342
ULONG ulCurrentLayoutNum
Definition: kbswitch.c:36
#define GetClassName
Definition: winuser.h:5773
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define MIIM_STRING
Definition: winuser.h:722
ULONG_PTR SIZE_T
Definition: typedefs.h:80
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: kbswitch.c:418
UINT ShellHookMessage
Definition: kbswitch.c:31
#define DT_SINGLELINE
Definition: winuser.h:540
TCHAR szKbSwitcherName[]
Definition: kbswitch.h:29
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define RegOpenKeyEx
Definition: winreg.h:520
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define TEXT(s)
Definition: k32.h:26
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
Definition: ime.c:890
static ULONG GetMaxLayoutNum(VOID)
Definition: kbswitch.c:519
#define LoadMenu
Definition: winuser.h:5807
PKBSWITCHSETHOOKS KbSwitchSetHooks
Definition: kbswitch.c:29
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
#define BLACKNESS
Definition: wingdi.h:323
BOOL WINAPI DeleteDC(_In_ HDC)
HICON hIcon
Definition: msconfig.c:44
FxAutoRegKey hKey
LPCWSTR szPath
Definition: env.c:37
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
#define WM_LBUTTONUP
Definition: winuser.h:1767
#define KLF_SETFORPROCESS
Definition: winuser.h:117
int CDECL _ttoi(const _TCHAR *str)
Definition: atoi.c:10
UINT UpdateLanguageDisplay(HWND hwnd, HKL hKl)
Definition: kbswitch.c:609
PKEYBOARD_LAYOUT GetKeyboardLayout()
Definition: utils.c:194
static BOOL GetLayoutName(LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
Definition: kbswitch.c:96
#define HWND_DESKTOP
Definition: winuser.h:1199
#define CreateFontIndirect
Definition: wingdi.h:4444
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define ID_NEXTLAYOUT
Definition: resource.h:12
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define GetMessage
Definition: winuser.h:5780
#define SPI_GETICONTITLELOGFONT
Definition: winuser.h:1370
#define NIM_ADD
Definition: shellapi.h:91
static HMENU BuildLeftPopupMenu(VOID)
Definition: kbswitch.c:465
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:846
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define LoadLibraryEx
Definition: winbase.h:3734
#define Shell_NotifyIcon
Definition: shellapi.h:689
UINT UpdateLanguageDisplayCurrent(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:640
#define WM_CREATE
Definition: winuser.h:1598
#define _ultot
Definition: tchar.h:610
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI IsWindowVisible(_In_ HWND)
#define MAKELANGID(p, s)
Definition: nls.h:15
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define DT_CENTER
Definition: winuser.h:527
#define GetProcAddress(x, y)
Definition: compat.h:753
#define LoadImage
Definition: winuser.h:5805
static HBITMAP
Definition: button.c:44
#define RegisterClass
Definition: winuser.h:5826
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define LoadIcon
Definition: winuser.h:5803
BOOL SetHooks(VOID)
Definition: kbswitch.c:553
static UINT GetCurLayoutNum(HKL hKL)
Definition: kbswitch.c:649
#define ID_PREFERENCES
Definition: resource.h:11
LONG_PTR LRESULT
Definition: windef.h:209
_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
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
#define LR_DEFAULTCOLOR
Definition: winuser.h:1081
HBRUSH WINAPI GetSysColorBrush(_In_ int)
LPSTR dwTypeData
Definition: winuser.h:3241
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
_Out_opt_ PICONINFO IconInfo
Definition: ntuser.h:2417
LPARAM lParam
Definition: combotst.c:139
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
int k
Definition: mpi.c:3369
#define LOWORD(l)
Definition: pedump.c:82
static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LPARAM lParam)
Definition: kbswitch.c:212
#define RegEnumValue
Definition: winreg.h:511
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define RegCloseKey(hKey)
Definition: registry.h:47
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define LoadString
Definition: winuser.h:5809
#define NIM_MODIFY
Definition: shellapi.h:92
WCHAR WndClass[]
Definition: capicon.c:23
#define InsertMenuItem
Definition: winuser.h:5794
HMODULE hModule
Definition: animate.c:44
HANDLE hProcessHeap
Definition: kbswitch.c:34
static VOID DeleteTrayIcon(HWND hwnd)
Definition: kbswitch.c:380
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
ULONG GetNextLayout(VOID)
Definition: kbswitch.c:588
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68