Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

hotkeys.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

VOID SetDebugHotKeys ()
VOID DestroyThreadsHotKeys ()
VOID DestroyWindowsHotKeys (PWND pwnd)
BOOL _RegisterHotKey (PWND pwnd, int id, UINT fsModifiers, UINT vk)
BOOL _UnregisterHotKey (PWND pwnd, int id)
PHOTKEY FindHotKey (PTHREADINFO ptiCurrent, PWND pwnd, int id, UINT fsModifiers, UINT vk, BOOL fUnregister, PBOOL pfKeysExist)
BOOL IsSAS (BYTE vk, UINT *pfsModifiers)
BOOL xxxDoHotKeyStuff (UINT vk, BOOL fBreak, DWORD fsReserveKeys)
PHOTKEY IsHotKey (UINT fsModifiers, UINT vk)


Function Documentation

BOOL _RegisterHotKey PWND  pwnd,
int  id,
UINT  fsModifiers,
UINT  vk
 

Definition at line 125 of file hotkeys.c.

References BOOL, CheckWinstaWriteAttributesAccess(), FALSE, FindHotKey(), tagHOTKEY::fsModifiers, GETPTI, gfsSASModifiers, gpepCSRSS, gphkFirst, gpidLogon, grpWinStaList, gvkSAS, HOTKEY, tagHOTKEY::id, Lock, NULL, tagHOTKEY::phkNext, PsGetCurrentProcess, tagHOTKEY::pti, PtiCurrent, PWND_FOCUS, PWND_INPUTOWNER, tagHOTKEY::spwnd, TRUE, tagHOTKEY::vk, and tagHOTKEY::wFlags.

Referenced by NtUserRegisterHotKey(), RawInputThread(), SetDebugHotKeys(), and xxxSetShellWindow().

00130 { 00131 PHOTKEY phk; 00132 BOOL fKeysExist; 00133 PTHREADINFO ptiCurrent; 00134 BOOL bSAS = FALSE; 00135 WORD wFlags; 00136 00137 wFlags = fsModifiers & MOD_SAS; 00138 fsModifiers &= ~MOD_SAS; 00139 00140 ptiCurrent = PtiCurrent(); 00141 00142 /* 00143 * Blow it off if the caller is not the windowstation init thread 00144 * and doesn't have the proper access rights 00145 */ 00146 if (PsGetCurrentProcess() != gpepCSRSS) { 00147 if (grpWinStaList && !CheckWinstaWriteAttributesAccess()) { 00148 return FALSE; 00149 } 00150 } 00151 00152 /* 00153 * If VK_PACKET is specified, just bail out, since VK_PACKET is 00154 * not a real keyboard input. 00155 */ 00156 if (vk == VK_PACKET) { 00157 return FALSE; 00158 } 00159 00160 /* 00161 * If this is the SAS check that winlogon is the one registering it. 00162 */ 00163 if (wFlags & MOD_SAS) { 00164 if (PsGetCurrentProcess()->UniqueProcessId == gpidLogon) { 00165 bSAS = TRUE; 00166 } 00167 } 00168 00169 /* 00170 * Can't register hotkey for a window of another queue. 00171 * Return FALSE in this case. 00172 */ 00173 if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) { 00174 if (GETPTI(pwnd) != ptiCurrent) { 00175 RIPERR0(ERROR_WINDOW_OF_OTHER_THREAD, RIP_VERBOSE, ""); 00176 return FALSE; 00177 } 00178 } 00179 00180 phk = FindHotKey(ptiCurrent, pwnd, id, fsModifiers, vk, FALSE, &fKeysExist); 00181 00182 /* 00183 * If the keys have already been registered, return FALSE. 00184 */ 00185 if (fKeysExist) { 00186 RIPERR0(ERROR_HOTKEY_ALREADY_REGISTERED, RIP_WARNING, "Hotkey already exists"); 00187 return FALSE; 00188 } 00189 00190 if (phk == NULL) { 00191 /* 00192 * This hotkey doesn't exist yet. 00193 */ 00194 phk = (PHOTKEY)UserAllocPool(sizeof(HOTKEY), TAG_HOTKEY); 00195 00196 /* 00197 * If the allocation failed, bail out. 00198 */ 00199 if (phk == NULL) { 00200 return FALSE; 00201 } 00202 00203 phk->pti = ptiCurrent; 00204 00205 if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) { 00206 phk->spwnd = NULL; 00207 Lock(&phk->spwnd, pwnd); 00208 } else { 00209 phk->spwnd = pwnd; 00210 } 00211 phk->fsModifiers = (WORD)fsModifiers; 00212 phk->wFlags = wFlags; 00213 00214 phk->vk = vk; 00215 phk->id = id; 00216 00217 /* 00218 * Link the new hotkey to the front of the list. 00219 */ 00220 phk->phkNext = gphkFirst; 00221 gphkFirst = phk; 00222 00223 } else { 00224 00225 /* 00226 * Hotkey already exists, reset the keys. 00227 */ 00228 phk->fsModifiers = (WORD)fsModifiers; 00229 phk->wFlags = wFlags; 00230 phk->vk = vk; 00231 } 00232 00233 if (bSAS) { 00234 /* 00235 * store the SAS on the terminal. 00236 */ 00237 gvkSAS = vk; 00238 gfsSASModifiers = fsModifiers; 00239 } 00240 00241 return TRUE; 00242 }

