3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS user32.dll
21 * FILE: win32ss/user/user32/windows/input.c
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * 09-05-2001 CSH Created
32 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
34 typedef struct tagIMEHOTKEYENTRY
40 } IMEHOTKEYENTRY
, *PIMEHOTKEYENTRY
;
43 IMEHOTKEYENTRY DefaultHotKeyTableJ
[] =
45 { IME_JHOTKEY_CLOSE_OPEN
, VK_KANJI
, MOD_IGNORE_ALL_MODIFIER
, NULL
},
48 // Chinese Traditional
49 IMEHOTKEYENTRY DefaultHotKeyTableT
[] =
51 { IME_THOTKEY_IME_NONIME_TOGGLE
, VK_SPACE
, MOD_LEFT
| MOD_RIGHT
| MOD_CONTROL
, NULL
},
52 { IME_THOTKEY_SHAPE_TOGGLE
, VK_SPACE
, MOD_LEFT
| MOD_RIGHT
| MOD_SHIFT
, NULL
},
56 IMEHOTKEYENTRY DefaultHotKeyTableC
[] =
58 { IME_CHOTKEY_IME_NONIME_TOGGLE
, VK_SPACE
, MOD_LEFT
| MOD_RIGHT
| MOD_CONTROL
, NULL
},
59 { IME_CHOTKEY_SHAPE_TOGGLE
, VK_SPACE
, MOD_LEFT
| MOD_RIGHT
| MOD_SHIFT
, NULL
},
63 #define FE_JAPANESE (1 << 0)
64 #define FE_CHINESE_TRADITIONAL (1 << 1)
65 #define FE_CHINESE_SIMPLIFIED (1 << 2)
66 #define FE_KOREAN (1 << 3)
68 // Sets the far-east flags
69 // Win: SetFeKeyboardFlags
70 VOID FASTCALL
IntSetFeKeyboardFlags(LANGID LangID
, PBYTE pbFlags
)
74 case MAKELANGID(LANG_JAPANESE
, SUBLANG_DEFAULT
):
75 *pbFlags
|= FE_JAPANESE
;
78 case MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_TRADITIONAL
):
79 case MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_HONGKONG
):
80 *pbFlags
|= FE_CHINESE_TRADITIONAL
;
83 case MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_SIMPLIFIED
):
84 case MAKELANGID(LANG_CHINESE
, SUBLANG_CHINESE_SINGAPORE
):
85 *pbFlags
|= FE_CHINESE_SIMPLIFIED
;
88 case MAKELANGID(LANG_KOREAN
, SUBLANG_KOREAN
):
89 *pbFlags
|= FE_KOREAN
;
97 DWORD FASTCALL
CliReadRegistryValue(HANDLE hKey
, LPCWSTR pszName
)
99 DWORD dwValue
, cbValue
;
102 cbValue
= sizeof(dwValue
);
103 error
= RegQueryValueExW(hKey
, pszName
, NULL
, NULL
, (LPBYTE
)&dwValue
, &cbValue
);
104 if (error
!= ERROR_SUCCESS
|| cbValue
< sizeof(DWORD
))
111 CliImmSetHotKeyWorker(DWORD dwHotKeyId
, UINT uModifiers
, UINT uVirtualKey
, HKL hKL
, DWORD dwAction
)
113 if (dwAction
== SETIMEHOTKEY_ADD
)
115 if (IME_HOTKEY_DSWITCH_FIRST
<= dwHotKeyId
&& dwHotKeyId
<= IME_HOTKEY_DSWITCH_LAST
)
125 if (IME_KHOTKEY_SHAPE_TOGGLE
<= dwHotKeyId
&&
126 dwHotKeyId
< IME_THOTKEY_IME_NONIME_TOGGLE
)
128 // The Korean cannot set the IME hotkeys
133 #define MOD_ALL_MODS (MOD_ALT | MOD_CONTROL | MOD_SHIFT | MOD_WIN)
134 if ((uModifiers
& MOD_ALL_MODS
) && !(uModifiers
& (MOD_LEFT
| MOD_RIGHT
)))
139 return NtUserSetImeHotKey(dwHotKeyId
, uModifiers
, uVirtualKey
, hKL
, dwAction
);
142 SetLastError(ERROR_INVALID_PARAMETER
);
147 /* Win: LoadPreloadKeyboardLayouts */
148 VOID
IntLoadPreloadKeyboardLayouts(VOID
)
150 UINT nNumber
, uFlags
;
151 DWORD cbValue
, dwType
;
152 WCHAR szNumber
[32], szValue
[KL_NAMELENGTH
];
155 HKL hKL
, hDefaultKL
= NULL
;
157 if (RegOpenKeyW(HKEY_CURRENT_USER
,
158 L
"Keyboard Layout\\Preload",
159 &hPreloadKey
) != ERROR_SUCCESS
)
164 for (nNumber
= 1; nNumber
<= 1000; ++nNumber
)
166 _ultow(nNumber
, szNumber
, 10);
168 cbValue
= sizeof(szValue
);
169 if (RegQueryValueExW(hPreloadKey
,
174 &cbValue
) != ERROR_SUCCESS
)
179 if (dwType
!= REG_SZ
)
182 if (nNumber
== 1) /* The first entry is for default keyboard layout */
183 uFlags
= KLF_SUBSTITUTE_OK
| KLF_ACTIVATE
| KLF_RESET
;
185 uFlags
= KLF_SUBSTITUTE_OK
| KLF_NOTELLSHELL
| KLF_REPLACELANG
;
187 hKL
= LoadKeyboardLayoutW(szValue
, uFlags
);
191 if (nNumber
== 1) /* The first entry */
196 RegCloseKey(hPreloadKey
);
199 SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG
, 0, &hDefaultKL
, 0);
203 /* Fallback to English (US) */
204 LoadKeyboardLayoutW(L
"00000409", KLF_SUBSTITUTE_OK
| KLF_ACTIVATE
| KLF_RESET
);
210 CliSaveImeHotKey(DWORD dwID
, UINT uModifiers
, UINT uVirtualKey
, HKL hKL
, BOOL bDelete
)
212 WCHAR szName
[MAX_PATH
];
214 HKEY hControlPanel
= NULL
, hInputMethod
= NULL
, hHotKeys
= NULL
, hKey
= NULL
;
215 BOOL ret
= FALSE
, bRevertOnFailure
= FALSE
;
219 StringCchPrintfW(szName
, _countof(szName
),
220 L
"Control Panel\\Input Method\\Hot Keys\\%08lX", dwID
);
221 error
= RegDeleteKeyW(HKEY_CURRENT_USER
, szName
);
222 return (error
== ERROR_SUCCESS
);
225 // Open "Control Panel"
226 error
= RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel", 0, NULL
, 0, KEY_ALL_ACCESS
,
227 NULL
, &hControlPanel
, NULL
);
228 if (error
== ERROR_SUCCESS
)
230 // Open "Input Method"
231 error
= RegCreateKeyExW(hControlPanel
, L
"Input Method", 0, NULL
, 0, KEY_ALL_ACCESS
,
232 NULL
, &hInputMethod
, NULL
);
233 if (error
== ERROR_SUCCESS
)
236 error
= RegCreateKeyExW(hInputMethod
, L
"Hot Keys", 0, NULL
, 0, KEY_ALL_ACCESS
,
237 NULL
, &hHotKeys
, NULL
);
238 if (error
== ERROR_SUCCESS
)
241 StringCchPrintfW(szName
, _countof(szName
), L
"%08lX", dwID
);
242 error
= RegCreateKeyExW(hHotKeys
, szName
, 0, NULL
, 0, KEY_ALL_ACCESS
,
244 if (error
== ERROR_SUCCESS
)
246 bRevertOnFailure
= TRUE
;
249 error
= RegSetValueExW(hKey
, L
"Virtual Key", 0, REG_BINARY
,
250 (LPBYTE
)&uVirtualKey
, sizeof(uVirtualKey
));
251 if (error
== ERROR_SUCCESS
)
253 // Set "Key Modifiers"
254 error
= RegSetValueExW(hKey
, L
"Key Modifiers", 0, REG_BINARY
,
255 (LPBYTE
)&uModifiers
, sizeof(uModifiers
));
256 if (error
== ERROR_SUCCESS
)
259 error
= RegSetValueExW(hKey
, L
"Target IME", 0, REG_BINARY
,
260 (LPBYTE
)&hKL
, sizeof(hKL
));
261 if (error
== ERROR_SUCCESS
)
265 bRevertOnFailure
= FALSE
;
271 RegCloseKey(hHotKeys
);
273 RegCloseKey(hInputMethod
);
275 RegCloseKey(hControlPanel
);
278 if (bRevertOnFailure
)
279 CliSaveImeHotKey(dwID
, uVirtualKey
, uModifiers
, hKL
, TRUE
);
286 * Same as imm32!ImmSetHotKey.
288 BOOL WINAPI
CliImmSetHotKey(DWORD dwID
, UINT uModifiers
, UINT uVirtualKey
, HKL hKL
)
292 if (uVirtualKey
== 0) // Delete?
294 ret
= CliSaveImeHotKey(dwID
, uModifiers
, uVirtualKey
, hKL
, TRUE
);
296 CliImmSetHotKeyWorker(dwID
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_DELETE
);
301 ret
= CliImmSetHotKeyWorker(dwID
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_ADD
);
304 ret
= CliSaveImeHotKey(dwID
, uModifiers
, uVirtualKey
, hKL
, FALSE
);
305 if (!ret
) // Failure?
306 CliImmSetHotKeyWorker(dwID
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_DELETE
);
312 BOOL FASTCALL
CliSetSingleHotKey(LPCWSTR pszSubKey
, HANDLE hKey
)
316 DWORD dwHotKeyId
= 0;
317 UINT uModifiers
= 0, uVirtualKey
= 0;
319 UNICODE_STRING ustrName
;
321 error
= RegOpenKeyExW(hKey
, pszSubKey
, 0, KEY_READ
, &hSubKey
);
322 if (error
!= ERROR_SUCCESS
)
325 RtlInitUnicodeString(&ustrName
, pszSubKey
);
326 RtlUnicodeStringToInteger(&ustrName
, 16, &dwHotKeyId
);
328 uModifiers
= CliReadRegistryValue(hSubKey
, L
"Key Modifiers");
329 hKL
= (HKL
)(ULONG_PTR
)CliReadRegistryValue(hSubKey
, L
"Target IME");
330 uVirtualKey
= CliReadRegistryValue(hSubKey
, L
"Virtual Key");
332 RegCloseKey(hSubKey
);
334 return CliImmSetHotKeyWorker(dwHotKeyId
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_ADD
);
337 BOOL FASTCALL
CliGetImeHotKeysFromRegistry(VOID
)
342 DWORD dwIndex
, cchKeyName
;
345 error
= RegOpenKeyExW(HKEY_CURRENT_USER
,
346 L
"Control Panel\\Input Method\\Hot Keys",
350 if (error
!= ERROR_SUCCESS
)
353 for (dwIndex
= 0; dwIndex
< 1000; ++dwIndex
)
355 cchKeyName
= _countof(szKeyName
);
356 error
= RegEnumKeyExW(hKey
, dwIndex
, szKeyName
, &cchKeyName
, NULL
, NULL
, NULL
, NULL
);
357 if (error
!= ERROR_SUCCESS
)
360 szKeyName
[_countof(szKeyName
) - 1] = 0; /* Avoid stack overrun */
362 if (CliSetSingleHotKey(szKeyName
, hKey
))
370 VOID APIENTRY
CliGetPreloadKeyboardLayouts(PBYTE pbFlags
)
372 WCHAR szValueName
[33], szValue
[16];
373 UNICODE_STRING ustrValue
;
374 DWORD dwKL
, cbValue
, dwType
;
379 error
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Preload", 0, KEY_READ
, &hKey
);
380 if (error
!= ERROR_SUCCESS
)
383 for (iNumber
= 1; iNumber
< 1000; ++iNumber
)
385 _ultow(iNumber
, szValueName
, 10);
387 cbValue
= sizeof(szValue
);
388 error
= RegQueryValueExW(hKey
, szValueName
, NULL
, &dwType
, (LPBYTE
)szValue
, &cbValue
);
389 if (error
!= ERROR_SUCCESS
)
392 if (dwType
!= REG_SZ
)
395 szValue
[_countof(szValue
) - 1] = 0; /* Avoid stack overrun */
397 RtlInitUnicodeString(&ustrValue
, szValue
);
398 RtlUnicodeStringToInteger(&ustrValue
, 16, &dwKL
);
400 IntSetFeKeyboardFlags(LOWORD(dwKL
), pbFlags
);
406 VOID APIENTRY
CliSetDefaultImeHotKeys(PIMEHOTKEYENTRY pEntries
, UINT nCount
, BOOL bCheck
)
408 UINT uVirtualKey
, uModifiers
;
413 if (!bCheck
|| !NtUserGetImeHotKey(pEntries
->dwHotKeyId
, &uModifiers
, &uVirtualKey
, &hKL
))
415 CliImmSetHotKeyWorker(pEntries
->dwHotKeyId
,
416 pEntries
->uModifiers
,
417 pEntries
->uVirtualKey
,
425 VOID APIENTRY
CliImmInitializeHotKeys(DWORD dwAction
, HKL hKL
)
434 NtUserSetImeHotKey(0, 0, 0, NULL
, SETIMEHOTKEY_INITIALIZE
);
436 bCheck
= CliGetImeHotKeysFromRegistry();
438 if (dwAction
== SETIMEHOTKEY_INITIALIZE
)
440 LangID
= LANGIDFROMLCID(GetUserDefaultLCID());
441 IntSetFeKeyboardFlags(LangID
, &bFlags
);
443 CliGetPreloadKeyboardLayouts(&bFlags
);
447 nCount
= NtUserGetKeyboardLayoutList(0, NULL
);
451 pList
= RtlAllocateHeap(RtlGetProcessHeap(), 0, nCount
* sizeof(HKL
));
455 NtUserGetKeyboardLayoutList(nCount
, pList
);
457 for (iIndex
= 0; iIndex
< nCount
; ++iIndex
)
459 LangID
= LOWORD(pList
[iIndex
]);
460 IntSetFeKeyboardFlags(LangID
, &bFlags
);
463 RtlFreeHeap(RtlGetProcessHeap(), 0, pList
);
466 if (bFlags
& FE_JAPANESE
)
467 CliSetDefaultImeHotKeys(DefaultHotKeyTableJ
, _countof(DefaultHotKeyTableJ
), bCheck
);
469 if (bFlags
& FE_CHINESE_TRADITIONAL
)
470 CliSetDefaultImeHotKeys(DefaultHotKeyTableT
, _countof(DefaultHotKeyTableT
), bCheck
);
472 if (bFlags
& FE_CHINESE_SIMPLIFIED
)
473 CliSetDefaultImeHotKeys(DefaultHotKeyTableC
, _countof(DefaultHotKeyTableC
), bCheck
);
485 return NtUserDragDetect(hWnd
, pt
);
490 ULONG dx
= GetSystemMetrics(SM_CXDRAG
);
491 ULONG dy
= GetSystemMetrics(SM_CYDRAG
);
493 rect
.left
= pt
.x
- dx
;
494 rect
.right
= pt
.x
+ dx
;
495 rect
.top
= pt
.y
- dy
;
496 rect
.bottom
= pt
.y
+ dy
;
503 PeekMessageW(&msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_REMOVE
) ||
504 PeekMessageW(&msg
, 0, WM_KEYFIRST
, WM_KEYLAST
, PM_REMOVE
)
507 if (msg
.message
== WM_LBUTTONUP
)
512 if (msg
.message
== WM_MOUSEMOVE
)
514 tmp
.x
= LOWORD(msg
.lParam
);
515 tmp
.y
= HIWORD(msg
.lParam
);
516 if (!PtInRect(&rect
, tmp
))
522 if (msg
.message
== WM_KEYDOWN
)
524 if (msg
.wParam
== VK_ESCAPE
)
541 EnableWindow(HWND hWnd
, BOOL bEnable
)
543 return NtUserxEnableWindow(hWnd
, bEnable
);
552 GetAsyncKeyState(int vKey
)
554 if (vKey
< 0 || vKey
> 256)
556 return (SHORT
)NtUserGetAsyncKeyState((DWORD
)vKey
);
564 GetKeyboardLayout(DWORD idThread
)
566 return NtUserxGetKeyboardLayout(idThread
);
584 GetKeyNameTextA(LONG lParam
,
591 BOOL defChar
= FALSE
;
593 pwszBuf
= HeapAlloc(GetProcessHeap(), 0, nSize
* sizeof(WCHAR
));
597 cchBuf
= NtUserGetKeyNameText(lParam
, pwszBuf
, nSize
);
599 iRet
= WideCharToMultiByte(CP_ACP
, 0,
601 lpString
, nSize
, ".", &defChar
); // FIXME: do we need defChar?
603 HeapFree(GetProcessHeap(), 0, pwszBuf
);
612 GetKeyNameTextW(LONG lParam
,
616 return NtUserGetKeyNameText(lParam
, lpString
, nSize
);
625 GetKeyState(int nVirtKey
)
627 return (SHORT
)NtUserGetKeyState((DWORD
)nVirtKey
);
634 GetKeyboardLayoutNameA(LPSTR pwszKLID
)
636 WCHAR buf
[KL_NAMELENGTH
];
638 if (!GetKeyboardLayoutNameW(buf
))
641 if (!WideCharToMultiByte(CP_ACP
, 0, buf
, -1, pwszKLID
, KL_NAMELENGTH
, NULL
, NULL
))
651 GetKeyboardLayoutNameW(LPWSTR pwszKLID
)
655 RtlInitEmptyUnicodeString(&Name
,
657 KL_NAMELENGTH
* sizeof(WCHAR
));
659 return NtUserGetKeyboardLayoutName(&Name
);
666 GetKeyboardType(int nTypeFlag
)
668 return NtUserxGetKeyboardType(nTypeFlag
);
675 GetLastInputInfo(PLASTINPUTINFO plii
)
679 if (plii
->cbSize
!= sizeof (*plii
))
681 SetLastError(ERROR_INVALID_PARAMETER
);
685 plii
->dwTime
= gpsi
->dwLastRITEventTickCount
;
693 LoadKeyboardLayoutA(LPCSTR pszKLID
,
698 if (!MultiByteToWideChar(CP_ACP
, 0, pszKLID
, -1,
699 wszKLID
, sizeof(wszKLID
)/sizeof(wszKLID
[0])))
704 return LoadKeyboardLayoutW(wszKLID
, Flags
);
707 static inline BOOL
IsValidKLID(_In_ LPCWSTR pwszKLID
)
709 return (pwszKLID
!= NULL
) && (wcsspn(pwszKLID
, L
"0123456789ABCDEFabcdef") == (KL_NAMELENGTH
- 1));
712 VOID
GetSystemLibraryPath(LPWSTR pszPath
, INT cchPath
, LPCWSTR pszFileName
)
714 WCHAR szSysDir
[MAX_PATH
];
715 GetSystemDirectoryW(szSysDir
, _countof(szSysDir
));
716 StringCchPrintfW(pszPath
, cchPath
, L
"%s\\%s", szSysDir
, pszFileName
);
719 #define ENGLISH_US MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
724 * NOTE: We adopt a different design from Microsoft's one due to security reason.
725 * See NtUserLoadKeyboardLayoutEx.
728 IntLoadKeyboardLayout(
730 _In_z_ LPCWSTR pwszKLID
,
735 DWORD dwKLID
, dwHKL
, dwType
, dwSize
;
736 UNICODE_STRING ustrKLID
;
737 WCHAR wszRegKey
[256] = L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
738 WCHAR wszLayoutId
[10], wszNewKLID
[KL_NAMELENGTH
], szImeFileName
[80];
744 if (!IsValidKLID(pwszKLID
))
746 ERR("pwszKLID: %s\n", debugstr_w(pwszKLID
));
747 return UlongToHandle(MAKELONG(ENGLISH_US
, ENGLISH_US
));
750 dwKLID
= wcstoul(pwszKLID
, NULL
, 16);
751 bIsIME
= IS_IME_HKL(UlongToHandle(dwKLID
));
753 wLow
= LOWORD(dwKLID
);
754 wHigh
= HIWORD(dwKLID
);
756 if (Flags
& KLF_SUBSTITUTE_OK
)
758 /* Check substitutes key */
759 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Substitutes", 0,
760 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
762 dwSize
= sizeof(wszNewKLID
);
763 if (RegQueryValueExW(hKey
, pwszKLID
, NULL
, &dwType
, (LPBYTE
)wszNewKLID
,
764 &dwSize
) == ERROR_SUCCESS
&&
767 /* Use new KLID value */
768 pwszKLID
= wszNewKLID
;
769 dwKLID
= wcstoul(pwszKLID
, NULL
, 16);
770 wHigh
= LOWORD(dwKLID
);
773 /* Close the key now */
778 /* Append KLID at the end of registry key */
779 StringCbCatW(wszRegKey
, sizeof(wszRegKey
), pwszKLID
);
781 /* Open layout registry key for read */
782 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, wszRegKey
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
784 dwSize
= sizeof(wszLayoutId
);
785 if (RegQueryValueExW(hKey
, L
"Layout Id", NULL
, &dwType
, (LPBYTE
)wszLayoutId
,
786 &dwSize
) == ERROR_SUCCESS
&& dwType
== REG_SZ
)
788 /* If Layout Id is specified, use this value | f000 as HIWORD */
789 wHigh
= (0xF000 | wcstoul(wszLayoutId
, NULL
, 16));
794 /* Check "IME File" value */
795 dwSize
= sizeof(szImeFileName
);
796 if (RegQueryValueExW(hKey
, L
"IME File", NULL
, &dwType
, (LPBYTE
)szImeFileName
,
797 &dwSize
) != ERROR_SUCCESS
)
801 ERR("0x%X\n", dwKLID
);
805 WCHAR szPath
[MAX_PATH
];
806 szImeFileName
[_countof(szImeFileName
) - 1] = UNICODE_NULL
;
807 GetSystemLibraryPath(szPath
, _countof(szPath
), szImeFileName
);
809 /* We don't allow the invalid "IME File" values due to security reason */
810 if (dwType
!= REG_SZ
|| szImeFileName
[0] == 0 ||
811 wcscspn(szImeFileName
, L
":\\/") != wcslen(szImeFileName
) ||
812 GetFileAttributesW(szPath
) == INVALID_FILE_ATTRIBUTES
) /* Does not exist? */
816 ERR("'%s'\n", debugstr_w(szPath
));
821 /* Close the key now */
826 ERR("Could not find keyboard layout %S.\n", pwszKLID
);
833 dwHKL
= MAKELONG(wLow
, wHigh
);
835 RtlInitUnicodeString(&ustrKLID
, pwszKLID
);
836 hNewKL
= NtUserLoadKeyboardLayoutEx(NULL
, 0, NULL
, hklUnload
, &ustrKLID
, dwHKL
, Flags
);
837 CliImmInitializeHotKeys(SETIMEHOTKEY_ADD
, hNewKL
);
845 LoadKeyboardLayoutW(LPCWSTR pwszKLID
,
848 TRACE("(%s, 0x%X)\n", debugstr_w(pwszKLID
), Flags
);
849 return IntLoadKeyboardLayout(NULL
, pwszKLID
, 0, Flags
, FALSE
);
856 LoadKeyboardLayoutEx(HKL hklUnload
,
860 FIXME("(%p, %s, 0x%X)", hklUnload
, debugstr_w(pwszKLID
), Flags
);
863 return IntLoadKeyboardLayout(hklUnload
, pwszKLID
, 0, Flags
, FALSE
);
869 BOOL WINAPI
UnloadKeyboardLayout(HKL hKL
)
871 if (!NtUserUnloadKeyboardLayout(hKL
))
874 CliImmInitializeHotKeys(SETIMEHOTKEY_DELETE
, hKL
);
882 MapVirtualKeyA(UINT uCode
,
885 return MapVirtualKeyExA(uCode
, uMapType
, GetKeyboardLayout(0));
892 MapVirtualKeyExA(UINT uCode
,
896 return MapVirtualKeyExW(uCode
, uMapType
, dwhkl
);
904 MapVirtualKeyExW(UINT uCode
,
908 return NtUserMapVirtualKeyEx(uCode
, uMapType
, 0, dwhkl
);
916 MapVirtualKeyW(UINT uCode
,
919 return MapVirtualKeyExW(uCode
, uMapType
, GetKeyboardLayout(0));
927 OemKeyScan(WORD wOemChar
)
933 MultiByteToWideChar(CP_OEMCP
, 0, (PCSTR
)&wOemChar
, 1, &p
, 1);
935 Scan
= MapVirtualKeyW((Vk
& 0x00ff), 0);
936 if (!Scan
) return -1;
938 Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
939 scan code and high word has the shift state.
941 return ((Vk
& 0xff00) << 8) | Scan
;
949 SetDoubleClickTime(UINT uInterval
)
951 return (BOOL
)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME
,
966 return NtUserxSwapMouseButton(fSwap
);
974 ToAscii(UINT uVirtKey
,
976 CONST BYTE
*lpKeyState
,
980 return ToAsciiEx(uVirtKey
, uScanCode
, lpKeyState
, lpChar
, uFlags
, 0);
988 ToAsciiEx(UINT uVirtKey
,
990 CONST BYTE
*lpKeyState
,
998 Ret
= ToUnicodeEx(uVirtKey
, uScanCode
, lpKeyState
, UniChars
, 2, uFlags
, dwhkl
);
999 CharCount
= (Ret
< 0 ? 1 : Ret
);
1000 WideCharToMultiByte(CP_ACP
, 0, UniChars
, CharCount
, (LPSTR
)lpChar
, 2, NULL
, NULL
);
1010 ToUnicode(UINT wVirtKey
,
1012 CONST BYTE
*lpKeyState
,
1017 return ToUnicodeEx(wVirtKey
, wScanCode
, lpKeyState
, pwszBuff
, cchBuff
,
1026 ToUnicodeEx(UINT wVirtKey
,
1028 CONST BYTE
*lpKeyState
,
1034 return NtUserToUnicodeEx(wVirtKey
, wScanCode
, (PBYTE
)lpKeyState
, pwszBuff
, cchBuff
,
1048 if (IsDBCSLeadByte(ch
))
1051 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
1052 return VkKeyScanW(wChar
);
1060 VkKeyScanExA(CHAR ch
,
1065 if (IsDBCSLeadByte(ch
))
1068 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
1069 return VkKeyScanExW(wChar
, dwhkl
);
1077 VkKeyScanExW(WCHAR ch
,
1080 return (SHORT
)NtUserVkKeyScanEx(ch
, dwhkl
, TRUE
);
1088 VkKeyScanW(WCHAR ch
)
1090 return (SHORT
)NtUserVkKeyScanEx(ch
, 0, FALSE
);
1103 ULONG_PTR dwExtraInfo
)
1107 Input
.type
= INPUT_KEYBOARD
;
1109 Input
.ki
.wScan
= bScan
;
1110 Input
.ki
.dwFlags
= dwFlags
;
1112 Input
.ki
.dwExtraInfo
= dwExtraInfo
;
1114 NtUserSendInput(1, &Input
, sizeof(INPUT
));
1128 ULONG_PTR dwExtraInfo
)
1132 Input
.type
= INPUT_MOUSE
;
1135 Input
.mi
.mouseData
= dwData
;
1136 Input
.mi
.dwFlags
= dwFlags
;
1138 Input
.mi
.dwExtraInfo
= dwExtraInfo
;
1140 NtUserSendInput(1, &Input
, sizeof(INPUT
));