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 CliSaveImeHotKey(DWORD dwID
, UINT uModifiers
, UINT uVirtualKey
, HKL hKL
, BOOL bDelete
)
149 WCHAR szName
[MAX_PATH
];
151 HKEY hControlPanel
= NULL
, hInputMethod
= NULL
, hHotKeys
= NULL
, hKey
= NULL
;
152 BOOL ret
= FALSE
, bRevertOnFailure
= FALSE
;
156 StringCchPrintfW(szName
, _countof(szName
),
157 L
"Control Panel\\Input Method\\Hot Keys\\%08lX", dwID
);
158 error
= RegDeleteKeyW(HKEY_CURRENT_USER
, szName
);
159 return (error
== ERROR_SUCCESS
);
162 // Open "Control Panel"
163 error
= RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel", 0, NULL
, 0, KEY_ALL_ACCESS
,
164 NULL
, &hControlPanel
, NULL
);
165 if (error
== ERROR_SUCCESS
)
167 // Open "Input Method"
168 error
= RegCreateKeyExW(hControlPanel
, L
"Input Method", 0, NULL
, 0, KEY_ALL_ACCESS
,
169 NULL
, &hInputMethod
, NULL
);
170 if (error
== ERROR_SUCCESS
)
173 error
= RegCreateKeyExW(hInputMethod
, L
"Hot Keys", 0, NULL
, 0, KEY_ALL_ACCESS
,
174 NULL
, &hHotKeys
, NULL
);
175 if (error
== ERROR_SUCCESS
)
178 StringCchPrintfW(szName
, _countof(szName
), L
"%08lX", dwID
);
179 error
= RegCreateKeyExW(hHotKeys
, szName
, 0, NULL
, 0, KEY_ALL_ACCESS
,
181 if (error
== ERROR_SUCCESS
)
183 bRevertOnFailure
= TRUE
;
186 error
= RegSetValueExW(hKey
, L
"Virtual Key", 0, REG_BINARY
,
187 (LPBYTE
)&uVirtualKey
, sizeof(uVirtualKey
));
188 if (error
== ERROR_SUCCESS
)
190 // Set "Key Modifiers"
191 error
= RegSetValueExW(hKey
, L
"Key Modifiers", 0, REG_BINARY
,
192 (LPBYTE
)&uModifiers
, sizeof(uModifiers
));
193 if (error
== ERROR_SUCCESS
)
196 error
= RegSetValueExW(hKey
, L
"Target IME", 0, REG_BINARY
,
197 (LPBYTE
)&hKL
, sizeof(hKL
));
198 if (error
== ERROR_SUCCESS
)
202 bRevertOnFailure
= FALSE
;
208 RegCloseKey(hHotKeys
);
210 RegCloseKey(hInputMethod
);
212 RegCloseKey(hControlPanel
);
215 if (bRevertOnFailure
)
216 CliSaveImeHotKey(dwID
, uVirtualKey
, uModifiers
, hKL
, TRUE
);
223 * Same as imm32!ImmSetHotKey.
225 BOOL WINAPI
CliImmSetHotKey(DWORD dwID
, UINT uModifiers
, UINT uVirtualKey
, HKL hKL
)
229 if (uVirtualKey
== 0) // Delete?
231 ret
= CliSaveImeHotKey(dwID
, uModifiers
, uVirtualKey
, hKL
, TRUE
);
233 CliImmSetHotKeyWorker(dwID
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_DELETE
);
238 ret
= CliImmSetHotKeyWorker(dwID
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_ADD
);
241 ret
= CliSaveImeHotKey(dwID
, uModifiers
, uVirtualKey
, hKL
, FALSE
);
242 if (!ret
) // Failure?
243 CliImmSetHotKeyWorker(dwID
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_DELETE
);
249 BOOL FASTCALL
CliSetSingleHotKey(LPCWSTR pszSubKey
, HANDLE hKey
)
253 DWORD dwHotKeyId
= 0;
254 UINT uModifiers
= 0, uVirtualKey
= 0;
256 UNICODE_STRING ustrName
;
258 error
= RegOpenKeyExW(hKey
, pszSubKey
, 0, KEY_READ
, &hSubKey
);
259 if (error
!= ERROR_SUCCESS
)
262 RtlInitUnicodeString(&ustrName
, pszSubKey
);
263 RtlUnicodeStringToInteger(&ustrName
, 16, &dwHotKeyId
);
265 uModifiers
= CliReadRegistryValue(hSubKey
, L
"Key Modifiers");
266 hKL
= (HKL
)(ULONG_PTR
)CliReadRegistryValue(hSubKey
, L
"Target IME");
267 uVirtualKey
= CliReadRegistryValue(hSubKey
, L
"Virtual Key");
269 RegCloseKey(hSubKey
);
271 return CliImmSetHotKeyWorker(dwHotKeyId
, uModifiers
, uVirtualKey
, hKL
, SETIMEHOTKEY_ADD
);
274 BOOL FASTCALL
CliGetImeHotKeysFromRegistry(VOID
)
279 DWORD dwIndex
, cchKeyName
;
282 error
= RegOpenKeyExW(HKEY_CURRENT_USER
,
283 L
"Control Panel\\Input Method\\Hot Keys",
287 if (error
!= ERROR_SUCCESS
)
290 for (dwIndex
= 0; ; ++dwIndex
)
292 cchKeyName
= _countof(szKeyName
);
293 error
= RegEnumKeyExW(hKey
, dwIndex
, szKeyName
, &cchKeyName
, NULL
, NULL
, NULL
, NULL
);
294 if (error
== ERROR_NO_MORE_ITEMS
|| error
!= ERROR_SUCCESS
)
297 szKeyName
[_countof(szKeyName
) - 1] = 0;
299 if (CliSetSingleHotKey(szKeyName
, hKey
))
307 VOID APIENTRY
CliGetPreloadKeyboardLayouts(PBYTE pbFlags
)
309 WCHAR szValueName
[8], szValue
[16];
310 UNICODE_STRING ustrValue
;
311 DWORD dwKL
, cbValue
, dwType
;
316 error
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Preload", 0, KEY_READ
, &hKey
);
317 if (error
!= ERROR_SUCCESS
)
320 for (iNumber
= 1; iNumber
< 1000; ++iNumber
)
322 StringCchPrintfW(szValueName
, _countof(szValueName
), L
"%u", iNumber
);
324 cbValue
= sizeof(szValue
);
325 error
= RegQueryValueExW(hKey
, szValueName
, NULL
, &dwType
, (LPBYTE
)szValue
, &cbValue
);
326 if (error
!= ERROR_SUCCESS
|| dwType
!= REG_SZ
)
329 szValue
[_countof(szValue
) - 1] = 0;
331 RtlInitUnicodeString(&ustrValue
, szValue
);
332 RtlUnicodeStringToInteger(&ustrValue
, 16, &dwKL
);
334 IntSetFeKeyboardFlags(LOWORD(dwKL
), pbFlags
);
340 VOID APIENTRY
CliSetDefaultImeHotKeys(PIMEHOTKEYENTRY pEntries
, UINT nCount
, BOOL bCheck
)
342 UINT uVirtualKey
, uModifiers
;
347 if (!bCheck
|| !NtUserGetImeHotKey(pEntries
->dwHotKeyId
, &uModifiers
, &uVirtualKey
, &hKL
))
349 CliImmSetHotKeyWorker(pEntries
->dwHotKeyId
,
350 pEntries
->uModifiers
,
351 pEntries
->uVirtualKey
,
359 VOID APIENTRY
CliImmInitializeHotKeys(DWORD dwAction
, HKL hKL
)
368 NtUserSetImeHotKey(0, 0, 0, NULL
, SETIMEHOTKEY_DELETEALL
);
370 bCheck
= CliGetImeHotKeysFromRegistry();
372 if (dwAction
== SETIMEHOTKEY_DELETEALL
)
374 LangID
= LANGIDFROMLCID(GetUserDefaultLCID());
375 IntSetFeKeyboardFlags(LangID
, &bFlags
);
377 CliGetPreloadKeyboardLayouts(&bFlags
);
381 nCount
= NtUserGetKeyboardLayoutList(0, NULL
);
385 pList
= RtlAllocateHeap(RtlGetProcessHeap(), 0, nCount
* sizeof(HKL
));
389 NtUserGetKeyboardLayoutList(nCount
, pList
);
391 for (iIndex
= 0; iIndex
< nCount
; ++iIndex
)
393 LangID
= LOWORD(pList
[iIndex
]);
394 IntSetFeKeyboardFlags(LangID
, &bFlags
);
397 RtlFreeHeap(RtlGetProcessHeap(), 0, pList
);
400 if (bFlags
& FE_JAPANESE
)
401 CliSetDefaultImeHotKeys(DefaultHotKeyTableJ
, _countof(DefaultHotKeyTableJ
), bCheck
);
403 if (bFlags
& FE_CHINESE_TRADITIONAL
)
404 CliSetDefaultImeHotKeys(DefaultHotKeyTableT
, _countof(DefaultHotKeyTableT
), bCheck
);
406 if (bFlags
& FE_CHINESE_SIMPLIFIED
)
407 CliSetDefaultImeHotKeys(DefaultHotKeyTableC
, _countof(DefaultHotKeyTableC
), bCheck
);
419 return NtUserDragDetect(hWnd
, pt
);
424 ULONG dx
= GetSystemMetrics(SM_CXDRAG
);
425 ULONG dy
= GetSystemMetrics(SM_CYDRAG
);
427 rect
.left
= pt
.x
- dx
;
428 rect
.right
= pt
.x
+ dx
;
429 rect
.top
= pt
.y
- dy
;
430 rect
.bottom
= pt
.y
+ dy
;
437 PeekMessageW(&msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_REMOVE
) ||
438 PeekMessageW(&msg
, 0, WM_KEYFIRST
, WM_KEYLAST
, PM_REMOVE
)
441 if (msg
.message
== WM_LBUTTONUP
)
446 if (msg
.message
== WM_MOUSEMOVE
)
448 tmp
.x
= LOWORD(msg
.lParam
);
449 tmp
.y
= HIWORD(msg
.lParam
);
450 if (!PtInRect(&rect
, tmp
))
456 if (msg
.message
== WM_KEYDOWN
)
458 if (msg
.wParam
== VK_ESCAPE
)
475 EnableWindow(HWND hWnd
, BOOL bEnable
)
477 return NtUserxEnableWindow(hWnd
, bEnable
);
486 GetAsyncKeyState(int vKey
)
488 if (vKey
< 0 || vKey
> 256)
490 return (SHORT
)NtUserGetAsyncKeyState((DWORD
)vKey
);
498 GetKeyboardLayout(DWORD idThread
)
500 return NtUserxGetKeyboardLayout(idThread
);
518 GetKeyNameTextA(LONG lParam
,
525 BOOL defChar
= FALSE
;
527 pwszBuf
= HeapAlloc(GetProcessHeap(), 0, nSize
* sizeof(WCHAR
));
531 cchBuf
= NtUserGetKeyNameText(lParam
, pwszBuf
, nSize
);
533 iRet
= WideCharToMultiByte(CP_ACP
, 0,
535 lpString
, nSize
, ".", &defChar
); // FIXME: do we need defChar?
537 HeapFree(GetProcessHeap(), 0, pwszBuf
);
546 GetKeyNameTextW(LONG lParam
,
550 return NtUserGetKeyNameText(lParam
, lpString
, nSize
);
559 GetKeyState(int nVirtKey
)
561 return (SHORT
)NtUserGetKeyState((DWORD
)nVirtKey
);
568 GetKeyboardLayoutNameA(LPSTR pwszKLID
)
570 WCHAR buf
[KL_NAMELENGTH
];
572 if (!GetKeyboardLayoutNameW(buf
))
575 if (!WideCharToMultiByte(CP_ACP
, 0, buf
, -1, pwszKLID
, KL_NAMELENGTH
, NULL
, NULL
))
585 GetKeyboardLayoutNameW(LPWSTR pwszKLID
)
589 RtlInitEmptyUnicodeString(&Name
,
591 KL_NAMELENGTH
* sizeof(WCHAR
));
593 return NtUserGetKeyboardLayoutName(&Name
);
600 GetKeyboardType(int nTypeFlag
)
602 return NtUserxGetKeyboardType(nTypeFlag
);
609 GetLastInputInfo(PLASTINPUTINFO plii
)
613 if (plii
->cbSize
!= sizeof (*plii
))
615 SetLastError(ERROR_INVALID_PARAMETER
);
619 plii
->dwTime
= gpsi
->dwLastRITEventTickCount
;
627 LoadKeyboardLayoutA(LPCSTR pszKLID
,
632 if (!MultiByteToWideChar(CP_ACP
, 0, pszKLID
, -1,
633 wszKLID
, sizeof(wszKLID
)/sizeof(wszKLID
[0])))
638 return LoadKeyboardLayoutW(wszKLID
, Flags
);
645 LoadKeyboardLayoutW(LPCWSTR pwszKLID
,
648 DWORD dwhkl
, dwType
, dwSize
;
649 UNICODE_STRING ustrKbdName
;
650 UNICODE_STRING ustrKLID
;
651 WCHAR wszRegKey
[256] = L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
652 WCHAR wszLayoutId
[10], wszNewKLID
[10];
655 /* LOWORD of dwhkl is Locale Identifier */
656 dwhkl
= LOWORD(wcstoul(pwszKLID
, NULL
, 16));
658 if (Flags
& KLF_SUBSTITUTE_OK
)
660 /* Check substitutes key */
661 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Substitutes", 0,
662 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
664 dwSize
= sizeof(wszNewKLID
);
665 if (RegQueryValueExW(hKey
, pwszKLID
, NULL
, &dwType
, (LPBYTE
)wszNewKLID
, &dwSize
) == ERROR_SUCCESS
)
667 /* Use new KLID value */
668 pwszKLID
= wszNewKLID
;
671 /* Close the key now */
676 /* Append KLID at the end of registry key */
677 StringCbCatW(wszRegKey
, sizeof(wszRegKey
), pwszKLID
);
679 /* Open layout registry key for read */
680 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, wszRegKey
, 0,
681 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
683 dwSize
= sizeof(wszLayoutId
);
684 if (RegQueryValueExW(hKey
, L
"Layout Id", NULL
, &dwType
, (LPBYTE
)wszLayoutId
, &dwSize
) == ERROR_SUCCESS
)
686 /* If Layout Id is specified, use this value | f000 as HIWORD */
687 /* FIXME: Microsoft Office expects this value to be something specific
688 * for Japanese and Korean Windows with an IME the value is 0xe001
689 * We should probably check to see if an IME exists and if so then
690 * set this word properly.
692 dwhkl
|= (0xf000 | wcstol(wszLayoutId
, NULL
, 16)) << 16;
695 /* Close the key now */
700 ERR("Could not find keyboard layout %S.\n", pwszKLID
);
704 /* If Layout Id is not given HIWORD == LOWORD (for dwhkl) */
706 dwhkl
|= dwhkl
<< 16;
708 ZeroMemory(&ustrKbdName
, sizeof(ustrKbdName
));
709 RtlInitUnicodeString(&ustrKLID
, pwszKLID
);
710 return NtUserLoadKeyboardLayoutEx(NULL
, 0, &ustrKbdName
,
718 BOOL WINAPI
UnloadKeyboardLayout(HKL hKL
)
720 if (!NtUserUnloadKeyboardLayout(hKL
))
723 CliImmInitializeHotKeys(SETIMEHOTKEY_DELETE
, hKL
);
731 MapVirtualKeyA(UINT uCode
,
734 return MapVirtualKeyExA(uCode
, uMapType
, GetKeyboardLayout(0));
741 MapVirtualKeyExA(UINT uCode
,
745 return MapVirtualKeyExW(uCode
, uMapType
, dwhkl
);
753 MapVirtualKeyExW(UINT uCode
,
757 return NtUserMapVirtualKeyEx(uCode
, uMapType
, 0, dwhkl
);
765 MapVirtualKeyW(UINT uCode
,
768 return MapVirtualKeyExW(uCode
, uMapType
, GetKeyboardLayout(0));
776 OemKeyScan(WORD wOemChar
)
782 MultiByteToWideChar(CP_OEMCP
, 0, (PCSTR
)&wOemChar
, 1, &p
, 1);
784 Scan
= MapVirtualKeyW((Vk
& 0x00ff), 0);
785 if (!Scan
) return -1;
787 Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
788 scan code and high word has the shift state.
790 return ((Vk
& 0xff00) << 8) | Scan
;
798 SetDoubleClickTime(UINT uInterval
)
800 return (BOOL
)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME
,
815 return NtUserxSwapMouseButton(fSwap
);
823 ToAscii(UINT uVirtKey
,
825 CONST BYTE
*lpKeyState
,
829 return ToAsciiEx(uVirtKey
, uScanCode
, lpKeyState
, lpChar
, uFlags
, 0);
837 ToAsciiEx(UINT uVirtKey
,
839 CONST BYTE
*lpKeyState
,
847 Ret
= ToUnicodeEx(uVirtKey
, uScanCode
, lpKeyState
, UniChars
, 2, uFlags
, dwhkl
);
848 CharCount
= (Ret
< 0 ? 1 : Ret
);
849 WideCharToMultiByte(CP_ACP
, 0, UniChars
, CharCount
, (LPSTR
)lpChar
, 2, NULL
, NULL
);
859 ToUnicode(UINT wVirtKey
,
861 CONST BYTE
*lpKeyState
,
866 return ToUnicodeEx(wVirtKey
, wScanCode
, lpKeyState
, pwszBuff
, cchBuff
,
875 ToUnicodeEx(UINT wVirtKey
,
877 CONST BYTE
*lpKeyState
,
883 return NtUserToUnicodeEx(wVirtKey
, wScanCode
, (PBYTE
)lpKeyState
, pwszBuff
, cchBuff
,
897 if (IsDBCSLeadByte(ch
))
900 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
901 return VkKeyScanW(wChar
);
909 VkKeyScanExA(CHAR ch
,
914 if (IsDBCSLeadByte(ch
))
917 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
918 return VkKeyScanExW(wChar
, dwhkl
);
926 VkKeyScanExW(WCHAR ch
,
929 return (SHORT
)NtUserVkKeyScanEx(ch
, dwhkl
, TRUE
);
939 return (SHORT
)NtUserVkKeyScanEx(ch
, 0, FALSE
);
952 ULONG_PTR dwExtraInfo
)
956 Input
.type
= INPUT_KEYBOARD
;
958 Input
.ki
.wScan
= bScan
;
959 Input
.ki
.dwFlags
= dwFlags
;
961 Input
.ki
.dwExtraInfo
= dwExtraInfo
;
963 NtUserSendInput(1, &Input
, sizeof(INPUT
));
977 ULONG_PTR dwExtraInfo
)
981 Input
.type
= INPUT_MOUSE
;
984 Input
.mi
.mouseData
= dwData
;
985 Input
.mi
.dwFlags
= dwFlags
;
987 Input
.mi
.dwExtraInfo
= dwExtraInfo
;
989 NtUserSendInput(1, &Input
, sizeof(INPUT
));