BOOL _UnregisterHotKey PWND  pwnd,
int  id
 

Definition at line 255 of file hotkeys.c.

References BOOL, FALSE, FindHotKey(), NULL, PtiCurrent, and TRUE.

Referenced by NtUserUnregisterHotKey(), and SetDebugHotKeys().

00258 { 00259 PHOTKEY phk; 00260 BOOL fKeysExist; 00261 PTHREADINFO ptiCurrent = PtiCurrent(); 00262 phk = FindHotKey(ptiCurrent, pwnd, id, 0, 0, TRUE, &fKeysExist); 00263 00264 /* 00265 * No hotkey to unregister, return FALSE. 00266 */ 00267 if (phk == NULL) { 00268 RIPERR0(ERROR_HOTKEY_NOT_REGISTERED, RIP_VERBOSE, ""); 00269 return FALSE; 00270 } 00271 00272 return TRUE; 00273 }

VOID DestroyThreadsHotKeys  ) 
 

Definition at line 56 of file hotkeys.c.

References gphkFirst, tagHOTKEY::phkNext, PtiCurrent, PWND_FOCUS, PWND_INPUTOWNER, tagHOTKEY::spwnd, Unlock, and VOID().

Referenced by xxxDestroyThreadInfo().

00057 { 00058 PHOTKEY *pphk; 00059 PHOTKEY phk; 00060 PTHREADINFO ptiCurrent = PtiCurrent(); 00061 pphk = &gphkFirst; 00062 while (*pphk) { 00063 if ((*pphk)->pti == ptiCurrent) { 00064 phk = *pphk; 00065 *pphk = (*pphk)->phkNext; 00066 00067 /* 00068 * Unlock the object stored here. 00069 */ 00070 if ((phk->spwnd != PWND_FOCUS) && (phk->spwnd != PWND_INPUTOWNER)) { 00071 Unlock(&phk->spwnd); 00072 } 00073 00074 UserFreePool(phk); 00075 } else { 00076 pphk = &((*pphk)->phkNext); 00077 } 00078 } 00079 }

VOID DestroyWindowsHotKeys PWND  pwnd  ) 
 

Definition at line 93 of file hotkeys.c.

References gphkFirst, tagHOTKEY::phkNext, tagHOTKEY::spwnd, Unlock, and VOID().

Referenced by xxxFreeWindow().

00095 { 00096 PHOTKEY *pphk; 00097 PHOTKEY phk; 00098 pphk = &gphkFirst; 00099 while (*pphk) { 00100 if ((*pphk)->spwnd == pwnd) { 00101 phk = *pphk; 00102 *pphk = (*pphk)->phkNext; 00103 00104 Unlock(&phk->spwnd); 00105 UserFreePool(phk); 00106 } else { 00107 pphk = &((*pphk)->phkNext); 00108 } 00109 } 00110 }

PHOTKEY FindHotKey PTHREADINFO  ptiCurrent,
PWND  pwnd,
int  id,
UINT  fsModifiers,
UINT  vk,
BOOL  fUnregister,
PBOOL  pfKeysExist
 

Definition at line 290 of file hotkeys.c.

References FALSE, tagHOTKEY::fsModifiers, gphkFirst, tagHOTKEY::id, NULL, tagHOTKEY::phkNext, tagHOTKEY::pti, PWND_FOCUS, PWND_INPUTOWNER, tagHOTKEY::spwnd, TRUE, Unlock, and tagHOTKEY::vk.

Referenced by _RegisterHotKey(), and _UnregisterHotKey().

