ReactOS 0.4.16-dev-1260-g901af6a
kbswitch.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Keyboard Layout Switcher
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Switching Keyboard Layouts
5 * COPYRIGHT: Copyright Dmitry Chapyshev (dmitry@reactos.org)
6 * Copyright Colin Finck (mail@colinfinck.de)
7 * Copyright 2022-2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8 */
9#include "kbswitch.h"
10#include <shlobj.h>
11#include <shlwapi_undoc.h>
12#include <imm.h>
13#include <imm32_undoc.h>
14
15#include <wine/debug.h>
17
18/*
19 * This program kbswitch is a mimic of Win2k's internat.exe.
20 * However, there are some differences.
21 *
22 * Comparing with WinNT4 ActivateKeyboardLayout, WinXP ActivateKeyboardLayout has
23 * process boundary, so we cannot activate the IME keyboard layout from the outer process.
24 * It needs special care.
25 *
26 * We use global hook by our indicdll.dll, to watch the shell and the windows.
27 *
28 * It might not work correctly on Vista+ because keyboard layout change notification
29 * won't be generated in Vista+.
30 */
31
32#define WM_NOTIFYICONMSG (WM_USER + 248)
33
34#define TIMER_ID_LANG_CHANGED_DELAYED 0x10000
35#define TIMER_LANG_CHANGED_DELAY 200
36
38
48
49typedef struct tagSPECIAL_ID
50{
55
56#define MAX_SPECIAL_IDS 256
57
60
62{
63 TCHAR szKLID[KL_NAMELENGTH], szLayoutId[16];
64 DWORD dwSize, dwIndex;
65 HKEY hKey, hLayoutKey;
66
67 g_cSpecialIds = 0;
68
70 TEXT("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"),
72 {
73 return;
74 }
75
76 for (dwIndex = 0; dwIndex < 1000; ++dwIndex)
77 {
78 dwSize = _countof(szKLID);
79 if (RegEnumKeyEx(hKey, dwIndex, szKLID, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
80 break;
81
82 if (RegOpenKeyEx(hKey, szKLID, 0, KEY_READ, &hLayoutKey) != ERROR_SUCCESS)
83 continue;
84
85 dwSize = sizeof(szLayoutId);
86 if (RegQueryValueEx(hLayoutKey, TEXT("Layout Id"), NULL, NULL,
87 (LPBYTE)szLayoutId, &dwSize) == ERROR_SUCCESS)
88 {
89 DWORD dwKLID = _tcstoul(szKLID, NULL, 16);
90 WORD wLangId = LOWORD(dwKLID), wLayoutId = LOWORD(_tcstoul(szLayoutId, NULL, 16));
91 HKL hKL = (HKL)(LONG_PTR)(SPECIAL_MASK | MAKELONG(wLangId, wLayoutId));
92
93 /* Add a special ID */
97 _countof(g_SpecialIds[g_cSpecialIds].szKLID), szKLID);
99 }
100
101 RegCloseKey(hLayoutKey);
102
104 {
105 ERR("g_SpecialIds is full!");
106 break;
107 }
108 }
109
111}
112
113static VOID
114GetKLIDFromHKL(HKL hKL, LPTSTR szKLID, SIZE_T KLIDLength)
115{
116 szKLID[0] = 0;
117
118 if (IS_IME_HKL(hKL))
119 {
120 StringCchPrintf(szKLID, KLIDLength, _T("%08lx"), (DWORD)(DWORD_PTR)hKL);
121 return;
122 }
123
124 if (IS_SPECIAL_HKL(hKL))
125 {
126 INT i;
127 for (i = 0; i < g_cSpecialIds; ++i)
128 {
129 if (g_SpecialIds[i].hKL == hKL)
130 {
131 StringCchCopy(szKLID, KLIDLength, g_SpecialIds[i].szKLID);
132 return;
133 }
134 }
135 }
136 else
137 {
138 StringCchPrintf(szKLID, KLIDLength, _T("%08lx"), LOWORD(hKL));
139 }
140}
141
143{
144 /* FIXME: Get correct console window's HKL when console window */
146 DWORD dwTID = GetWindowThreadProcessId(hwndTarget, NULL);
147 return GetKeyboardLayout(dwTID);
148}
149
151{
152 UINT iKL;
153
154 if (!hKL)
155 hKL = GetActiveKL();
156
158
159 g_iKL = 0;
160 for (iKL = 0; iKL < g_cKLs; ++iKL)
161 {
162 if (g_ahKLs[iKL] == hKL)
163 {
164 g_iKL = iKL;
165 break;
166 }
167 }
168}
169
171{
172 return (iKL < g_cKLs) ? g_ahKLs[iKL] : GetActiveKL();
173}
174
175static VOID
176GetKLIDFromLayoutNum(UINT iKL, LPTSTR szKLID, SIZE_T KLIDLength)
177{
178 GetKLIDFromHKL(GetHKLFromLayoutNum(iKL), szKLID, KLIDLength);
179}
180
181static BOOL
183{
184 if (!GetSystemDirectory(szPath, cchPath))
185 return FALSE;
186
187 StringCchCat(szPath, cchPath, TEXT("\\"));
188 StringCchCat(szPath, cchPath, FileName);
189 return TRUE;
190}
191
192static BOOL
194{
195 HKEY hKey;
196 HRESULT hr;
198 TCHAR szBuf[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1];
199
200 GetKLIDFromLayoutNum(iKL, szKLID, _countof(szKLID));
201
202 StringCchPrintf(szBuf, _countof(szBuf),
203 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
204
206 return FALSE;
207
208 /* Use "Layout Display Name" value as an entry name if possible */
209 hr = SHLoadRegUIString(hKey, _T("Layout Display Name"), szName, NameLength);
210 if (SUCCEEDED(hr))
211 {
213 return TRUE;
214 }
215
216 /* Otherwise, use "Layout Text" value as an entry name */
217 dwBufLen = NameLength * sizeof(TCHAR);
218 if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL,
220 {
222 return TRUE;
223 }
224
226 return FALSE;
227}
228
229static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szKLID)
230{
231 HKEY hKey;
233 TCHAR szBuf[MAX_PATH];
234
235 szImeFile[0] = UNICODE_NULL;
236
237 if (_tcslen(szKLID) != CCH_LAYOUT_ID)
238 return FALSE; /* Invalid LCID */
239
240 if (szKLID[0] != TEXT('E') && szKLID[0] != TEXT('e'))
241 return FALSE; /* Not an IME HKL */
242
243 StringCchPrintf(szBuf, _countof(szBuf),
244 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szKLID);
245
247 return FALSE;
248
249 dwBufLen = cchImeFile * sizeof(TCHAR);
250 if (RegQueryValueEx(hKey, _T("IME File"), NULL, NULL,
251 (LPBYTE)szImeFile, &dwBufLen) != ERROR_SUCCESS)
252 {
253 szImeFile[0] = UNICODE_NULL;
254 }
255
257
258 return (szImeFile[0] != UNICODE_NULL);
259}
260
261typedef struct tagLOAD_ICON
262{
266
267static BOOL CALLBACK
270 LPCTSTR lpszType,
271 LPTSTR lpszName,
273{
274 PLOAD_ICON pLoadIcon = (PLOAD_ICON)lParam;
275 pLoadIcon->hIcon = (HICON)LoadImage(hModule, lpszName, IMAGE_ICON,
276 pLoadIcon->cxIcon, pLoadIcon->cyIcon,
278 if (pLoadIcon->hIcon)
279 return FALSE; /* Stop enumeration */
280 return TRUE;
281}
282
283static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
284{
285 LOAD_ICON LoadIcon = { cxIcon, cyIcon, NULL };
286 HMODULE hImeDLL = LoadLibraryEx(szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
287 if (hImeDLL)
288 {
290 FreeLibrary(hImeDLL);
291 }
292 return LoadIcon.hIcon;
293}
294
296{
297 HDC hdcScreen = GetDC(NULL);
298 HDC hdc = CreateCompatibleDC(hdcScreen);
301 HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
302 HGDIOBJ hbmOld;
303
304 if (hbm != NULL)
305 {
306 hbmOld = SelectObject(hdc, hbm);
307 DrawIconEx(hdc, 0, 0, hIcon, cxIcon, cyIcon, 0, GetSysColorBrush(COLOR_MENU), DI_NORMAL);
308 SelectObject(hdc, hbmOld);
309 }
310
311 DeleteDC(hdc);
312 ReleaseDC(NULL, hdcScreen);
313 return hbm;
314}
315
316static HICON
318{
320 TCHAR szBuf[4];
321 HDC hdcScreen, hdc;
322 HBITMAP hbmColor, hbmMono, hBmpOld;
323 HFONT hFont, hFontOld;
324 LOGFONT lf;
325 RECT rect;
327 HICON hIcon;
331
332 if (szImeFile && szImeFile[0])
333 {
334 if (GetSystemLibraryPath(szPath, _countof(szPath), szImeFile))
335 return FakeExtractIcon(szPath, cxIcon, cyIcon);
336 }
337
338 /* Getting "EN", "FR", etc. from English, French, ... */
339 LangID = LANGIDFROMLCID(_tcstoul(szKLID, NULL, 16));
342 szBuf,
343 _countof(szBuf)) == 0)
344 {
345 szBuf[0] = szBuf[1] = _T('?');
346 }
347 szBuf[2] = 0; /* Truncate the identifier to two characters: "ENG" --> "EN" etc. */
348
349 /* Create hdc, hbmColor and hbmMono */
350 hdcScreen = GetDC(NULL);
351 hdc = CreateCompatibleDC(hdcScreen);
352 hbmColor = CreateCompatibleBitmap(hdcScreen, cxIcon, cyIcon);
353 ReleaseDC(NULL, hdcScreen);
354 hbmMono = CreateBitmap(cxIcon, cyIcon, 1, 1, NULL);
355
356 /* Checking NULL */
357 if (!hdc || !hbmColor || !hbmMono)
358 {
359 if (hbmMono)
360 DeleteObject(hbmMono);
361 if (hbmColor)
362 DeleteObject(hbmColor);
363 if (hdc)
364 DeleteDC(hdc);
365 return NULL;
366 }
367
368 /* Create a font */
369 hFont = NULL;
370 if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
371 {
372 /* Override the current size with something manageable */
373 lf.lfHeight = -11;
374 lf.lfWidth = 0;
376 }
377 if (!hFont)
379
380 SetRect(&rect, 0, 0, cxIcon, cyIcon);
381
382 /* Draw hbmColor */
383 hBmpOld = SelectObject(hdc, hbmColor);
385 FillRect(hdc, &rect, (HBRUSH)GetStockObject(DC_BRUSH));
386 hFontOld = SelectObject(hdc, hFont);
390 SelectObject(hdc, hFontOld);
391
392 /* Fill hbmMono with black */
393 SelectObject(hdc, hbmMono);
394 PatBlt(hdc, 0, 0, cxIcon, cyIcon, BLACKNESS);
395 SelectObject(hdc, hBmpOld);
396
397 /* Create an icon from hbmColor and hbmMono */
400 IconInfo.hbmColor = hbmColor;
401 IconInfo.hbmMask = hbmMono;
403
404 /* Clean up */
406 DeleteObject(hbmMono);
407 DeleteObject(hbmColor);
408 DeleteDC(hdc);
409
410 return hIcon;
411}
412
413static VOID
415{
416 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
417 TCHAR szKLID[CCH_LAYOUT_ID + 1], szName[MAX_PATH], szImeFile[80];
418
419 GetKLIDFromLayoutNum(g_iKL, szKLID, _countof(szKLID));
421 GetImeFile(szImeFile, _countof(szImeFile), szKLID);
422
424 tnid.hIcon = CreateTrayIcon(szKLID, szImeFile);
426
428
429 if (g_hTrayIcon)
431 g_hTrayIcon = tnid.hIcon;
432}
433
434static VOID
436{
437 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1 };
439
440 if (g_hTrayIcon)
441 {
444 }
445}
446
447static VOID
449{
450 NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
451 TCHAR szImeFile[80];
452
453 GetImeFile(szImeFile, _countof(szImeFile), szKLID);
454
456 tnid.hIcon = CreateTrayIcon(szKLID, szImeFile);
458
460
461 if (g_hTrayIcon)
463 g_hTrayIcon = tnid.hIcon;
464}
465
466static BOOL CALLBACK
468{
469 PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET, lParam);
470 return TRUE;
471}
472
473static VOID
474ActivateLayout(HWND hwnd, UINT iKL, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
475{
476 HKL hKl;
477 TCHAR szKLID[CCH_LAYOUT_ID + 1], szLangName[MAX_PATH];
479
480 if (iKL >= g_cKLs) /* Invalid */
481 return;
482
483 GetKLIDFromLayoutNum(iKL, szKLID, _countof(szKLID));
484 LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
485
486 /* Switch to the new keyboard layout */
487 GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, _countof(szLangName));
488 UpdateTrayIcon(hwnd, szKLID, szLangName);
489
490 if (hwndTarget && !bNoActivate)
491 SetForegroundWindow(hwndTarget);
492
493 hKl = LoadKeyboardLayout(szKLID, KLF_ACTIVATE);
494 if (hKl)
496
497 /* Post WM_INPUTLANGCHANGEREQUEST */
498 if (hwndTarget)
499 {
500 PostMessage(hwndTarget, WM_INPUTLANGCHANGEREQUEST,
501 INPUTLANGCHANGE_SYSCHARSET, (LPARAM)hKl);
502 }
503 else
504 {
506 }
507
508 g_iKL = iKL;
509}
510
511static HMENU
513{
514 HMENU hMenu = CreatePopupMenu();
515 TCHAR szName[MAX_PATH], szKLID[CCH_LAYOUT_ID + 1], szImeFile[80];
516 HICON hIcon;
517 MENUITEMINFO mii = { sizeof(mii) };
518 UINT iKL;
519
520 for (iKL = 0; iKL < g_cKLs; ++iKL)
521 {
522 GetKLIDFromHKL(g_ahKLs[iKL], szKLID, _countof(szKLID));
523 GetImeFile(szImeFile, _countof(szImeFile), szKLID);
524
525 if (!GetLayoutName(iKL, szName, _countof(szName)))
526 continue;
527
528 mii.fMask = MIIM_ID | MIIM_STRING;
529 mii.wID = ID_LANG_BASE + iKL;
530 mii.dwTypeData = szName;
531
532 hIcon = CreateTrayIcon(szKLID, szImeFile);
533 if (hIcon)
534 {
535 mii.hbmpItem = BitmapFromIcon(hIcon);
536 if (mii.hbmpItem)
537 mii.fMask |= MIIM_BITMAP;
538 }
539
540 InsertMenuItem(hMenu, -1, TRUE, &mii);
542 }
543
545
546 return hMenu;
547}
548
549static BOOL
551{
552 g_hHookDLL = LoadLibrary(_T("indicdll.dll"));
553 if (!g_hHookDLL)
554 {
555 return FALSE;
556 }
557
558#define IHOOK_SET 1
560
562 {
563 ERR("SetHooks failed\n");
564 return FALSE;
565 }
566
567 TRACE("SetHooks OK\n");
568 return TRUE;
569}
570
571static VOID
573{
575 {
578 }
579
580 if (g_hHookDLL)
581 {
584 }
585
586 TRACE("DeleteHooks OK\n");
587}
588
590{
591 UINT iKL;
592
593 for (iKL = 0; iKL < g_cKLs; ++iKL)
594 {
595 if (g_ahKLs[iKL] == hKL)
596 return iKL;
597 }
598
599 return 0;
600}
601
602UINT
604{
605 TCHAR szKLID[MAX_PATH], szLangName[MAX_PATH];
607
608 GetKLIDFromHKL(hKL, szKLID, _countof(szKLID));
609 LangID = (LANGID)_tcstoul(szKLID, NULL, 16);
610 GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, _countof(szLangName));
611 UpdateTrayIcon(hwnd, szKLID, szLangName);
612 g_iKL = GetLayoutNum(hKL);
613
614 return 0;
615}
616
617HWND
619{
620 HWND hwndTarget = (hwndFore ? hwndFore : GetForegroundWindow());
621 if (IsWndClassName(hwndTarget, szKbSwitcherName))
622 hwndTarget = g_hwndLastActive;
623 return hwndTarget;
624}
625
626UINT
628{
629 DWORD dwThreadID = GetWindowThreadProcessId(GetTargetWindow(hwndFore), NULL);
630 HKL hKL = GetKeyboardLayout(dwThreadID);
632
633 return 0;
634}
635
637{
638 hwndFore = GetAncestor(hwndFore, GA_ROOT);
639
640 if (!IsWindowVisible(hwndFore))
641 return FALSE;
642
643 if (IsWndClassName(hwndFore, szKbSwitcherName) ||
644 IsWndClassName(hwndFore, TEXT("Shell_TrayWnd")))
645 {
646 return FALSE; /* Special window */
647 }
648
649 g_hwndLastActive = hwndFore;
650 return TRUE;
651}
652
653// WM_CREATE
654static INT
656{
657 if (!SetHooks())
658 {
659 MessageBox(NULL, TEXT("SetHooks failed."), NULL, MB_ICONERROR);
660 return -1; /* Failed */
661 }
662
664
667
670
671 return 0; /* Success */
672}
673
674// WM_DESTROY
675static void
677{
679 DeleteHooks();
682}
683
684// WM_TIMER
685static void
687{
688 if (nTimerID == TIMER_ID_LANG_CHANGED_DELAYED)
689 {
690 KillTimer(hwnd, nTimerID);
691 HKL hKL = GetActiveKL();
692 UpdateLayoutList(hKL);
694 }
695}
696
697// WM_NOTIFYICONMSG
698static void
700{
701 if (uMouseMsg != WM_LBUTTONUP && uMouseMsg != WM_RBUTTONUP && uMouseMsg != WM_CONTEXTMENU)
702 return;
703
705
706 POINT pt;
708
710
711 INT nID;
712 if (uMouseMsg == WM_LBUTTONUP)
713 {
714 /* Rebuild the left popup menu on every click to take care of keyboard layout changes */
715 HMENU hPopupMenu = BuildLeftPopupMenu();
717 pt.x, pt.y, hwnd, NULL);
718 DestroyMenu(hPopupMenu);
719 }
720 else /* WM_RBUTTONUP or WM_CONTEXTMENU */
721 {
723 HMENU hSubMenu = GetSubMenu(hPopupMenu, 0);
725 pt.x, pt.y, hwnd, NULL);
726 DestroyMenu(hPopupMenu);
727 }
728
729 PostMessage(hwnd, WM_NULL, 0, 0);
730
731 if (nID)
732 PostMessage(hwnd, WM_COMMAND, nID, 0);
733}
734
735// WM_COMMAND
736static void
738{
739 switch (nID)
740 {
741 case ID_EXIT:
742 PostMessage(hwnd, WM_CLOSE, 0, 0);
743 break;
744
745 case ID_PREFERENCES:
746 {
748 TEXT("control.exe"), TEXT("input.dll"),
750 if (ret <= 32)
751 MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_ICONERROR);
752 break;
753 }
754
755 default:
756 {
757 if (nID >= ID_LANG_BASE)
758 {
760 {
762 }
764 }
765 break;
766 }
767 }
768}
769
770// WM_LANG_CHANGED
771static LRESULT
773{
774 TRACE("WM_LANG_CHANGED: hwndTarget:%p, hKL:%p\n", hwndTarget, hKL);
775 /* Delayed action */
778 return 0;
779}
780
781// WM_WINDOW_ACTIVATE
782static LRESULT
784{
785 TRACE("WM_WINDOW_ACTIVATE: hwndTarget:%p, lParam:%p\n", hwndTarget, lParam);
786 HWND hwndFore = hwndTarget ? hwndTarget : GetForegroundWindow();
787 if (RememberLastActive(hwnd, hwndFore))
788 return UpdateLanguageDisplayCurrent(hwnd, hwndFore);
789 return 0;
790}
791
792// WM_SETTINGCHANGE
793static void
795{
796 if (wParam == SPI_SETNONCLIENTMETRICS)
798}
799
800static LRESULT
802{
803 if (uMsg == g_uTaskbarRestartMsg)
804 {
807 return 0;
808 }
809
810 if (uMsg == g_uShellHookMessage)
811 {
812 TRACE("g_uShellHookMessage: wParam:%p, lParam:%p\n", wParam, lParam);
813 if (wParam == HSHELL_LANGUAGE)
815 else if (wParam == HSHELL_WINDOWACTIVATED || wParam == HSHELL_RUDEAPPACTIVATED)
817 return 0;
818 }
819
820 return DefWindowProc(hwnd, uMsg, wParam, lParam);
821}
822
825{
826 switch (uMsg)
827 {
828 case WM_CREATE:
829 return KbSwitch_OnCreate(hwnd);
830
831 case WM_TIMER:
833 break;
834
835 case WM_LANG_CHANGED: /* Comes from indicdll.dll and this module */
837
838 case WM_WINDOW_ACTIVATE: /* Comes from indicdll.dll and this module */
840
841 case WM_NOTIFYICONMSG:
843 break;
844
845 case WM_COMMAND:
847 break;
848
849 case WM_SETTINGCHANGE:
851 break;
852
853 case WM_DESTROY:
855 break;
856
857 default:
858 return KbSwitch_OnDefault(hwnd, uMsg, wParam, lParam);
859 }
860
861 return 0;
862}
863
865_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
866{
868 MSG msg;
870 HWND hwnd;
871
872 switch (GetUserDefaultUILanguage())
873 {
875 TRACE("LAYOUT_RTL\n");
877 break;
878 default:
879 break;
880 }
881
883 if (!hMutex)
884 {
885 ERR("!hMutex\n");
886 return 1;
887 }
888
890 {
891 ERR("Another instance is already running\n");
893 return 1;
894 }
895
897
898 ZeroMemory(&WndClass, sizeof(WndClass));
899 WndClass.lpfnWndProc = WndProc;
900 WndClass.hInstance = hInstance;
901 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
902 WndClass.lpszClassName = szKbSwitcherName;
903 if (!RegisterClass(&WndClass))
904 {
906 return 1;
907 }
908
912 {
913 ERR("RegisterShellHookWindow failed\n");
916 return 1;
917 }
918
919 while (GetMessage(&msg, NULL, 0, 0))
920 {
923 }
924
926 return 0;
927}
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ID_EXIT
Definition: resource.h:10
#define ID_PREFERENCES
Definition: resource.h:11
#define ID_LANG_BASE
Definition: resource.h:12
#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
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#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
LANGID WINAPI GetUserDefaultUILanguage(void)
Definition: locale.c:1375
#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
#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:2306
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define TEXT(s)
Definition: k32.h:28
static void KbSwitch_OnCommand(HWND hwnd, UINT nID)
Definition: kbswitch.c:737
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: kbswitch.c:467
#define IHOOK_SET
#define TIMER_ID_LANG_CHANGED_DELAYED
Definition: kbswitch.c:34
static VOID LoadSpecialIds(VOID)
Definition: kbswitch.c:61
static VOID ActivateLayout(HWND hwnd, UINT iKL, HWND hwndTarget OPTIONAL, BOOL bNoActivate)
Definition: kbswitch.c:474
static HBITMAP BitmapFromIcon(HICON hIcon)
Definition: kbswitch.c:295
static BOOL GetLayoutName(UINT iKL, LPTSTR szName, SIZE_T NameLength)
Definition: kbswitch.c:193
struct tagLOAD_ICON LOAD_ICON
static VOID UpdateTrayIcon(HWND hwnd, LPTSTR szKLID, LPTSTR szName)
Definition: kbswitch.c:448
static VOID GetKLIDFromLayoutNum(UINT iKL, LPTSTR szKLID, SIZE_T KLIDLength)
Definition: kbswitch.c:176
UINT g_cKLs
Definition: kbswitch.c:44
INT g_cSpecialIds
Definition: kbswitch.c:59
static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
Definition: kbswitch.c:283
static LRESULT KbSwitch_OnWindowActivate(HWND hwnd, HWND hwndTarget OPTIONAL, LPARAM lParam OPTIONAL)
Definition: kbswitch.c:783
static HKL GetActiveKL(VOID)
Definition: kbswitch.c:142
UINT g_uShellHookMessage
Definition: kbswitch.c:47
static VOID GetKLIDFromHKL(HKL hKL, LPTSTR szKLID, SIZE_T KLIDLength)
Definition: kbswitch.c:114
static LRESULT KbSwitch_OnDefault(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:801
SPECIAL_ID g_SpecialIds[MAX_SPECIAL_IDS]
Definition: kbswitch.c:58
static VOID DeleteHooks(VOID)
Definition: kbswitch.c:572
static UINT GetLayoutNum(HKL hKL)
Definition: kbswitch.c:589
static void KbSwitch_OnSettingChange(HWND hwnd, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:794
#define TIMER_LANG_CHANGED_DELAY
Definition: kbswitch.c:35
static HICON CreateTrayIcon(LPTSTR szKLID, LPCTSTR szImeFile OPTIONAL)
Definition: kbswitch.c:317
static HMENU BuildLeftPopupMenu(VOID)
Definition: kbswitch.c:512
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: kbswitch.c:824
HKL g_ahKLs[64]
Definition: kbswitch.c:45
#define MAX_SPECIAL_IDS
Definition: kbswitch.c:56
static BOOL RememberLastActive(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:636
static VOID UpdateLayoutList(HKL hKL OPTIONAL)
Definition: kbswitch.c:150
static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LPARAM lParam)
Definition: kbswitch.c:268
static LRESULT KbSwitch_OnLangChanged(HWND hwnd, HWND hwndTarget OPTIONAL, HKL hKL OPTIONAL)
Definition: kbswitch.c:772
static void KbSwitch_OnNotifyIconMsg(HWND hwnd, UINT uMouseMsg)
Definition: kbswitch.c:699
HWND GetTargetWindow(HWND hwndFore OPTIONAL)
Definition: kbswitch.c:618
static void KbSwitch_OnTimer(HWND hwnd, UINT_PTR nTimerID)
Definition: kbswitch.c:686
HWND g_hwndLastActive
Definition: kbswitch.c:42
UINT UpdateLanguageDisplay(HWND hwnd, HKL hKL)
Definition: kbswitch.c:603
static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szKLID)
Definition: kbswitch.c:229
HICON g_hTrayIcon
Definition: kbswitch.c:41
UINT UpdateLanguageDisplayCurrent(HWND hwnd, HWND hwndFore)
Definition: kbswitch.c:627
HMODULE g_hHookDLL
Definition: kbswitch.c:40
static BOOL SetHooks(VOID)
Definition: kbswitch.c:550
#define WM_NOTIFYICONMSG
Definition: kbswitch.c:32
struct tagLOAD_ICON * PLOAD_ICON
static BOOL GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
Definition: kbswitch.c:182
FN_KbSwitchSetHooks KbSwitchSetHooks
Definition: kbswitch.c:37
static VOID AddTrayIcon(HWND hwnd)
Definition: kbswitch.c:414
static HKL GetHKLFromLayoutNum(UINT iKL)
Definition: kbswitch.c:170
static INT KbSwitch_OnCreate(HWND hwnd)
Definition: kbswitch.c:655
UINT g_uTaskbarRestartMsg
Definition: kbswitch.c:46
static void KbSwitch_OnDestroy(HWND hwnd)
Definition: kbswitch.c:676
HINSTANCE g_hInst
Definition: kbswitch.c:39
UINT g_iKL
Definition: kbswitch.c:43
static VOID DeleteTrayIcon(HWND hwnd)
Definition: kbswitch.c:435
struct tagSPECIAL_ID SPECIAL_ID
struct tagSPECIAL_ID * PSPECIAL_ID
#define CCH_LAYOUT_ID
Definition: kbswitch.h:17
const TCHAR szKbSwitcherName[]
Definition: kbswitch.h:25
#define WM_WINDOW_ACTIVATE
Definition: kbswitch.h:21
static BOOL IsWndClassName(_In_opt_ HWND hwndTarget, PCTSTR pszName)
Definition: kbswitch.h:28
#define WM_LANG_CHANGED
Definition: kbswitch.h:20
BOOL(APIENTRY * FN_KbSwitchSetHooks)(BOOL bDoHook)
Definition: kbswitch.h:23
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:125
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
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 WM_CONTEXTMENU
Definition: richedit.h:64
#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:732
#define NIM_DELETE
Definition: shellapi.h:96
#define NIM_MODIFY
Definition: shellapi.h:95
#define NIF_ICON
Definition: shellapi.h:106
#define NIF_MESSAGE
Definition: shellapi.h:105
#define NIM_ADD
Definition: shellapi.h:94
#define Shell_NotifyIcon
Definition: shellapi.h:730
#define NIF_TIP
Definition: shellapi.h:107
HRESULT hr
Definition: shlfolder.c:183
#define SHLoadRegUIString
#define _countof(array)
Definition: sndvol32.h:70
#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 yHotspot
Definition: winuser.h:3201
BOOL fIcon
Definition: winuser.h:3199
DWORD xHotspot
Definition: winuser.h:3200
HBITMAP hbmColor
Definition: winuser.h:3203
HBITMAP hbmMask
Definition: winuser.h:3202
UINT uCallbackMessage
Definition: shellapi.h:231
CHAR szTip[128]
Definition: shellapi.h:237
HICON hIcon
Definition: kbswitch.c:264
LPSTR dwTypeData
Definition: winuser.h:3327
TCHAR szKLID[CCH_LAYOUT_ID+1]
Definition: kbswitch.c:53
DWORD dwLayoutId
Definition: kbswitch.c:51
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
#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:1753
#define GetSystemDirectory
Definition: winbase.h:3883
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LoadLibraryEx
Definition: winbase.h:3904
#define LoadLibrary
Definition: winbase.h:3903
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:375
#define CreateMutex
Definition: winbase.h:3797
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
#define EnumResourceNames
Definition: winbase.h:3813
_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:1289
#define LOCALE_SLANGUAGE
Definition: winnls.h:31
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
#define LOCALE_SABBREVLANGNAME
Definition: winnls.h:34
#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)
#define HSHELL_RUDEAPPACTIVATED
Definition: winuser.h:1292
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:1640
#define MIIM_STRING
Definition: winuser.h:738
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2943
#define GA_ROOT
Definition: winuser.h:2865
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 TPM_RIGHTBUTTON
Definition: winuser.h:2399
#define WM_CREATE
Definition: winuser.h:1627
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#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:1759
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:1799
#define InsertMenuItem
Definition: winuser.h:5889
#define SM_CYSMICON
Definition: winuser.h:1024
#define MF_CHECKED
Definition: winuser.h:132
#define LoadKeyboardLayout
Definition: winuser.h:5901
#define SPI_GETICONTITLELOGFONT
Definition: winuser.h:1391
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define DrawText
Definition: winuser.h:5856
#define CreateWindow
Definition: winuser.h:5839
#define HWND_DESKTOP
Definition: winuser.h:1220
#define MB_ICONERROR
Definition: winuser.h:798
#define WM_SETTINGCHANGE
Definition: winuser.h:1648
#define GetMessage
Definition: winuser.h:5875
#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:5925
UINT WINAPI GetKeyboardLayoutList(_In_ int nBuff, _Out_writes_to_opt_(nBuff, return) HKL FAR *lpList)
#define MIIM_BITMAP
Definition: winuser.h:739
#define WM_TIMER
Definition: winuser.h:1761
#define TPM_LEFTALIGN
Definition: winuser.h:2396
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:5898
#define WM_NULL
Definition: winuser.h:1626
#define LoadCursor
Definition: winuser.h:5897
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:938
HDC WINAPI GetDC(_In_opt_ HWND)
#define TPM_LEFTBUTTON
Definition: winuser.h:2398
#define LoadMenu
Definition: winuser.h:5902
#define WM_LBUTTONUP
Definition: winuser.h:1796
#define DT_VCENTER
Definition: winuser.h:543
#define PostMessage
Definition: winuser.h:5917
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
#define LoadImage
Definition: winuser.h:5900
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MessageBox
Definition: winuser.h:5907
#define LR_DEFAULTCOLOR
Definition: winuser.h:1098
#define RegisterClass
Definition: winuser.h:5921
#define WM_DESTROY
Definition: winuser.h:1628
#define DispatchMessage
Definition: winuser.h:5850
HKL WINAPI ActivateKeyboardLayout(_In_ HKL, _In_ UINT)
#define TPM_RETURNCMD
Definition: winuser.h:2406
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SystemParametersInfo
Definition: winuser.h:5943
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