ReactOS 0.4.16-dev-1165-g40721f4
hotkey.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: HotKey support
5 * FILE: win32ss/user/ntuser/hotkey.c
6 * PROGRAMER: Eric Kohl
7 */
8
9/*
10 * FIXME: Hotkey notifications are triggered by keyboard input (physical or programmatically)
11 * and since only desktops on WinSta0 can receive input in seems very wrong to allow
12 * windows/threads on destops not belonging to WinSta0 to set hotkeys (receive notifications).
13 * -- Gunnar
14 */
15
16#include <win32k.h>
18
19/* GLOBALS *******************************************************************/
20
21/*
22 * Hardcoded hotkeys. See http://ivanlef0u.fr/repo/windoz/VI20051005.html (DEAD_LINK)
23 * or https://web.archive.org/web/20170826161432/http://repo.meh.or.id/Windows/VI20051005.html .
24 *
25 * NOTE: The (Shift-)F12 keys are used only for the "UserDebuggerHotKey" setting
26 * which enables setting a key shortcut which, when pressed, establishes a
27 * breakpoint in the code being debugged:
28 * see https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc786263(v=ws.10)
29 * and https://flylib.com/books/en/4.441.1.33/1/ for more details.
30 * By default the key is VK-F12 on a 101-key keyboard, and is VK_SUBTRACT
31 * (hyphen / substract sign) on a 82-key keyboard.
32 */
33/* pti pwnd modifiers vk id next */
34// HOT_KEY hkF12 = {NULL, 1, 0, VK_F12, IDHK_F12, NULL};
35// HOT_KEY hkShiftF12 = {NULL, 1, MOD_SHIFT, VK_F12, IDHK_SHIFTF12, &hkF12};
36// HOT_KEY hkWinKey = {NULL, 1, MOD_WIN, 0, IDHK_WINKEY, &hkShiftF12};
37
40
41/* FUNCTIONS *****************************************************************/
42
43#define IsWindowHotKey(pHK) ( (pHK)->pti == NULL && (pHK)->id == IDHK_WNDKEY )
44
47{
48 UINT vk = VK_F12;
52 {
54 }
57 TRACE("Start up the debugger hotkeys!! If you see this you enabled debugprints. Congrats!\n");
58}
59
60/*
61 * IntGetModifiers
62 *
63 * Returns a value that indicates if the key is a modifier key, and
64 * which one.
65 */
66static
69{
70 UINT fModifiers = 0;
71
72 if (IS_KEY_DOWN(pKeyState, VK_SHIFT))
73 fModifiers |= MOD_SHIFT;
74
75 if (IS_KEY_DOWN(pKeyState, VK_CONTROL))
76 fModifiers |= MOD_CONTROL;
77
78 if (IS_KEY_DOWN(pKeyState, VK_MENU))
79 fModifiers |= MOD_ALT;
80
81 if (IS_KEY_DOWN(pKeyState, VK_LWIN) || IS_KEY_DOWN(pKeyState, VK_RWIN))
82 fModifiers |= MOD_WIN;
83
84 return fModifiers;
85}
86
87/*
88 * IntSwapModHKF
89 *
90 * Maps to/from MOD_/HOTKEYF_ (swaps the SHIFT and ALT bits)
91 */
92static inline
95{
96 return (Input & 2) | ((Input & 1) << 2) | ((Input >> 2) & 1);
97}
98
99/*
100 * UnregisterWindowHotKeys
101 *
102 * Removes hotkeys registered by specified window on its cleanup
103 */
106{
107 PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
108
109 while (pHotKey)
110 {
111 /* Save next ptr for later use */
112 phkNext = pHotKey->pNext;
113
114 /* Should we delete this hotkey? */
115 if (pHotKey->pWnd == pWnd)
116 {
117 /* Update next ptr for previous hotkey and free memory */
118 *pLink = phkNext;
120 }
121 else /* This hotkey will stay, use its next ptr */
122 pLink = &pHotKey->pNext;
123
124 /* Move to the next entry */
125 pHotKey = phkNext;
126 }
127}
128
129/*
130 * UnregisterThreadHotKeys
131 *
132 * Removes hotkeys registered by specified thread on its cleanup
133 */
136{
137 PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
138
139 while (pHotKey)
140 {
141 /* Save next ptr for later use */
142 phkNext = pHotKey->pNext;
143
144 /* Should we delete this hotkey? */
145 if (pHotKey->pti == pti)
146 {
147 /* Update next ptr for previous hotkey and free memory */
148 *pLink = phkNext;
150 }
151 else /* This hotkey will stay, use its next ptr */
152 pLink = &pHotKey->pNext;
153
154 /* Move to the next entry */
155 pHotKey = phkNext;
156 }
157}
158
159/*
160 * IsHotKey
161 *
162 * Checks if given key and modificators have corresponding hotkey
163 */
164static PHOT_KEY FASTCALL
165IsHotKey(UINT fsModifiers, WORD wVk)
166{
167 PHOT_KEY pHotKey = gphkFirst;
168
169 while (pHotKey)
170 {
171 if (pHotKey->fsModifiers == fsModifiers &&
172 pHotKey->vk == wVk)
173 {
174 /* We have found it */
175 return pHotKey;
176 }
177
178 /* Move to the next entry */
179 pHotKey = pHotKey->pNext;
180 }
181
182 return NULL;
183}
184
185/*
186 * co_UserProcessHotKeys
187 *
188 * Sends WM_HOTKEY message if given keys are hotkey
189 */
192{
193 UINT fModifiers;
194 PHOT_KEY pHotKey;
195 PWND pWnd;
196 BOOL DoNotPostMsg = FALSE;
197 BOOL IsModifier = FALSE;
198
199 if (wVk == VK_SHIFT || wVk == VK_CONTROL || wVk == VK_MENU ||
200 wVk == VK_LWIN || wVk == VK_RWIN)
201 {
202 /* Remember that this was a modifier */
203 IsModifier = TRUE;
204 }
205
206 fModifiers = IntGetModifiers(gafAsyncKeyState);
207
208 if (bIsDown)
209 {
210 if (IsModifier)
211 {
212 /* Modifier key down -- no hotkey trigger, but remember this */
213 gfsModOnlyCandidate = fModifiers;
214 return FALSE;
215 }
216 else
217 {
218 /* Regular key down -- check for hotkey, and reset mod candidates */
219 pHotKey = IsHotKey(fModifiers, wVk);
221 }
222 }
223 else
224 {
225 if (IsModifier)
226 {
227 /* Modifier key up -- modifier-only keys are triggered here */
228 pHotKey = IsHotKey(gfsModOnlyCandidate, 0);
230 }
231 else
232 {
233 /* Regular key up -- no hotkey, but reset mod-only candidates */
235 return FALSE;
236 }
237 }
238
239 if (pHotKey)
240 {
241 TRACE("Hot key pressed (pWnd %p, id %d)\n", pHotKey->pWnd, pHotKey->id);
242
243 /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */
244 if (pHotKey->id == IDHK_SHIFTF12 || pHotKey->id == IDHK_F12)
245 {
246 if (bIsDown)
247 {
248 ERR("Hot key pressed for Debug Activation! ShiftF12 = %d or F12 = %d\n",pHotKey->id == IDHK_SHIFTF12 , pHotKey->id == IDHK_F12);
249 //DoNotPostMsg = co_ActivateDebugger(); // FIXME
250 }
251 return DoNotPostMsg;
252 }
253
254 /* WIN and F12 keys are not hardcoded here. See comments on top of this file. */
255 if (pHotKey->id == IDHK_WINKEY)
256 {
257 ASSERT(!bIsDown);
259 if (pWnd)
260 {
261 TRACE("System Hot key Id %d Key %u\n", pHotKey->id, wVk );
263 co_IntShellHookNotify(HSHELL_TASKMAN, 0, 0);
264 return FALSE;
265 }
266 }
267
268 if (pHotKey->id == IDHK_SNAP_LEFT ||
269 pHotKey->id == IDHK_SNAP_RIGHT ||
270 pHotKey->id == IDHK_SNAP_UP ||
271 pHotKey->id == IDHK_SNAP_DOWN)
272 {
273 HWND topWnd = UserGetForegroundWindow();
274 if (topWnd)
275 {
276 UserPostMessage(topWnd, WM_KEYDOWN, wVk, 0);
277 }
278 return TRUE;
279 }
280
281 if (!pHotKey->pWnd)
282 {
283 TRACE("UPTM Hot key Id %d Key %u\n", pHotKey->id, wVk );
284 UserPostThreadMessage(pHotKey->pti, WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
285 //ptiLastInput = pHotKey->pti;
286 return TRUE; /* Don't send any message */
287 }
288 else
289 {
290 pWnd = pHotKey->pWnd;
291 if (pWnd == PWND_BOTTOM)
292 {
293 if (gpqForeground == NULL)
294 return FALSE;
295
297 }
298
299 if (pWnd)
300 {
301 // pWnd->head.rpdesk->pDeskInfo->spwndShell needs testing.
303 {
305 co_IntShellHookNotify(HSHELL_TASKMAN, 0, 0);
306 }
307 else if (IsWindowHotKey(pHotKey))
308 {
309 /* WM_SETHOTKEY notifies with WM_SYSCOMMAND, not WM_HOTKEY */
310 if (bIsDown)
311 {
316 }
317 }
318 else
319 {
320 TRACE("UPM Hot key Id %d Key %u\n", pHotKey->id, wVk );
321 UserPostMessage(UserHMGetHandle(pWnd), WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk));
322 }
323 //ptiLastInput = pWnd->head.pti;
324 return TRUE; /* Don't send any message */
325 }
326 }
327 }
328 return FALSE;
329}
330
331
332/*
333 * DefWndGetHotKey --- GetHotKey message support
334 *
335 * Win: DWP_GetHotKey
336 */
339{
340 PHOT_KEY pHotKey = gphkFirst;
341
342 WARN("DefWndGetHotKey\n");
343
344 while (pHotKey)
345 {
346 if (pHotKey->pWnd == pWnd && IsWindowHotKey(pHotKey))
347 {
348 /* We have found it */
349 return MAKEWORD(pHotKey->vk, IntSwapModHKF(pHotKey->fsModifiers));
350 }
351
352 /* Move to the next entry */
353 pHotKey = pHotKey->pNext;
354 }
355
356 return 0;
357}
358
359/*
360 * DefWndSetHotKey --- SetHotKey message support
361 *
362 * Win: DWP_SetHotKey
363 */
366{
367 const UINT fsModifiers = IntSwapModHKF(HIBYTE(wParam));
368 const UINT vk = LOBYTE(wParam);
369 PHOT_KEY pHotKey, *pLink;
370 INT iRet = 1;
371
372 WARN("DefWndSetHotKey wParam 0x%x\n", wParam);
373
374 // A hot key cannot be associated with a child window.
375 if (pWnd->style & WS_CHILD)
376 return 0;
377
378 // VK_ESCAPE, VK_SPACE, VK_TAB and VK_PACKET are invalid hot keys.
379 if (vk == VK_ESCAPE || vk == VK_SPACE || vk == VK_TAB || vk == VK_PACKET)
380 {
381 return -1;
382 }
383
384 if (wParam)
385 {
386 pHotKey = gphkFirst;
387 while (pHotKey)
388 {
389 if (pHotKey->fsModifiers == fsModifiers &&
390 pHotKey->vk == vk &&
391 IsWindowHotKey(pHotKey))
392 {
393 if (pHotKey->pWnd != pWnd)
394 iRet = 2; // Another window already has the same hot key.
395 break;
396 }
397
398 /* Move to the next entry */
399 pHotKey = pHotKey->pNext;
400 }
401 }
402
403 pHotKey = gphkFirst;
404 pLink = &gphkFirst;
405 while (pHotKey)
406 {
407 if (pHotKey->pWnd == pWnd && IsWindowHotKey(pHotKey))
408 {
409 /* This window has already hotkey registered */
410 break;
411 }
412
413 /* Move to the next entry */
414 pLink = &pHotKey->pNext;
415 pHotKey = pHotKey->pNext;
416 }
417
418 if (wParam)
419 {
420 if (!pHotKey)
421 {
422 /* Create new hotkey */
424 if (pHotKey == NULL)
425 return 0;
426
427 pHotKey->pWnd = pWnd;
428 pHotKey->id = IDHK_WNDKEY; // Don't care, these hot keys are unrelated to the hot keys set by RegisterHotKey
429 pHotKey->pNext = gphkFirst;
430 gphkFirst = pHotKey;
431 }
432
433 /* A window can only have one hot key. If the window already has a
434 hot key associated with it, the new hot key replaces the old one. */
435 pHotKey->pti = NULL; /* IsWindowHotKey */
436 pHotKey->fsModifiers = fsModifiers;
437 pHotKey->vk = vk;
438 }
439 else if (pHotKey)
440 {
441 /* Remove hotkey */
442 *pLink = pHotKey->pNext;
444 }
445
446 return iRet;
447}
448
449
452 int id,
453 UINT fsModifiers,
454 UINT vk)
455{
456 PHOT_KEY pHotKey;
457 PTHREADINFO pHotKeyThread;
458
459 /* Find hotkey thread */
460 if (pWnd == NULL || pWnd == PWND_BOTTOM)
461 {
462 pHotKeyThread = PsGetCurrentThreadWin32Thread();
463 }
464 else
465 {
466 pHotKeyThread = pWnd->head.pti;
467 }
468
469 /* Check for existing hotkey */
470 if (IsHotKey(fsModifiers, vk))
471 {
473 WARN("Hotkey already exists\n");
474 return FALSE;
475 }
476
477 /* Create new hotkey */
479 if (pHotKey == NULL)
480 {
482 return FALSE;
483 }
484
485 pHotKey->pti = pHotKeyThread;
486 pHotKey->pWnd = pWnd;
487 pHotKey->fsModifiers = fsModifiers;
488 pHotKey->vk = vk;
489 pHotKey->id = id;
490
491 /* Insert hotkey to the global list */
492 pHotKey->pNext = gphkFirst;
493 gphkFirst = pHotKey;
494
495 return TRUE;
496}
497
500{
501 PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
502 BOOL bRet = FALSE;
503
504 while (pHotKey)
505 {
506 /* Save next ptr for later use */
507 phkNext = pHotKey->pNext;
508
509 /* Should we delete this hotkey? */
510 if (pHotKey->pWnd == pWnd && pHotKey->id == id)
511 {
512 /* Update next ptr for previous hotkey and free memory */
513 *pLink = phkNext;
515
516 bRet = TRUE;
517 }
518 else /* This hotkey will stay, use its next ptr */
519 pLink = &pHotKey->pNext;
520
521 /* Move to the next entry */
522 pHotKey = phkNext;
523 }
524 return bRet;
525}
526
527
528/* SYSCALLS *****************************************************************/
529
530
533 int id,
534 UINT fsModifiers,
535 UINT vk)
536{
537 PHOT_KEY pHotKey;
538 PWND pWnd = NULL;
539 PTHREADINFO pHotKeyThread;
540 BOOL bRet = FALSE;
541
542 TRACE("Enter NtUserRegisterHotKey\n");
543
544 if (fsModifiers & ~(MOD_ALT|MOD_CONTROL|MOD_SHIFT|MOD_WIN)) // FIXME: Does Win2k3 support MOD_NOREPEAT?
545 {
546 WARN("Invalid modifiers: %x\n", fsModifiers);
548 return 0;
549 }
550
552
553 /* Find hotkey thread */
554 if (hWnd == NULL)
555 {
556 pHotKeyThread = gptiCurrent;
557 }
558 else
559 {
561 if (!pWnd)
562 goto cleanup;
563
564 pHotKeyThread = pWnd->head.pti;
565
566 /* Fix wine msg "Window on another thread" test_hotkey */
567 if (pWnd->head.pti != gptiCurrent)
568 {
570 WARN("Must be from the same Thread.\n");
571 goto cleanup;
572 }
573 }
574
575 /* Check for existing hotkey */
576 if (IsHotKey(fsModifiers, vk))
577 {
579 WARN("Hotkey already exists\n");
580 goto cleanup;
581 }
582
583 /* Create new hotkey */
585 if (pHotKey == NULL)
586 {
588 goto cleanup;
589 }
590
591 pHotKey->pti = pHotKeyThread;
592 pHotKey->pWnd = pWnd;
593 pHotKey->fsModifiers = fsModifiers;
594 pHotKey->vk = vk;
595 pHotKey->id = id;
596
597 /* Insert hotkey to the global list */
598 pHotKey->pNext = gphkFirst;
599 gphkFirst = pHotKey;
600
601 bRet = TRUE;
602
603cleanup:
604 TRACE("Leave NtUserRegisterHotKey, ret=%i\n", bRet);
605 UserLeave();
606 return bRet;
607}
608
609
612{
613 PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst;
614 BOOL bRet = FALSE;
615 PWND pWnd = NULL;
616
617 TRACE("Enter NtUserUnregisterHotKey\n");
619
620 /* Fail if given window is invalid */
621 if (hWnd && !(pWnd = UserGetWindowObject(hWnd)))
622 goto cleanup;
623
624 while (pHotKey)
625 {
626 /* Save next ptr for later use */
627 phkNext = pHotKey->pNext;
628
629 /* Should we delete this hotkey? */
630 if (pHotKey->pWnd == pWnd && pHotKey->id == id)
631 {
632 /* Update next ptr for previous hotkey and free memory */
633 *pLink = phkNext;
635
636 bRet = TRUE;
637 }
638 else /* This hotkey will stay, use its next ptr */
639 pLink = &pHotKey->pNext;
640
641 /* Move to the next entry */
642 pHotKey = phkNext;
643 }
644
645cleanup:
646 TRACE("Leave NtUserUnregisterHotKey, ret=%i\n", bRet);
647 UserLeave();
648 return bRet;
649}
650
651/* EOF */
HWND hWnd
Definition: settings.c:17
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
WPARAM wParam
Definition: combotst.c:138
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define APIENTRY
Definition: api.h:79
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:109
static void cleanup(void)
Definition: main.c:1335
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
HWND FASTCALL UserGetForegroundWindow(VOID)
Definition: focus.c:1424
GLuint id
Definition: glext.h:5910
#define IDHK_SNAP_LEFT
Definition: hotkey.h:20
#define IDHK_WNDKEY
Definition: hotkey.h:17
#define IDHK_WINKEY
Definition: hotkey.h:16
#define IDHK_SNAP_UP
Definition: hotkey.h:22
#define IDHK_F12
Definition: hotkey.h:14
#define IDHK_SNAP_DOWN
Definition: hotkey.h:23
#define IDHK_SNAP_RIGHT
Definition: hotkey.h:21
#define IDHK_SHIFTF12
Definition: hotkey.h:15
#define MOD_ALT
Definition: imm.h:184
#define MOD_SHIFT
Definition: imm.h:186
#define MOD_CONTROL
Definition: imm.h:185
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define PWND_BOTTOM
Definition: ntuser.h:769
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
WORD vk
Definition: input.c:77
unsigned int UINT
Definition: ndis.h:50
#define FASTCALL
Definition: nt_native.h:50
#define ENHANCED_KEYBOARD(Id)
Definition: ntddkbd.h:105
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
#define WS_CHILD
Definition: pedump.c:617
BYTE * PBYTE
Definition: pedump.c:66
@ Input
Definition: arc.h:84
#define TRACE(s)
Definition: solgame.cpp:4
Definition: hotkey.h:4
UINT fsModifiers
Definition: hotkey.h:7
PTHREADINFO pti
Definition: hotkey.h:5
struct _HOT_KEY * pNext
Definition: hotkey.h:10
INT id
Definition: hotkey.h:9
UINT vk
Definition: hotkey.h:8
PWND pWnd
Definition: hotkey.h:6
KEYBOARD_ID KeyboardIdentifier
Definition: ntddkbd.h:124
HANDLE ShellWindow
Definition: winsta.h:43
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:695
DWORD style
Definition: ntuser.h:706
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define NTAPI
Definition: typedefs.h:36
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:124
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1709
BOOL APIENTRY NtUserUnregisterHotKey(HWND hWnd, int id)
Definition: hotkey.c:611
BOOL FASTCALL UserRegisterHotKey(PWND pWnd, int id, UINT fsModifiers, UINT vk)
Definition: hotkey.c:451
static PHOT_KEY FASTCALL IsHotKey(UINT fsModifiers, WORD wVk)
Definition: hotkey.c:165
BOOL NTAPI co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
Definition: hotkey.c:191
BOOL APIENTRY NtUserRegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk)
Definition: hotkey.c:532
VOID FASTCALL StartDebugHotKeys(VOID)
Definition: hotkey.c:46
UINT FASTCALL DefWndGetHotKey(PWND pWnd)
Definition: hotkey.c:338
PHOT_KEY gphkFirst
Definition: hotkey.c:38
VOID FASTCALL UnregisterThreadHotKeys(PTHREADINFO pti)
Definition: hotkey.c:135
UINT gfsModOnlyCandidate
Definition: hotkey.c:39
static UCHAR IntSwapModHKF(UINT Input)
Definition: hotkey.c:94
#define IsWindowHotKey(pHK)
Definition: hotkey.c:43
static UINT FASTCALL IntGetModifiers(PBYTE pKeyState)
Definition: hotkey.c:68
VOID FASTCALL UnregisterWindowHotKeys(PWND pWnd)
Definition: hotkey.c:105
INT FASTCALL DefWndSetHotKey(PWND pWnd, WPARAM wParam)
Definition: hotkey.c:365
BOOL FASTCALL UserUnregisterHotKey(PWND pWnd, int id)
Definition: hotkey.c:499
KEYBOARD_ATTRIBUTES gKeyboardInfo
Definition: keyboard.c:17
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:98
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1395
BOOL FASTCALL UserPostThreadMessage(PTHREADINFO pti, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1358
#define USERTAG_HOTKEY
Definition: tags.h:238
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define ERROR_WINDOW_OF_OTHER_THREAD
Definition: winerror.h:889
#define ERROR_HOTKEY_ALREADY_REGISTERED
Definition: winerror.h:890
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define WM_SYSCOMMAND
Definition: winuser.h:1752
#define VK_F12
Definition: winuser.h:2277
#define VK_TAB
Definition: winuser.h:2210
#define MOD_WIN
Definition: winuser.h:2655
#define VK_SPACE
Definition: winuser.h:2230
#define VK_CONTROL
Definition: winuser.h:2214
#define SC_TASKLIST
Definition: winuser.h:2610
#define SC_HOTKEY
Definition: winuser.h:2612
#define VK_LWIN
Definition: winuser.h:2246
#define WM_HOTKEY
Definition: winuser.h:1890
#define VK_SHIFT
Definition: winuser.h:2213
#define WM_KEYDOWN
Definition: winuser.h:1726
#define VK_ESCAPE
Definition: winuser.h:2225
#define VK_RWIN
Definition: winuser.h:2247
#define VK_SUBTRACT
Definition: winuser.h:2263
#define VK_MENU
Definition: winuser.h:2215
unsigned char UCHAR
Definition: xmlstorage.h:181