00298 { 00299 PHOTKEY phk, phkRet, phkPrev; 00300 00301 /* 00302 * Initialize out 'return' values. 00303 */ 00304 *pfKeysExist = FALSE; 00305 phkRet = NULL; 00306 00307 phk = gphkFirst; 00308 00309 while (phk) { 00310 00311 /* 00312 * If all this matches up then we've found it. 00313 */ 00314 if ((phk->pti == ptiCurrent) && (phk->spwnd == pwnd) && (phk->id == id)) { 00315 if (fUnregister) { 00316 00317 /* 00318 * Unlink the HOTKEY from the list. 00319 */ 00320 if (phk == gphkFirst) { 00321 gphkFirst = phk->phkNext; 00322 } else { 00323 phkPrev->phkNext = phk->phkNext; 00324 } 00325 00326 if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) { 00327 Unlock(&phk->spwnd); 00328 } 00329 UserFreePool((PVOID)phk); 00330 00331 return((PHOTKEY)1); 00332 } 00333 phkRet = phk; 00334 } 00335 00336 /* 00337 * If the key is already registered, set the exists flag so 00338 * the app knows it can't use this hotkey sequence. 00339 */ 00340 if ((phk->fsModifiers == (WORD)fsModifiers) && (phk->vk == vk)) { 00341 00342 /* 00343 * In the case of PWND_FOCUS, we need to check that the queues 00344 * are the same since PWND_FOCUS is local to the queue it was 00345 * registered under. 00346 */ 00347 if (phk->spwnd == PWND_FOCUS) { 00348 if (phk->pti == ptiCurrent) { 00349 *pfKeysExist = TRUE; 00350 } 00351 } else { 00352 *pfKeysExist = TRUE; 00353 } 00354 } 00355 00356 phkPrev = phk; 00357 phk = phk->phkNext; 00358 } 00359 00360 return phkRet; 00361 }

PHOTKEY IsHotKey UINT  fsModifiers,
UINT  vk
 

Definition at line 735 of file hotkeys.c.

References CheckCritIn, tagHOTKEY::fsModifiers, gphkFirst, NULL, tagHOTKEY::phkNext, and tagHOTKEY::vk.

Referenced by xxxDoHotKeyStuff(), and xxxKeyEvent().

00738 { 00739 PHOTKEY phk; 00740 00741 CheckCritIn(); 00742 00743 phk = gphkFirst; 00744 00745 while (phk != NULL) { 00746 00747 /* 00748 * Do the modifiers and vk for this hotkey match the current state? 00749 */ 00750 if ((phk->fsModifiers == fsModifiers) && (phk->vk == vk)) { 00751 return phk; 00752 } 00753 00754 phk = phk->phkNext; 00755 } 00756 00757 return NULL; 00758 }

BOOL IsSAS BYTE  vk,
UINT *  pfsModifiers
 

Definition at line 372 of file hotkeys.c.

References BOOL, CheckCritIn, FALSE, gfsSASModifiers, gfsSASModifiersDown, gvkSAS, TRUE, and UINT.

Referenced by xxxDoHotKeyStuff(), xxxKeyEvent(), and xxxNumpadCursor().

00375 { 00376 UINT fsDown = 0; 00377 00378 CheckCritIn(); 00379 00380 if (gvkSAS != vk) { 00381 return FALSE; 00382 } 00383 00384 /* 00385 * Special case for SAS - examine real physical modifier-key state! 00386 * 00387 * An evil daemon process can fool convincingly pretend to be winlogon 00388 * by registering Alt+Del as a hotkey, and spinning another thread that 00389 * continually calls keybd_event() to send the Ctrl key up: when the 00390 * user types Ctrl+Alt+Del, only Alt+Del will be seen by the system, 00391 * the evil daemon will get woken by WM_HOTKEY and can pretend to be 00392 * winlogon. So look at gfsSASModifiersDown in this case, to see what keys 00393 * were physically pressed. 00394 * NOTE: If hotkeys are ever made to work under journal playback, make 00395 * sure they don't affect the gfsSASModifiersDown! - IanJa. 00396 */ 00397 if (gfsSASModifiersDown == gfsSASModifiers) { 00398 *pfsModifiers = gfsSASModifiersDown; 00399 return TRUE; 00400 } 00401 00402 return FALSE; 00403 }

VOID SetDebugHotKeys  ) 
 

Definition at line 26 of file hotkeys.c.

