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

mnaccel.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define TA_DISABLED   1

Functions

int ItemContainingSubMenu (PMENU pmainMenu, ULONG_PTR wID)
int UT_FindTopLevelMenuIndex (PMENU pMenu, UINT cmd)
BOOL xxxHiliteMenuItem (PWND pwnd, PMENU pMenu, UINT cmd, UINT flags)
UINT xxxTA_AccelerateMenu (PWND pwnd, PMENU pMenu, UINT cmd, HMENU *phmenuInit)
HANDLE APIENTRY _CreateAcceleratorTable (LPACCEL ccxpaccel, int cbAccel)
int xxxTranslateAccelerator (PWND pwnd, LPACCELTABLE pat, LPMSG lpMsg)
UINT SystoChar (UINT message, LPARAM lParam)


Define Documentation

#define TA_DISABLED   1
 

Definition at line 143 of file mnaccel.c.

Referenced by xxxTA_AccelerateMenu(), and xxxTranslateAccelerator().


Function Documentation

HANDLE _CreateAcceleratorTable LPACCEL  paccel,
int  cbAccel
 

Definition at line 217 of file mnaccel.c.

References tagACCELTABLE::accel, APIENTRY, tagACCELTABLE::cAccel, FALSE, FLASTKEY, HMAllocObject(), HMFreeObject(), LPACCELTABLE, NULL, PtiCurrent, and TYPE_ACCELTABLE.

Referenced by NtUserCreateAcceleratorTable().

00220 { 00221 LPACCELTABLE pat; 00222 int size; 00223 00224 size = cbAccel + sizeof(ACCELTABLE) - sizeof(ACCEL); 00225 00226 pat = (LPACCELTABLE)HMAllocObject(PtiCurrent(), NULL, TYPE_ACCELTABLE, size); 00227 if (pat == NULL) 00228 return NULL; 00229 00230 try { 00231 RtlCopyMemory(pat->accel, ccxpaccel, cbAccel); 00232 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00233 HMFreeObject(pat); 00234 return NULL; 00235 } 00236 00237 pat->cAccel = cbAccel / sizeof(ACCEL); 00238 pat->accel[pat->cAccel - 1].fVirt |= FLASTKEY; 00239 00240 return pat; 00241 }

int ItemContainingSubMenu PMENU  pmainMenu,
ULONG_PTR  wID
 

Definition at line 22 of file mnaccel.c.

References tagMENU::cItems, NULL, tagMENU::rgItems, tagITEM::spSubMenu, and tagITEM::wID.

Referenced by UT_FindTopLevelMenuIndex().

