ReactOS 0.4.16-dev-1170-ge326b06
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 <shlobj.h>
12#include <shlwapi_undoc.h>
13#include <imm.h>
14#include <imm32_undoc.h>
15
16#include <wine/debug.h>
18
19/*
20 * This program kbswitch is a mimic of Win2k's internat.exe.
21 * However, there are some differences.
22 *
23 * Comparing with WinNT4 ActivateKeyboardLayout, WinXP ActivateKeyboardLayout has
24 * process boundary, so we cannot activate the IME keyboard layout from the outer process.
25 * It needs special care.
26 *
27 * We use global hook by our kbsdll.dll, to watch the shell and the windows.
28 *
29 * It might not work correctly on Vista+ because keyboard layout change notification
30 * won't be generated in Vista+.
31 */
32
33#define WM_NOTIFYICONMSG (WM_USER + 248)
34
38
47
48typedef struct
49{
52 TCHAR szKLID[CCH_LAYOUT_ID + 1];
54
57
59{
60 TCHAR szKLID[KL_NAMELENGTH], szLayoutId[16];
61 DWORD dwSize, dwIndex;
62 HKEY hKey, hLayoutKey;
63
64 g_cSpecialIds = 0;
65
67 TEXT("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"),
69 {
70 return;
71 }
72
73 for (dwIndex = 0; dwIndex < 1000; ++dwIndex)
74 {
75 dwSize = ARRAYSIZE(szKLID);
76 if (RegEnumKeyEx(hKey, dwIndex, szKLID, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
77 break;
78
79 if (RegOpenKeyEx(hKey, szKLID, 0, KEY_READ, &hLayoutKey) != ERROR_SUCCESS)
80 continue;
81
82 dwSize = sizeof(szLayoutId);
83 if (RegQueryValueEx(hLayoutKey, TEXT("Layout Id"), NULL, NULL,
84 (LPBYTE)szLayoutId, &dwSize) == ERROR_SUCCESS)
85 {
86 DWORD dwKLID = _tcstoul(szKLID, NULL, 16);
87 WORD wLangId = LOWORD(dwKLID), wLayoutId = LOWORD(_tcstoul(szLayoutId, NULL, 16));
88 HKL hKL = (HKL)(LONG_PTR)(SPECIAL_MASK | MAKELONG(wLangId, wLayoutId));
89
90 /* Add a special ID */
94 ARRAYSIZE(g_SpecialIds[g_cSpecialIds].szKLID), szKLID);
96 }
97
98 RegCloseKey(hLayoutKey);
99
101 {
102 OutputDebugStringA("g_SpecialIds is full!");
103 break;
104 }
105 }
106
108}
109
110static VOID
111GetKLIDFromHKL(HKL hKL, LPTSTR szKLID, SIZE_T KLIDLength)
112{
113 szKLID[0] = 0;
114
115 if (IS_IME_HKL(hKL))
116 {
117 StringCchPrintf(szKLID, KLIDLength, _T("%08lx"), (DWORD)(DWORD_PTR)hKL);
118 return;
119 }
120
121 if (IS_SPECIAL_HKL(hKL))
122 {
123 INT i;
124 for (i = 0; i < g_cSpecialIds; ++i)
125 {
126 if (g_SpecialIds[i].hKL == hKL)
127 {
128 StringCchCopy(szKLID, KLIDLength, g_SpecialIds[i].szKLID);
129 return;
130 }
131 }
132 }
133 else
134 {
135 StringCchPrintf(szKLID, KLIDLength, _T("%08lx"), LOWORD(hKL));
136 }
137}
138
140{
141 INT iKL;
142
143 if (!hKL)
144 {
146 DWORD dwTID = GetWindowThreadProcessId(hwndTarget, NULL);
147 hKL = GetKeyboardLayout(dwTID);
148 }
149
151
153 for (iKL = 0; iKL < g_cKLs; ++iKL)
154 {
155 if (g_ahKLs[iKL] == hKL)
156 {
157 g_nCurrentLayoutNum = iKL + 1;
158 break;
159 }
160 }
161
163 {
165 g_ahKLs[g_cKLs++] = hKL;
166 }
167}
168
169static HKL GetHKLFromLayoutNum(INT nLayoutNum)
170{
171 if (0 <= (nLayoutNum - 1) && (nLayoutNum - 1) < g_cKLs)
172 {
173 return g_ahKLs[nLayoutNum - 1];
174 }
175 else
176 {
178 DWORD dwTID = GetWindowThreadProcessId(hwndTarget, NULL);
179 return GetKeyboardLayout(dwTID);
180 }
181}
182
183static VOID
184GetKLIDFromLayoutNum(INT nLayoutNum, LPTSTR szKLID, SIZE_T KLIDLength)
185{
186 GetKLIDFromHKL(GetHKLFromLayoutNum(nLayoutNum), szKLID, KLIDLength);
187}
188
189static BOOL
191{
192 if (!GetSystemDirectory(szPath, cchPath))
193 return FALSE;
194
195 StringCchCat(szPath, cchPath, TEXT("\\"));
196 StringCchCat(szPath, cchPath, FileName);
197 return TRUE;
198}
199
200static BOOL
201GetLayoutName(INT nLayoutNum, LPTSTR szName, SIZE_T NameLength)
202{
203 HKEY hKey;
204 HRESULT hr;
206 TCHAR szBuf[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1];
207
208 GetKLIDFromLayoutNum(nLayoutNum, szKLID, ARRAYSIZE(szKLID));
209
210 StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
211 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
212
214 return FALSE;
215
216 /* Use "Layout Display Name" value as an entry name if possible */
217 hr = SHLoadRegUIString(hKey, _T("Layout Display Name"), szName, NameLength);
218 if (SUCCEEDED(hr))
219 {
221 return TRUE;
222 }
223
224 /* Otherwise, use "Layout Text" value as an entry name */
225 dwBufLen = NameLength * sizeof(TCHAR);
226 if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL,
228 {
230 return TRUE;
231 }
232
234 return FALSE;
235}
236
237static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szKLID)
238{
239 HKEY hKey;
241 TCHAR szBuf[MAX_PATH];
242
243 szImeFile[0] = UNICODE_NULL;
244
245 if (_tcslen(szKLID) != CCH_LAYOUT_ID)
246 return FALSE; /* Invalid LCID */
247
248 if (szKLID[0] != TEXT('E') && szKLID[0] != TEXT('e'))
249 return FALSE; /* Not an IME HKL */
250
251 StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
252 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
253
255 return FALSE;
256
257 dwBufLen = cchImeFile * sizeof(TCHAR);
258 if (RegQueryValueEx(hKey, _T("IME File"), NULL, NULL,
259 (LPBYTE)szImeFile, &dwBufLen) != ERROR_SUCCESS)
260 {
261 szImeFile[0] = UNICODE_NULL;
262 }
263
265
266 return (szImeFile[0] != UNICODE_NULL);
267}
268
269typedef struct tagLOAD_ICON
270{
274
275static BOOL CALLBACK
278 LPCTSTR lpszType,
279 LPTSTR lpszName,
281{
282 PLOAD_ICON pLoadIcon = (PLOAD_ICON)lParam;
283 pLoadIcon->hIcon = (HICON)LoadImage(hModule, lpszName, IMAGE_ICON,
284 pLoadIcon->cxIcon, pLoadIcon->cyIcon,
286 if (pLoadIcon->hIcon)
287 return FALSE; /* Stop enumeration */
288 return TRUE;
289}
290
291static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
292{
293 LOAD_ICON LoadIcon = { cxIcon, cyIcon, NULL };
294 HMODULE hImeDLL = LoadLibraryEx(szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
295 if (hImeDLL)
296 {
298 FreeLibrary(hImeDLL);
299 }
300 return LoadIcon.hIcon;
301}
302
304{
305 HDC hdcScreen = GetDC(NULL);
306 HDC hdc = CreateCompatibleDC(hdcScreen);
309 HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
310 HGDIOBJ hbmOld;
311
312 if (hbm != NULL)
313 {
314 hbmOld = SelectObject(hdc, hbm);
315 DrawIconEx(hdc, 0, 0, hIcon, cxIcon, cyIcon, 0, GetSysColorBrush(COLOR_MENU), DI_NORMAL);
316 SelectObject(hdc, hbmOld);
317 }
318
319 DeleteDC(hdc);
320 ReleaseDC(NULL, hdcScreen);
321 return hbm;
322}
323
324static HICON
326{
328 TCHAR szBuf[4];
329 HDC hdcScreen, hdc;
330 HBITMAP hbmColor, hbmMono, hBmpOld;
331 HFONT hFont, hFontOld;
332 LOGFONT lf;
333 RECT rect;
335 HICON hIcon;
339
340 if (szImeFile && szImeFile[0])
341 {
343 return FakeExtractIcon(szPath, cxIcon, cyIcon);
344 }
345
346 /* Getting "EN", "FR", etc. from English, French, ... */
347 LangID = LANGIDFROMLCID(_tcstoul(szKLID, NULL, 16));
350 szBuf,
351 ARRAYSIZE(szBuf)) == 0)
352 {
353 szBuf[0] = szBuf[1] = _T('?');
354 }
355 szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
356
357 /* Create hdc, hbmColor and hbmMono */
358 hdcScreen = GetDC(NULL);
359 hdc = CreateCompatibleDC(hdcScreen);
360 hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
361 ReleaseDC(NULL, hdcScreen);
362 hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
363
364 /* Checking NULL */
365 if (!hdc || !hbmColor || !hbmMono)
366 {
367 if (hbmMono)
368 DeleteObject(hbmMono);
369 if (hbmColor)
370 DeleteObject(hbmColor);
371 if (hdc)
372 DeleteDC(hdc);
373 return NULL;
374 }
375
376 /* Create a font */
377 hFont = NULL;
378 if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
379 {
380 /* Override the current size with something manageable */
381 lf.lfHeight = -11;
382 lf.lfWidth = 0;
384 }
385 if (!hFont)
387
388 SetRect(&rect, 0, 0, cxIcon, cyIcon);
389
390 /* Draw hbmColor */
391 hBmpOld = SelectObject(hdc, hbmColor);
393 FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
394 hFontOld = SelectObject(hdc, hFont);
398 SelectObject(hdc, hFontOld);
399
400 /* Fill hbmMono with black */
401 SelectObject(hdc, hbmMono);
402 PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
403 SelectObject(hdc, hBmpOld);
404
405 /* Create an icon from hbmColor and hbmMono */
408 IconInfo.hbmColor = hbmColor;
409 IconInfo.hbmMask = hbmMono;
411
412 /* Clean up */
414 DeleteObject(hbmMono);
415 DeleteObject(hbmColor);
416 DeleteDC(hdc);
417
418 return hIcon;
419}
420
421static VOID
423{
424 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
425 TCHAR szKLID[CCH_LAYOUT_ID + 1], szName[MAX_PATH], szImeFile[80];
426
429 GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szKLID);
430
432 tnid.hIcon = CreateTrayIcon(szKLID, szImeFile);
434
436
437 if (g_hTrayIcon)
439 g_hTrayIcon = tnid.hIcon;
440}
441
442static VOID
444{
445 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1 };
447
448 if (g_hTrayIcon)
449 {
452 }
453}
454
455static VOID
457{
458 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
459 TCHAR szImeFile[80];
460
461 GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szKLID);
462
464 tnid.hIcon = CreateTrayIcon(szKLID, szImeFile);
466
468
469 if (g_hTrayIcon)
471 g_hTrayIcon = tnid.hIcon;
472}
473
474static BOOL CALLBACK
476{
477 PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET, lParam);
478 return TRUE;
479}
480
481static VOID
482ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
483{
484 HKL hKl;
485 TCHAR szKLID[CCH_LAYOUT_ID + 1], szLangName[MAX_PATH];
487
488 /* The layout number starts from one. Zero is invalid */
489 if (uLayoutNum == 0 || uLayoutNum > 0xFF) /* Invalid */
490 return;
491
492 GetKLIDFromLayoutNum(uLayoutNum, szKLID, ARRAYSIZE(szKLID));
493 LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
494
495 /* Switch to the new keyboard layout */
496 GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
497 UpdateTrayIcon(hwnd, szKLID, szLangName);
498
499 if (hwndTarget && !bNoActivate)
500 SetForegroundWindow(hwndTarget);
501
502 hKl = LoadKeyboardLayout(szKLID, KLF_ACTIVATE);
503 if (hKl)
505
506 /* Post WM_INPUTLANGCHANGEREQUEST */
507 if (hwndTarget)
508 {
509 PostMessage(hwndTarget, WM_INPUTLANGCHANGEREQUEST,
510 INPUTLANGCHANGE_SYSCHARSET, (LPARAM)hKl);
511 }
512 else
513 {
515 }
516
517 g_nCurrentLayoutNum = uLayoutNum;
518}
519
520static HMENU
522{
523 HMENU hMenu = CreatePopupMenu();
524 TCHAR szName[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1], szImeFile[80];
525 HICON hIcon;
526 MENUITEMINFO mii = { sizeof(mii) };
527 INT iKL;
528
529 for (iKL = 0; iKL < g_cKLs; ++iKL)
530 {
531 GetKLIDFromHKL(g_ahKLs[iKL], szKLID, ARRAYSIZE(szKLID));
532 GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szKLID);
533
534 if (!GetLayoutName(iKL + 1, szName, ARRAYSIZE(szName)))
535 continue;
536
537 mii.fMask = MIIM_ID | MIIM_STRING;
538 mii.wID = iKL + 1;
539 mii.dwTypeData = szName;
540
541 hIcon = CreateTrayIcon(szKLID, szImeFile);
542 if (hIcon)
543 {
544 mii.hbmpItem = BitmapFromIcon(hIcon);
545 if (mii.hbmpItem)
546 mii.fMask |= MIIM_BITMAP;
547 }
548
549 InsertMenuItem(hMenu, -1, TRUE, &mii);
551 }
552
554
555 return hMenu;
556}
557
558BOOL
560{
561 g_hHookDLL = LoadLibrary(_T("kbsdll.dll"));
562 if (!g_hHookDLL)
563 {
564 return FALSE;
565 }
566
567#define IHOOK_SET 1
568#define IHOOK_DELETE 2
571
573 {
574 ERR("SetHooks failed\n");
575 return FALSE;
576 }
577
578 TRACE("SetHooks OK\n");
579 return TRUE;
580}
581
582VOID
584{
586 {
589 }
590
591 if (g_hHookDLL)
592 {
595 }
596
597 TRACE("DeleteHooks OK\n");
598}
599
601{
602 INT iKL;
603
604 for (iKL = 0; iKL < g_cKLs; ++iKL)
605 {
606 if (g_ahKLs[iKL] == hKL)
607 return iKL + 1;
608 }
609
610 return 0;
611}
612
613ULONG
615{
616 return (g_nCurrentLayoutNum % g_cKLs) + 1;
617}
618
619UINT
621{
622 TCHAR szKLID[MAX_PATH], szLangName[MAX_PATH];
624
625 GetKLIDFromHKL(hKL, szKLID, ARRAYSIZE(szKLID));
626 LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
627 GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
628 UpdateTrayIcon(hwnd, szKLID, szLangName);
630
631 return 0;
632}
633
634HWND
636{
637 TCHAR szClass[64];
638 HWND hwndIME;
639 HWND hwndTarget = hwndFore;
640 if (hwndTarget == NULL)
641 hwndTarget = GetForegroundWindow();
642
643 GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass));
644 if (_tcsicmp(szClass, szKbSwitcherName) == 0)
645 hwndTarget = g_hwndLastActive;
646
647 hwndIME = ImmGetDefaultIMEWnd(hwndTarget);
648 return (hwndIME ? hwndIME : hwndTarget);
649}
650
651UINT
653{
654 DWORD dwThreadID = GetWindowThreadProcessId(GetTargetWindow(hwndFore), NULL);
655 HKL hKL = GetKeyboardLayout(dwThreadID);
657
658 return 0;
659}
660
662{
663 TCHAR szClass[64];
664
665 hwndFore = GetAncestor(hwndFore, GA_ROOT);
666
667 if (!IsWindowVisible(hwndFore) || !GetClassName(hwndFore, szClass, ARRAYSIZE(szClass)))
668 return FALSE;
669
670 if (_tcsicmp(szClass, szKbSwitcherName) == 0 ||
671 _tcsicmp(szClass, TEXT("Shell_TrayWnd")) == 0)
672 {
673 return FALSE; /* Special window */
674 }
675
676 /* FIXME: CONWND needs special handling */
677 if (_tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
678 {
679 HKL hKL = GetKeyboardLayout(0);
681 }
682
683 g_hwndLastActive = hwndFore;
684 return TRUE;
685}
686
689{
690 static HMENU s_hMenu = NULL, s_hRightPopupMenu = NULL;
691 static UINT s_uTaskbarRestart;
692 POINT pt;
693 HMENU hLeftPopupMenu;
694
695 switch (Message)
696 {
697 case WM_CREATE:
698 {
699 if (!SetHooks())
700 {
701 MessageBox(NULL, TEXT("SetHooks failed."), NULL, MB_ICONERROR);
702 return -1;
703 }
704
706
709
711 s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
712 break;
713 }
714
715 case WM_LANG_CHANGED: /* Comes from kbsdll.dll and this module */
716 {
717 TRACE("WM_LANG_CHANGED: wParam:%p, lParam:%p\n", wParam, lParam);
720 break;
721 }
722
723 case WM_WINDOW_ACTIVATE: /* Comes from kbsdll.dll and this module */
724 {
725 HWND hwndFore;
726 TRACE("WM_WINDOW_ACTIVATE: wParam:%p, lParam:%p\n", wParam, lParam);
727 hwndFore = GetForegroundWindow();
728 if (RememberLastActive(hwnd, hwndFore))
729 return UpdateLanguageDisplayCurrent(hwnd, hwndFore);
730 break;
731 }
732
733 case WM_NOTIFYICONMSG:
734 {
735 switch (lParam)
736 {
737 case WM_RBUTTONUP:
738 case WM_LBUTTONUP:
739 {
741
744
745 if (lParam == WM_LBUTTONUP)
746 {
747 /* Rebuild the left popup menu on every click to take care of keyboard layout changes */
748 hLeftPopupMenu = BuildLeftPopupMenu();
749 TrackPopupMenu(hLeftPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
750 DestroyMenu(hLeftPopupMenu);
751 }
752 else
753 {
754 if (!s_hRightPopupMenu)
755 {
757 s_hRightPopupMenu = GetSubMenu(s_hMenu, 0);
758 }
759 TrackPopupMenu(s_hRightPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
760 }
761
762 PostMessage(hwnd, WM_NULL, 0, 0);
763 break;
764 }
765 }
766 break;
767 }
768
769 case WM_COMMAND:
770 switch (LOWORD(wParam))
771 {
772 case ID_EXIT:
773 {
774 PostMessage(hwnd, WM_CLOSE, 0, 0);
775 break;
776 }
777
778 case ID_PREFERENCES:
779 {
781 TEXT("control.exe"), TEXT("input.dll"),
783 if (ret <= 32)
784 MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_ICONERROR);
785 break;
786 }
787
788 case ID_NEXTLAYOUT:
789 {
790 HWND hwndTarget = (HWND)lParam, hwndTargetSave = NULL;
791 DWORD dwThreadID;
792 HKL hKL;
793 UINT uNum;
794 TCHAR szClass[64];
795 BOOL bCONWND = FALSE;
796
797 if (hwndTarget == NULL)
798 hwndTarget = g_hwndLastActive;
799
800 /* FIXME: CONWND needs special handling */
801 if (hwndTarget &&
802 GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass)) &&
803 _tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
804 {
805 bCONWND = TRUE;
806 hwndTargetSave = hwndTarget;
807 hwndTarget = NULL;
808 }
809
810 if (hwndTarget)
811 {
812 dwThreadID = GetWindowThreadProcessId(hwndTarget, NULL);
813 hKL = GetKeyboardLayout(dwThreadID);
814 uNum = GetLayoutNum(hKL);
815 if (uNum != 0)
816 g_nCurrentLayoutNum = uNum;
817 }
818
819 ActivateLayout(hwnd, GetNextLayout(), hwndTarget, TRUE);
820
821 /* FIXME: CONWND needs special handling */
822 if (bCONWND)
823 ActivateLayout(hwnd, g_nCurrentLayoutNum, hwndTargetSave, TRUE);
824
825 break;
826 }
827
828 default:
829 {
830 if (1 <= LOWORD(wParam) && LOWORD(wParam) <= 1000)
831 {
833 {
835 }
837 }
838 break;
839 }
840 }
841 break;
842
843 case WM_SETTINGCHANGE:
844 {
845 if (wParam == SPI_SETNONCLIENTMETRICS)
846 {
848 break;
849 }
850 }
851 break;
852
853 case WM_DESTROY:
854 {
855 DeleteHooks();
856 DestroyMenu(s_hMenu);
859 break;
860 }
861
862 default:
863 {
864 if (Message == s_uTaskbarRestart)
865 {
868 break;
869 }
870 else if (Message == ShellHookMessage)
871 {
872 TRACE("ShellHookMessage: wParam:%p, lParam:%p\n", wParam, lParam);
873 if (wParam == HSHELL_LANGUAGE)
875 else if (wParam == HSHELL_WINDOWACTIVATED)
877
878 break;
879 }
881 }
882 }
883
884 return 0;
885}
886
888_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
889{
891 MSG msg;
893 HWND hwnd;
894
895 switch (GetUserDefaultUILanguage())
896 {
898 TRACE("LAYOUT_RTL\n");
900 break;
901 default:
902 break;
903 }
904
906 if (!hMutex)
907 {
908 ERR("!hMutex\n");
909 return 1;
910 }
911
913 {
914 ERR("Another instance is already running\n");
916 return 1;
917 }
918
921
922 ZeroMemory(&WndClass, sizeof(WndClass));
923 WndClass.lpfnWndProc = WndProc;
924 WndClass.hInstance = hInstance;
925 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
926 WndClass.lpszClassName = szKbSwitcherName;
927 if (!RegisterClass(&WndClass))
928 {
930 return 1;
931 }
932
936 {
937 ERR("RegisterShellHookWindow failed\n");
940 return 1;
941 }
942
943 while (GetMessage(&msg, NULL, 0, 0))
944 {
947 }
948
950 return 0;
951}
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#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
HFONT hFont
Definition: main.c:53
#define SPECIAL_MASK
Definition: debug.h:13
#define ERR(fmt,...)
Definition: precomp.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
WCHAR WndClass[]
Definition: capicon.c:23
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
Definition: ime.c:572
LANGID WINAPI GetUserDefaultUILanguage(void)
Definition: locale.c:1375
static const WCHAR Message[]
Definition: register.c:74
#define pt(x, y)
Definition: drawing.c:79
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
pKey DeleteObject()
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
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
#define IS_SPECIAL_HKL(hKL)
Definition: imm32_undoc.h:22
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:21
#define _tcstoul
Definition: tchar.h:595
#define _tWinMain
Definition: tchar.h:498
_Out_opt_ PICONINFO IconInfo
Definition: ntuser.h:2299
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define TEXT(s)
Definition: k32.h:26
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: kbswitch.c:475
#define IHOOK_SET
static VOID LoadSpecialIds(VOID)
Definition: kbswitch.c:58
static HBITMAP BitmapFromIcon(HICON hIcon)
Definition: kbswitch.c:303
UINT ShellHookMessage
Definition: kbswitch.c:37
PKBSWITCHSETHOOKS KbSwitchSetHooks
Definition: kbswitch.c:35
struct tagLOAD_ICON LOAD_ICON
static VOID UpdateTrayIcon(HWND hwnd, LPTSTR szKLID, LPTSTR szName)
Definition: kbswitch.c:456
struct SPECIAL_ID * PSPECIAL_ID
INT g_cSpecialIds
Definition: kbswitch.c:56
static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
Definition: kbswitch.c:291
static BOOL GetLayoutName(INT nLayoutNum, LPTSTR szName, SIZE_T NameLength)
Definition: kbswitch.c:201
HINSTANCE hInst
Definition: kbswitch.c:39
static VOID GetKLIDFromHKL(HKL hKL, LPTSTR szKLID, SIZE_T KLIDLength)
Definition: kbswitch.c:111
static UINT GetLayoutNum(HKL hKL)
Definition: kbswitch.c:600
SPECIAL_ID g_SpecialIds[80]
Definition: kbswitch.c:55
static HICON CreateTrayIcon(LPTSTR szKLID, LPCTSTR szImeFile OPTIONAL)
Definition: kbswitch.c:325
static HKL GetHKLFromLayoutNum(INT nLayoutNum)
Definition: kbswitch.c:169
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:688
static HMENU BuildLeftPopupMenu(VOID)
Definition: kbswitch.c:521
HKL g_ahKLs[64]
Definition: kbswitch.c:46
static BOOL RememberLastActive(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:661
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks
Definition: kbswitch.c:36
static VOID UpdateLayoutList(HKL hKL OPTIONAL)
Definition: kbswitch.c:139
static VOID ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
Definition: kbswitch.c:482
ULONG GetNextLayout(VOID)
Definition: kbswitch.c:614
static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LPARAM lParam)
Definition: kbswitch.c:276
HWND g_hwndLastActive
Definition: kbswitch.c:44
VOID DeleteHooks(VOID)
Definition: kbswitch.c:583
static VOID GetKLIDFromLayoutNum(INT nLayoutNum, LPTSTR szKLID, SIZE_T KLIDLength)
Definition: kbswitch.c:184
INT g_cKLs
Definition: kbswitch.c:45
UINT UpdateLanguageDisplay(HWND hwnd, HKL hKL)
Definition: kbswitch.c:620
static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szKLID)
Definition: kbswitch.c:237
HICON g_hTrayIcon
Definition: kbswitch.c:43
UINT UpdateLanguageDisplayCurrent(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:652
HMODULE g_hHookDLL
Definition: kbswitch.c:41
INT g_nCurrentLayoutNum
Definition: kbswitch.c:42
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:33
struct tagLOAD_ICON * PLOAD_ICON
BOOL SetHooks(VOID)
Definition: kbswitch.c:559
static BOOL GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
Definition: kbswitch.c:190
#define IHOOK_DELETE
HANDLE hProcessHeap
Definition: kbswitch.c:40
static VOID AddTrayIcon(HWND hwnd)
Definition: kbswitch.c:422
static VOID DeleteTrayIcon(HWND hwnd)
Definition: kbswitch.c:443
HWND GetTargetWindow(HWND hwndFore)
Definition: kbswitch.c:635
#define CCH_LAYOUT_ID
Definition: kbswitch.h:18
BOOL(WINAPI * PKBSWITCHSETHOOKS)(VOID)
Definition: kbswitch.h:27
const TCHAR szKbSwitcherName[]
Definition: kbswitch.h:30
#define WM_WINDOW_ACTIVATE
Definition: kbswitch.h:25
VOID(WINAPI * PKBSWITCHDELETEHOOKS)(VOID)
Definition: kbswitch.h:28
#define WM_LANG_CHANGED
Definition: kbswitch.h:24
USHORT LANGID
Definition: mui.h:9
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
LPCWSTR szPath
Definition: env.c:37
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
HDC hdc
Definition: main.c:9
HANDLE hMutex
Definition: mutex.c:11
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
HICON hIcon
Definition: msconfig.c:44
UINT_PTR HKL
Definition: msctf.idl:143
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define UNICODE_NULL
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
#define L(x)
Definition: ntvdm.h:50
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define LOWORD(l)
Definition: pedump.c:82
#define RT_GROUP_ICON
Definition: pedump.c:375
static const WCHAR szName[]
Definition: powrprof.c:45
#define DefWindowProc
Definition: ros2win.h:31
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_HEBREW
Definition: nls.h:67
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define SUBLANG_DEFAULT
Definition: nls.h:168
#define ShellExecute
Definition: shellapi.h:733
#define NIM_DELETE
Definition: shellapi.h:97
#define NIM_MODIFY
Definition: shellapi.h:96
#define NIF_ICON
Definition: shellapi.h:107
#define NIF_MESSAGE
Definition: shellapi.h:106
#define NIM_ADD
Definition: shellapi.h:95
#define Shell_NotifyIcon
Definition: shellapi.h:731
#define NIF_TIP
Definition: shellapi.h:108
HRESULT hr
Definition: shlfolder.c:183
#define SHLoadRegUIString
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
#define StringCchCopy
Definition: strsafe.h:139
#define StringCchPrintf
Definition: strsafe.h:517
#define StringCchCat
Definition: strsafe.h:317
LONG lfHeight
Definition: dimm.idl:42
LONG lfWidth
Definition: dimm.idl:43
DWORD dwLayoutId
Definition: kbswitch.c:50
HKL hKL
Definition: kbswitch.c:51
DWORD yHotspot
Definition: winuser.h:3136
BOOL fIcon
Definition: winuser.h:3134
DWORD xHotspot
Definition: winuser.h:3135
HBITMAP hbmColor
Definition: winuser.h:3138
HBITMAP hbmMask
Definition: winuser.h:3137
UINT uCallbackMessage
Definition: shellapi.h:232
CHAR szTip[128]
Definition: shellapi.h:238
HICON hIcon
Definition: kbswitch.c:272
LPSTR dwTypeData
Definition: winuser.h:3262
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
uint32_t ULONG
Definition: typedefs.h:59
#define _T(x)
Definition: vfdio.h:22
int ret
_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
COLORREF WINAPI SetDCBrushColor(_In_ HDC hdc, _In_ COLORREF crColor)
Definition: dc.c:905
BOOL WINAPI SetProcessDefaultLayout(DWORD dwDefaultLayout)
Definition: window.c:1689
#define ZeroMemory
Definition: winbase.h:1744
#define GetSystemDirectory
Definition: winbase.h:3874
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LoadLibraryEx
Definition: winbase.h:3895
#define LoadLibrary
Definition: winbase.h:3894
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:369
#define CreateMutex
Definition: winbase.h:3788
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
#define EnumResourceNames
Definition: winbase.h:3804
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4246
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#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
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DI_NORMAL
Definition: wingdi.h:72
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define TRANSPARENT
Definition: wingdi.h:950
#define LAYOUT_RTL
Definition: wingdi.h:1371
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
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:917
BOOL WINAPI DeleteDC(_In_ HDC)
#define CreateFontIndirect
Definition: wingdi.h:4444
#define GetLocaleInfo
Definition: winnls.h:1243
#define LOCALE_SLANGUAGE
Definition: winnls.h:27
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:30
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RegOpenKeyEx
Definition: winreg.h:520
#define RegQueryValueEx
Definition: winreg.h:524
#define RegEnumKeyEx
Definition: winreg.h:510
#define SW_SHOWNORMAL
Definition: winuser.h:781
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD WINAPI GetSysColor(_In_ int)
BOOL WINAPI IsWindow(_In_opt_ HWND)
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define WM_CLOSE
Definition: winuser.h:1632
#define MIIM_STRING
Definition: winuser.h:738
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2943
#define GA_ROOT
Definition: winuser.h:2800
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define MIIM_ID
Definition: winuser.h:733
#define COLOR_MENU
Definition: winuser.h:928
#define KLF_SETFORPROCESS
Definition: winuser.h:117
#define DT_CENTER
Definition: winuser.h:527
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define KL_NAMELENGTH
Definition: winuser.h:122
#define IMAGE_ICON
Definition: winuser.h:212
#define WM_CREATE
Definition: winuser.h:1619
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define GetClassName
Definition: winuser.h:5803
#define KLF_ACTIVATE
Definition: winuser.h:111
BOOL WINAPI RegisterShellHookWindow(_In_ HWND)
#define COLOR_HIGHLIGHT
Definition: winuser.h:937
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define DT_SINGLELINE
Definition: winuser.h:540
#define WM_COMMAND
Definition: winuser.h:1751
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:695
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3032
#define WM_RBUTTONUP
Definition: winuser.h:1791
#define InsertMenuItem
Definition: winuser.h:5824
#define SM_CYSMICON
Definition: winuser.h:1024
#define MF_CHECKED
Definition: winuser.h:132
#define LoadKeyboardLayout
Definition: winuser.h:5836
#define SPI_GETICONTITLELOGFONT
Definition: winuser.h:1391
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define DrawText
Definition: winuser.h:5791
#define CreateWindow
Definition: winuser.h:5774
#define HWND_DESKTOP
Definition: winuser.h:1220
#define MB_ICONERROR
Definition: winuser.h:798
#define WM_SETTINGCHANGE
Definition: winuser.h:1640
#define GetMessage
Definition: winuser.h:5810
#define SM_CXSMICON
Definition: winuser.h:1023
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define RegisterWindowMessage
Definition: winuser.h:5860
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)
#define MIIM_BITMAP
Definition: winuser.h:739
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:2365
#define LoadIcon
Definition: winuser.h:5833
#define WM_NULL
Definition: winuser.h:1618
#define LoadCursor
Definition: winuser.h:5832
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:938
HDC WINAPI GetDC(_In_opt_ HWND)
#define LoadMenu
Definition: winuser.h:5837
#define WM_LBUTTONUP
Definition: winuser.h:1788
#define DT_VCENTER
Definition: winuser.h:543
#define PostMessage
Definition: winuser.h:5852
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
#define LoadImage
Definition: winuser.h:5835
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MessageBox
Definition: winuser.h:5842
#define LR_DEFAULTCOLOR
Definition: winuser.h:1098
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define RegisterClass
Definition: winuser.h:5856
#define WM_DESTROY
Definition: winuser.h:1620
#define DispatchMessage
Definition: winuser.h:5785
HKL WINAPI ActivateKeyboardLayout(_In_ HKL, _In_ UINT)
#define SystemParametersInfo
Definition: winuser.h:5878
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI DestroyWindow(_In_ HWND)
int WINAPI GetSystemMetrics(_In_ int)
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
Definition: window.c:929
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2390
char TCHAR
Definition: xmlstorage.h:189
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198
#define _tcsicmp
Definition: xmlstorage.h:205