References _RegisterHotKey(), _UnregisterHotKey(), FastGetProfileDwordW(), gKeyboardInfo, IDHOT_DEBUG, IDHOT_DEBUGSERVER, L, NULL, PMAP_AEDEBUG, PWND_INPUTOWNER, UINT, and VOID().

Referenced by ProcessDeviceChanges(), and RawInputThread().

00027 { 00028 UINT VkDebug; 00029 00030 VkDebug = FastGetProfileDwordW(NULL, PMAP_AEDEBUG, L"UserDebuggerHotkey", 0); 00031 if (VkDebug == 0) { 00032 if (ENHANCED_KEYBOARD(gKeyboardInfo.KeyboardIdentifier)) { 00033 VkDebug = VK_F12; 00034 } else { 00035 VkDebug = VK_SUBTRACT; 00036 } 00037 } else { 00038 UserAssert((0xFFFFFF00 & VkDebug) == 0); 00039 } 00040 00041 _UnregisterHotKey(PWND_INPUTOWNER, IDHOT_DEBUG); 00042 _UnregisterHotKey(PWND_INPUTOWNER, IDHOT_DEBUGSERVER); 00043 00044 _RegisterHotKey(PWND_INPUTOWNER, IDHOT_DEBUG, 0, VkDebug); 00045 _RegisterHotKey(PWND_INPUTOWNER, IDHOT_DEBUGSERVER, MOD_SHIFT, VkDebug); 00046 }

BOOL xxxDoHotKeyStuff UINT  vk,
BOOL  fBreak,
DWORD  fsReserveKeys
 

Definition at line 434 of file hotkeys.c.

References _PostMessage(), _PostThreadMessage(), BOOL, BYTE, CheckCritIn, tagWINDOWSTATION::dwWSF_Flags, FALSE, tagHOTKEY::fsModifiers, GETDESKINFO, GETPTI, gfInNumpadHexInput, ghwndSwitch, glinp, gpidLogon, gpqForeground, grpdeskRitInput, tagWND::head, tagHOTKEY::id, IDHOT_DEBUG, IDHOT_DEBUGSERVER, IDHOT_WINDOWS, IsHotKey(), IsSAS(), IsWinEventNotifyDeferredOK, NULL, NUMPAD_HEXMODE_LL, tagHOTKEY::pti, PtiCurrent, tagLASTINPUT::ptiLastWoken, PW, PWND_INPUTOWNER, tagDESKTOP::rpwinstaParent, tagHOTKEY::spwnd, tagQ::spwndFocus, ThreadLock, ThreadUnlock, TRUE, UINT, tagHOTKEY::wFlags, WSF_SWITCHLOCK, xxxActivateDebugger(), xxxSetForegroundWindow2(), and zzzCancelJournalling().

Referenced by xxxKeyEvent().