00025 { 00026 int i; 00027 PITEM pItem; 00028 00029 if ((i = pmainMenu->cItems - 1) == -1) 00030 return -1; 00031 00032 pItem = &pmainMenu->rgItems[i]; 00033 00034 /* 00035 * Scan through mainMenu's items (bottom up) until an item is found 00036 * that either has subMenu or an ancestor of subMenu as it's drop 00037 * down menu 00038 */ 00039 00040 /* 00041 * Make sure this works for new apps that set IDs for popup items that 00042 * aren't the same as the HMENU_16 value of the submenu. Accelerators 00043 * for disabled items will get generated otherwise, like in Exchange. 00044 */ 00045 while (i >= 0) 00046 { 00047 if (pItem->spSubMenu == NULL) 00048 { 00049 // 00050 // Does this command match? 00051 // 00052 if (pItem->wID == wID) 00053 break; 00054 } 00055 else 00056 { 00057 // 00058 // Does this popup match? 00059 // 00060 if (pItem->spSubMenu == (PMENU)wID) 00061 break; 00062 00063 // 00064 // Go recurse through this popup and see if we have a match on 00065 // one of our children. 00066 // 00067 if (ItemContainingSubMenu(pItem->spSubMenu, wID) != -1) 00068 break; 00069 } 00070 00071 i--; 00072 pItem--; 00073 } 00074 00075 return i; 00076 }

UINT SystoChar UINT  message,
LPARAM  lParam
 

Definition at line 461 of file mnaccel.c.

References CheckMsgFilter, SYS_ALTERNATE, and UINT.

Referenced by xxxSBTrackLoop(), and xxxTranslateAccelerator().

00464 { 00465 if (CheckMsgFilter(message, WM_SYSKEYDOWN, WM_SYSDEADCHAR) && 00466 !(HIWORD(lParam) & SYS_ALTERNATE)) 00467 return (message - (WM_SYSKEYDOWN - WM_KEYDOWN)); 00468 00469 return message; 00470 }

int UT_FindTopLevelMenuIndex PMENU  pMenu,
UINT  cmd
 

Definition at line 86 of file mnaccel.c.

References FALSE, ItemContainingSubMenu(), MNLookUpItem(), NULL, and tagITEM::spSubMenu.

Referenced by xxxHiliteMenuItem(), and xxxTA_AccelerateMenu().

00089 { 00090 PMENU pMenuItemIsOn; 00091 PITEM pItem; 00092 00093 /* 00094 * Get a pointer to the item we are searching for. 00095 */ 00096 pItem = MNLookUpItem(pMenu, cmd, FALSE, &pMenuItemIsOn); 00097 if ((pItem == NULL) || (pItem->spSubMenu != NULL)) 00098 return(-1); 00099 00100 /* 00101 * We want to search for the item that contains pMenuItemIsOn, 00102 * unless this is a top-level item without a dropdown, in which 00103 * case we want to search for cmd. 00104 */ 00105 return ItemContainingSubMenu(pMenu, 00106 pMenuItemIsOn != pMenu ? (ULONG_PTR)pMenuItemIsOn : cmd); 00107 }

BOOL xxxHiliteMenuItem PWND  pwnd,
PMENU  pMenu,
UINT  cmd,
UINT  flags
 

Definition at line 117 of file mnaccel.c.

References BOOL, MFISPOPUP, NULL, TestMF, TRUE, UINT, UT_FindTopLevelMenuIndex(), xxxMNInvertItem(), and xxxMNRecomputeBarIfNeeded().

Referenced by NtUserHiliteMenuItem().

00122 { 00123 00124 if (!(flags & MF_BYPOSITION)) 00125 cmd = (UINT)UT_FindTopLevelMenuIndex(pMenu, cmd); 00126 00127 if (!TestMF(pMenu, MFISPOPUP)) 00128 xxxMNRecomputeBarIfNeeded(pwnd, pMenu); 00129 00130 xxxMNInvertItem(NULL, pMenu, cmd, pwnd, (flags & MF_HILITE)); 00131 00132 return TRUE; 00133 }

UINT xxxTA_AccelerateMenu PWND  pwnd,
PMENU  pMenu,
UINT  cmd,
HMENU *  phmenuInit
 

Definition at line 145 of file mnaccel.c.

References BOOL, CheckLock, DWORD, FALSE, L, MNLookUpItem(), NULL, PtoHq, tagITEM::spSubMenu, TA_DISABLED, TestMFS, UINT, UT_FindTopLevelMenuIndex(), and xxxSendMessage().

Referenced by xxxTranslateAccelerator().

00150 { 00151 int i; 00152 PITEM pItem; 00153 BOOL fDisabledTop; 00154 BOOL fDisabled; 00155 UINT rgfItem; 00156 PMENU pMenuItemIsOn; 00157 00158 CheckLock(pwnd); 00159 CheckLock(pMenu); 00160 00161 rgfItem = 0; 00162 if (pMenu != NULL) { 00163 if ((i = UT_FindTopLevelMenuIndex(pMenu, cmd)) != -1) { 00164 00165 /* 00166 * 2 means we found an item 00167 */ 00168 rgfItem = 2; 00169 00170 xxxSendMessage(pwnd, WM_INITMENU, (WPARAM)PtoHq(pMenu), 0L); 00171 if ((UINT)i >= pMenu->cItems) 00172 return 0; 00173 00174 pItem = &pMenu->rgItems[i]; 00175 if (pItem->spSubMenu != NULL) { 00176 *phmenuInit = PtoHq(pItem->spSubMenu); 00177 xxxSendMessage(pwnd, WM_INITMENUPOPUP, (WPARAM)*phmenuInit, 00178 (DWORD)i); 00179 if ((UINT)i >= pMenu->cItems) 00180 return 0; 00181 fDisabledTop = TestMFS(pItem,MFS_GRAYED); 00182 } else { 00183 fDisabledTop = FALSE; 00184 } 00185 00186 pItem = MNLookUpItem(pMenu, cmd, FALSE, &pMenuItemIsOn); 00187 00188 /* 00189 * If the item was removed by the app in response to either of 00190 * the above messages, pItem will be NULL. 00191 */ 00192 if (pItem == NULL) { 00193 rgfItem = 0; 00194 } else { 00195 fDisabled = TestMFS(pItem,MFS_GRAYED); 00196 00197 /* 00198 * This 1 bit means it's disabled or it's 'parent' is disabled. 00199 */ 00200 if (fDisabled || fDisabledTop) 00201 rgfItem |= TA_DISABLED; 00202 } 00203 } 00204 } 00205 00206 return rgfItem; 00207 }

int xxxTranslateAccelerator PWND  pwnd,
LPACCELTABLE  pat,
LPMSG  lpMsg
 

Definition at line 251 of file mnaccel.c.

References _GetKeyState(), tagACCELTABLE::accel, BOOL, CheckLock, DWORD, FALSE, FLASTKEY, gfInNumpadHexInput, tagWND::head, ID_SYSMENU, NULL, NUMPAD_HEXMODE_HL, PtiCurrent, tagWND::spmenu, tagWND::spmenuSys, SystoChar(), TA_DISABLED, TestWF, ThreadLock, ThreadUnlock, TRUE, UINT, WFCHILD, WFDISABLED, WFICONIC, WFSYSMENU, xxxLoadSysDesktopMenu(), xxxSendMessage(), xxxSetSysMenu(), and xxxTA_AccelerateMenu().

Referenced by NtUserTranslateAccelerator().

00255 { 00256 UINT cmd; 00257 BOOL fVirt; 00258 PMENU pMenu; 00259 BOOL fFound; 00260 UINT flags; 00261 UINT keystate; 00262 UINT message; 00263 UINT rgfItem; 00264 BOOL fDisabled; 00265 BOOL fSystemMenu; 00266 LPACCEL paccel; 00267 TL tlpMenu; 00268 int vkAlt, vkCtrl; 00269 HMENU hmenuInit = NULL; 00270 00271 CheckLock(pwnd); 00272 CheckLock(pat); 00273 00274 if (gfInNumpadHexInput & NUMPAD_HEXMODE_HL) { 00275 return FALSE; 00276 } 00277 00278 paccel = pat->accel; 00279 00280 fFound = FALSE; 00281 00282 message = SystoChar(lpMsg->message, lpMsg->lParam); 00283 00284 switch (message) { 00285 case WM_KEYDOWN: 00286 case WM_SYSKEYDOWN: 00287 fVirt = TRUE; 00288 break; 00289 00290 case WM_CHAR: 00291 case WM_SYSCHAR: 00292 fVirt = FALSE; 00293 break; 00294 00295 default: 00296 return FALSE; 00297 } 00298 00299 /* 00300 * Many kbd layouts use the r.h. Alt key like a shift key to generate some 00301 * additional chars: this r.h. Alt (or "AltGr") key synthesizes a left Ctrl 00302 * (for backward compatibility with 84-key kbds), so when the AltGr key is 00303 * down neither the left Ctrl nor the right Alt should be counted as part 00304 * of the keystate. 00305 * Note: Don't expect spklActive == NULL (winlogon should have loaded kbd 00306 * layouts already), but test it anyway to be robust. #99321) 00307 */ 00308 keystate = 0; 00309 UserAssert(PtiCurrent()->spklActive != NULL); // #99321 00310 if (PtiCurrent()->spklActive && 00311 (PtiCurrent()->spklActive->spkf->pKbdTbl->fLocaleFlags & KLLF_ALTGR) && 00312 (_GetKeyState(VK_RMENU) & 0x8000)) { 00313 /* 00314 * count only right hand Ctrl as a Ctrl keystate 00315 * count only left hand Alt as a Alt keystate 00316 */ 00317 vkCtrl = VK_RCONTROL; 00318 vkAlt = VK_LMENU; 00319 } else { 00320 /* 00321 * count left or right hand Ctrl as a Ctrl keystate 00322 * count left or right hand Alt as a Alt keystate 00323 */ 00324 vkAlt = VK_MENU; 00325 vkCtrl = VK_CONTROL; 00326 } 00327 00328 if (_GetKeyState(vkCtrl) & 0x8000) { 00329 keystate |= FCONTROL; 00330 } 00331 if (_GetKeyState(vkAlt) & 0x8000) { 00332 keystate |= FALT; 00333 } 00334 if (_GetKeyState(VK_SHIFT) & 0x8000) { 00335 keystate |= FSHIFT; 00336 } 00337 00338 do 00339 { 00340 flags = paccel->fVirt; 00341 if ( (DWORD)paccel->key != lpMsg->wParam || 00342 ((fVirt != 0) != ((flags & FVIRTKEY) != 0))) { 00343 goto Next; 00344 } 00345 00346 if (fVirt && ((keystate & (FSHIFT | FCONTROL)) != (flags & (FSHIFT | FCONTROL)))) { 00347 goto Next; 00348 } 00349 00350 if ((keystate & FALT) != (flags & FALT)) { 00351 goto Next; 00352 } 00353 00354 fFound = TRUE; 00355 fSystemMenu = 0; 00356 rgfItem = 0; 00357 00358 cmd = paccel->cmd; 00359 if (cmd != 0) { 00360 00361 /* 00362 * The order of these next two if's is important for default 00363 * situations. Also, just check accelerators in the system 00364 * menu of child windows passed to TranslateAccelerator. 00365 */ 00366 pMenu = pwnd->spmenu; 00367 rgfItem = 0; 00368 00369 if (!TestWF(pwnd, WFCHILD)) { 00370 ThreadLock(pMenu, &tlpMenu); 00371 rgfItem = xxxTA_AccelerateMenu(pwnd, pMenu, cmd, &hmenuInit); 00372 ThreadUnlock(&tlpMenu); 00373 } 00374 00375 if (TestWF(pwnd, WFCHILD) || rgfItem == 0) { 00376 UserAssert(hmenuInit == NULL); 00377 pMenu = pwnd->spmenuSys; 00378 if (pMenu == NULL && TestWF(pwnd, WFSYSMENU)) { 00379 00380 /* 00381 * Change owner so this app can access this menu. 00382 */ 00383 pMenu = pwnd->head.rpdesk->spmenuSys; 00384 if (pMenu == NULL) { 00385 pMenu = xxxLoadSysDesktopMenu (&pwnd->head.rpdesk->spmenuSys, ID_SYSMENU); 00386 } 00387 ThreadLock(pMenu, &tlpMenu); 00388 /* 00389 * Must reset the system menu for this window. 00390 */ 00391 xxxSetSysMenu(pwnd); 00392 } else { 00393 ThreadLock(pMenu, &tlpMenu); 00394 } 00395 00396 if ((rgfItem = xxxTA_AccelerateMenu(pwnd, pMenu, cmd, &hmenuInit)) != 0) { 00397 fSystemMenu = TRUE; 00398 } 00399 ThreadUnlock(&tlpMenu); 00400 } 00401 } 00402 00403 fDisabled = TestWF(pwnd, WFDISABLED); 00404 00405 /* 00406 * Send only if: 1. The Item is not disabled, AND 00407 * 2. The Window's not being captured AND 00408 * 3. The Window's not minimzed, OR 00409 * 4. The Window's minimized but the Item is in 00410 * the System Menu. 00411 */ 00412 if (!(rgfItem & TA_DISABLED) && 00413 !(rgfItem && TestWF(pwnd, WFICONIC) && !fSystemMenu)) { 00414 if (!(rgfItem != 0 && (PtiCurrent()->pq->spwndCapture != NULL || 00415 fDisabled))) { 00416 00417 if (fSystemMenu) { 00418 xxxSendMessage(pwnd, WM_SYSCOMMAND, cmd, 0x00010000L); 00419 } else { 00420 xxxSendMessage(pwnd, WM_COMMAND, MAKELONG(cmd, 1), 0); 00421 } 00422 00423 /* 00424 * Get outta here 00425 */ 00426 flags = FLASTKEY; 00427 } 00428 } 00429 00430 /* 00431 * Send matching WM_UNINITMENUPOPUP if needed 00432 */ 00433 if (hmenuInit != NULL) { 00434 xxxSendMessage(pwnd, WM_UNINITMENUPOPUP, (WPARAM)hmenuInit, 0); 00435 hmenuInit = NULL; 00436 } 00437 00438 Next: 00439 paccel++; 00440 00441 } while (!(flags & FLASTKEY) && !fFound); 00442 00443 00444 return fFound; 00445 }


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