00438 { 00439 static UINT fsModifiers = 0; 00440 static UINT fsModOnlyCandidate = 0; 00441 UINT fsModOnlyHotkey; 00442 UINT fs; 00443 PHOTKEY phk; 00444 BOOL fCancel; 00445 BOOL fEatDebugKeyBreak = FALSE; 00446 PWND pwnd; 00447 BOOL bSAS; 00448 00449 CheckCritIn(); 00450 UserAssert(IsWinEventNotifyDeferredOK()); 00451 00452 if (gfInNumpadHexInput & NUMPAD_HEXMODE_LL) { 00453 RIPMSG0(RIP_VERBOSE, "xxxDoHotKeyStuff: Since we're in gfInNumpadHexInput, just bail out."); 00454 return FALSE; 00455 } 00456 00457 /* 00458 * Update fsModifiers. 00459 */ 00460 fs = 0; 00461 fsModOnlyHotkey = 0; 00462 00463 switch (vk) { 00464 case VK_SHIFT: 00465 fs = MOD_SHIFT; 00466 break; 00467 00468 case VK_CONTROL: 00469 fs = MOD_CONTROL; 00470 break; 00471 00472 case VK_MENU: 00473 fs = MOD_ALT; 00474 break; 00475 00476 case VK_LWIN: 00477 case VK_RWIN: 00478 fs = MOD_WIN; 00479 break; 00480 00481 default: 00482 /* 00483 * A non-modifier key rules out Modifier-Only hotkeys 00484 */ 00485 fsModOnlyCandidate = 0; 00486 break; 00487 } 00488 00489 if (fBreak) { 00490 fsModifiers &= ~fs; 00491 /* 00492 * If a modifier key is coming up, the current modifier only hotkey 00493 * candidate must be tested to see if it is a hotkey. Store this 00494 * in fsModOnlyHotkey, and prevent the next key release from 00495 * being a candidate by clearing fsModOnlyCandidate. 00496 */ 00497 if (fs != 0) { 00498 fsModOnlyHotkey = fsModOnlyCandidate; 00499 fsModOnlyCandidate = 0; 00500 } 00501 } else { 00502 fsModifiers |= fs; 00503 /* 00504 * If a modifier key is going down, we have a modifier-only hotkey 00505 * candidate. Save current modifier state until the following break. 00506 */ 00507 if (fs != 0) { 00508 fsModOnlyCandidate = fsModifiers; 00509 } 00510 } 00511 00512 /* 00513 * We look at the physical state for the modifiers because they can not be 00514 * manipulated and this prevents someone from writing a trojan winlogon look alike. 00515 * (See comment in AreModifiersIndicatingSAS) 00516 */ 00517 bSAS = IsSAS((BYTE)vk, &fsModifiers); 00518 00519 /* 00520 * If the key is not a hotkey then we're done but first check if the 00521 * key is an Alt-Escape if so we need to cancel journalling. 00522 * 00523 * NOTE: Support for Alt+Esc to cancel journalling dropped in NT 4.0 00524 */ 00525 if (fsModOnlyHotkey && fBreak) { 00526 /* 00527 * A hotkey involving only VK_SHIFT, VK_CONTROL, VK_MENU or VK_WINDOWS 00528 * must only operate on a key release. 00529 */ 00530 if ((phk = IsHotKey(fsModOnlyHotkey, VK_NONE)) == NULL) { 00531 return FALSE; 00532 } 00533 } else if ((phk = IsHotKey(fsModifiers, vk)) == NULL) { 00534 return FALSE; 00535 } 00536 00537 /* 00538 * If we tripped a SAS hotkey, but it's not really the SAS, don't do it. 00539 */ 00540 if ((phk->wFlags & MOD_SAS) && !bSAS) { 00541 return FALSE; 00542 00543 } 00544 if (phk->id == IDHOT_WINDOWS) { 00545 pwnd = GETDESKINFO(PtiCurrent())->spwndShell; 00546 if (pwnd != NULL) { 00547 fsModOnlyCandidate = 0; /* Make it return TRUE */ 00548 goto PostTaskListSysCmd; 00549 } 00550 } 00551 00552 if ((phk->id == IDHOT_DEBUG) || (phk->id == IDHOT_DEBUGSERVER)) { 00553 00554 if (!fBreak) { 00555 /* 00556 * The DEBUG key has been pressed. Break the appropriate 00557 * thread into the debugger. Won't need phk after this callback 00558 * because we return immediately. 00559 */ 00560 fEatDebugKeyBreak = xxxActivateDebugger(phk->fsModifiers); 00561 } 00562 00563 /* 00564 * This'll eat the debug key down and break if we broke into 00565 * the debugger on the server only on the down. 00566 */ 00567 return fEatDebugKeyBreak; 00568 } 00569 00570 /* 00571 * don't allow hotkeys(except for ones owned by the logon process) 00572 * if the window station is locked. 00573 */ 00574 00575 if (((grpdeskRitInput->rpwinstaParent->dwWSF_Flags & WSF_SWITCHLOCK) != 0) && 00576 (phk->pti->pEThread->Cid.UniqueProcess != gpidLogon)) { 00577 RIPMSG0(RIP_WARNING, "Ignoring hotkey because Workstation locked"); 00578 return FALSE; 00579 } 00580 00581 if ((fsModOnlyHotkey == 0) && fBreak) { 00582 /* 00583 * Do Modifier-Only hotkeys on break events, else return here. 00584 */ 00585 return FALSE; 00586 } 00587 00588 /* 00589 * Unhook hooks if a control-escape, alt-escape, or control-alt-del 00590 * comes through, so the user can cancel if the system seems hung. 00591 * 00592 * Note the hook may be locked so even if the unhook succeeds it 00593 * won't remove the hook from the global asphkStart array. So 00594 * we have to walk the list manually. This code works because 00595 * we are in the critical section and we know other hooks won't 00596 * be deleted. 00597 * 00598 * Once we've unhooked, post a WM_CANCELJOURNAL message to the app 00599 * that set the hook so it knows we did this. 00600 * 00601 * NOTE: Support for Alt+Esc to cancel journalling dropped in NT 4.0 00602 */ 00603 fCancel = FALSE; 00604 if (vk == VK_ESCAPE && (fsModifiers == MOD_CONTROL)) { 00605 fCancel = TRUE; 00606 } 00607 00608 if (bSAS) { 00609 fCancel = TRUE; 00610 } 00611 00612 if (fCancel) 00613 zzzCancelJournalling(); // BUG BUG phk might go away IANJA 00614 00615 /* 00616 * See if the key is reserved by a console window. If it is, 00617 * return FALSE so the key will be passed to the console. 00618 */ 00619 if (fsReserveKeys != 0) { 00620 switch (vk) { 00621 case VK_TAB: 00622 if ((fsReserveKeys & CONSOLE_ALTTAB) && 00623 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) { 00624 return FALSE; 00625 } 00626 break; 00627 case VK_ESCAPE: 00628 if ((fsReserveKeys & CONSOLE_ALTESC) && 00629 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) { 00630 return FALSE; 00631 } 00632 if ((fsReserveKeys & CONSOLE_CTRLESC) && 00633 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_CONTROL)) { 00634 return FALSE; 00635 } 00636 break; 00637 case VK_RETURN: 00638 if ((fsReserveKeys & CONSOLE_ALTENTER) && 00639 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) { 00640 return FALSE; 00641 } 00642 break; 00643 case VK_SNAPSHOT: 00644 if ((fsReserveKeys & CONSOLE_PRTSC) && 00645 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == 0)) { 00646 return FALSE; 00647 } 00648 if ((fsReserveKeys & CONSOLE_ALTPRTSC) && 00649 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) { 00650 return FALSE; 00651 } 00652 break; 00653 case VK_SPACE: 00654 if ((fsReserveKeys & CONSOLE_ALTSPACE) && 00655 ((fsModifiers & (MOD_CONTROL | MOD_ALT)) == MOD_ALT)) { 00656 return FALSE; 00657 } 00658 break; 00659 } 00660 } 00661 00662 /* 00663 * If this is the task-list hotkey, go ahead and set foreground 00664 * status to the task-list queue right now. This prevents problems 00665 * where the user hits ctrl-esc and types-ahead before the task-list 00666 * processes the hotkey and brings up the task-list window. 00667 */ 00668 if ((fsModifiers == MOD_CONTROL) && (vk == VK_ESCAPE) && !fBreak) { 00669 PWND pwndSwitch; 00670 TL tlpwndSwitch; 00671 00672 if (ghwndSwitch != NULL) { 00673 pwndSwitch = PW(ghwndSwitch); 00674 ThreadLock(pwndSwitch, &tlpwndSwitch); 00675 xxxSetForegroundWindow2(pwndSwitch, NULL, 0); // BUG BUG phk might go away IANJA 00676 ThreadUnlock(&tlpwndSwitch); 00677 } 00678 } 00679 00680 /* 00681 * Get the hot key contents. 00682 */ 00683 if (phk->spwnd == NULL) { 00684 _PostThreadMessage( 00685 phk->pti, WM_HOTKEY, phk->id, 00686 MAKELONG(fsModifiers, vk)); 00687 /* 00688 * Since this hotkey is for this guy, he owns the last input. 00689 */ 00690 glinp.ptiLastWoken = phk->pti; 00691 00692 } else { 00693 if (phk->spwnd == PWND_INPUTOWNER) { 00694 if (gpqForeground != NULL) { 00695 pwnd = gpqForeground->spwndFocus; 00696 } else { 00697 return FALSE; 00698 } 00699 } else { 00700 pwnd = phk->spwnd; 00701 } 00702 00703 if (pwnd) { 00704 if (pwnd == pwnd->head.rpdesk->pDeskInfo->spwndShell && phk->id == SC_TASKLIST) { 00705 PostTaskListSysCmd: 00706 _PostMessage(pwnd, WM_SYSCOMMAND, SC_TASKLIST, 0); 00707 } else { 00708 _PostMessage(pwnd, WM_HOTKEY, phk->id, MAKELONG(fsModifiers, vk)); 00709 } 00710 00711 /* 00712 * Since this hotkey is for this guy, he owns the last input. 00713 */ 00714 glinp.ptiLastWoken = GETPTI(pwnd); 00715 } 00716 } 00717 00718 /* 00719 * If this is a Modifier-Only hotkey, let the modifier break through 00720 * by returning FALSE, otherwise we will have modifier keys stuck down. 00721 */ 00722 return (fsModOnlyHotkey == 0); 00723 00724 }


Generated on Sat May 15 19:44:06 2004 for test by doxygen 1.3.7