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

mnstate.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

PMENU xxxGetInitMenuParam (PWND pwndMenu, BOOL *lpfSystem)
void MNPositionSysMenu (PWND pwnd, PMENU pmenusys)
void MNFlushDestroyedPopups (PPOPUPMENU ppopupmenu, BOOL fUnlock)
PPOPUPMENU MNAllocPopup (BOOL fForceAlloc)
VOID MNFreePopup (PPOPUPMENU ppopupmenu)
BOOL MNEndMenuStateNotify (PMENUSTATE pMenuState)
void xxxMNEndMenuState (BOOL fFreePopup)
BOOL MNCreateAnimationBitmap (PMENUSTATE pMenuState, UINT cx, UINT cy)
void MNDestroyAnimationBitmap (PMENUSTATE pMenuState)
BOOL MNSetupAnimationDC (PMENUSTATE pMenuState)
BOOL xxxUnlockMenuState (PMENUSTATE pMenuState)
PMENUSTATE xxxMNAllocMenuState (PTHREADINFO ptiCurrent, PTHREADINFO ptiNotify, PPOPUPMENU ppopupmenuRoot)
PMENUSTATE xxxMNStartMenuState (PWND pwnd, DWORD cmd, LPARAM lParam)
BOOL xxxMNStartMenu (PPOPUPMENU ppopupmenu, int mn)


Function Documentation

PPOPUPMENU MNAllocPopup BOOL  fForceAlloc  ) 
 

Definition at line 143 of file mnstate.c.

References gpopupMenu, PUDF_POPUPINUSE, SET_PUDF, and TEST_PUDF.

Referenced by xxxMenuWindowProc(), and xxxMNStartMenuState().

00144 { 00145 PPOPUPMENU ppm; 00146 if (!fForceAlloc && !TEST_PUDF(PUDF_POPUPINUSE)) { 00147 SET_PUDF(PUDF_POPUPINUSE); 00148 00149 ppm = &gpopupMenu; 00150 } else { 00151 ppm = (PPOPUPMENU)UserAllocPoolWithQuota(sizeof(POPUPMENU), TAG_POPUPMENU); 00152 } 00153 00154 if (ppm) { 00155 RtlZeroMemory(ppm, sizeof(POPUPMENU)); 00156 } 00157 00158 return (ppm); 00159 }

BOOL MNCreateAnimationBitmap PMENUSTATE  pMenuState,
UINT  cx,
UINT  cy
 

Definition at line 389 of file mnstate.c.

References BOOL, cy, FALSE, gpDispInfo, tagMENUSTATE::hbmAni, tagDISPLAYINFO::hdcScreen, NULL, and TRUE.

Referenced by xxxMenuWindowProc().

00390 { 00391 HBITMAP hbm = GreCreateCompatibleBitmap(gpDispInfo->hdcScreen, cx, cy); 00392 if (hbm == NULL) { 00393 RIPMSG0(RIP_WARNING, "MNSetupAnimationBitmap: Failed to create hbmAni"); 00394 return FALSE; 00395 } 00396 00397 #if DBG 00398 if (pMenuState->hdcAni == NULL) { 00399 RIPMSG0(RIP_WARNING, "MNCreateAnimationBitmap: hdcAni is NULL"); 00400 } 00401 if (pMenuState->hbmAni != NULL) { 00402 RIPMSG0(RIP_WARNING, "MNCreateAnimationBitmap: hbmAni already exists"); 00403 } 00404 #endif 00405 00406 GreSelectBitmap(pMenuState->hdcAni, hbm); 00407 pMenuState->hbmAni = hbm; 00408 return TRUE; 00409 }

void MNDestroyAnimationBitmap PMENUSTATE  pMenuState  ) 
 

Definition at line 414 of file mnstate.c.

References tagMENUSTATE::hbmAni, and NULL.

Referenced by MNAnimate(), and xxxMNEndMenuState().

00415 { 00416 GreSelectBitmap(pMenuState->hdcAni, GreGetStockObject(PRIV_STOCK_BITMAP)); 00417 UserVerify(GreDeleteObject(pMenuState->hbmAni)); 00418 pMenuState->hbmAni = NULL; 00419 }

BOOL MNEndMenuStateNotify PMENUSTATE  pMenuState  ) 
 

Definition at line 234 of file mnstate.c.

References BOOL, FALSE, GETPTI, NULL, tagMENUSTATE::pGlobalPopupMenu, tagTHREADINFO::pMenuState, tagMENUSTATE::pmnsPrev, tagMENUSTATE::ptiMenuStateOwner, tagPOPUPMENU::spwndNotify, and TRUE.

Referenced by xxxDestroyWindow(), and xxxMNEndMenuState().

00235 { 00236 PTHREADINFO ptiNotify; 00237 00238 if (pMenuState->pGlobalPopupMenu->spwndNotify != NULL) { 00239 ptiNotify = GETPTI(pMenuState->pGlobalPopupMenu->spwndNotify); 00240 if (ptiNotify != pMenuState->ptiMenuStateOwner) { 00241 /* 00242 * Later5.0 GerardoB. xxxMNStartMenuState no longer allows this. 00243 * This is dead code that I'll remove eventually 00244 */ 00245 UserAssert(ptiNotify == pMenuState->ptiMenuStateOwner); 00246 00247 UserAssert(ptiNotify->pMenuState == pMenuState); 00248 UserAssert(pMenuState->pmnsPrev == NULL); 00249 ptiNotify->pMenuState = NULL; 00250 return TRUE; 00251 } 00252 } 00253 00254 return FALSE; 00255 }

void MNFlushDestroyedPopups PPOPUPMENU  ppopupmenu,
BOOL  fUnlock
 

Definition at line 91 of file mnstate.c.

References FALSE, tagPOPUPMENU::fDelayedFree, tagPOPUPMENU::fDestroyed, IsRootPopupMenu(), MNFreePopup(), NULL, tagPOPUPMENU::ppmDelayedFree, and tagPOPUPMENU::ppopupmenuRoot.

Referenced by MNFreePopup(), and xxxMNLoop().

00092 { 00093 PPOPUPMENU ppmDestroyed, ppmFree; 00094 00095 UserAssert(IsRootPopupMenu(ppopupmenu)); 00096 00097 /* 00098 * Walk ppmDelayedFree 00099 */ 00100 ppmDestroyed = ppopupmenu; 00101 while (ppmDestroyed->ppmDelayedFree != NULL) { 00102 /* 00103 * If it's marked as destroyed, unlink it and free it 00104 */ 00105 if (ppmDestroyed->ppmDelayedFree->fDestroyed) { 00106 ppmFree = ppmDestroyed->ppmDelayedFree; 00107 ppmDestroyed->ppmDelayedFree = ppmFree->ppmDelayedFree; 00108 UserAssert(ppmFree != ppmFree->ppopupmenuRoot); 00109 MNFreePopup(ppmFree); 00110 } else { 00111 /* 00112 * fUnlock is TRUE if the root popup is being destroyed; if 00113 * so, reset fDelayedFree and unlink it 00114 */ 00115 if (fUnlock) { 00116 /* 00117 * This means that the root popup is going away before 00118 * some of the hierarchical popups have been destroyed. 00119 * This can happen if someone destroys one of the menu 00120 * windows breaking the spwndNextPopup chain. 00121 */ 00122 ppmDestroyed->ppmDelayedFree->fDelayedFree = FALSE; 00123 /* 00124 * Stop here so we can figure how this happened. 00125 */ 00126 UserAssert(ppmDestroyed->ppmDelayedFree->fDelayedFree); 00127 ppmDestroyed->ppmDelayedFree = ppmDestroyed->ppmDelayedFree->ppmDelayedFree; 00128 } else { 00129 /* 00130 * Not fDestroyed so move to the next one. 00131 */ 00132 ppmDestroyed = ppmDestroyed->ppmDelayedFree; 00133 } /* fUnlock */ 00134 } /* fDestroyed */ 00135 } /* while ppmDelayedFree */ 00136 00137 }

VOID MNFreePopup PPOPUPMENU  ppopupmenu  ) 
 

Definition at line 165 of file mnstate.c.

References CLEAR_PUDF, DF_MENUINUSE, tagDESKTOP::dwDTFlags, tagPOPUPMENU::fDesktopMenu, tagPOPUPMENU::fFreed, tagPOPUPMENU::fIsMenuBar, FNID_MENU, GETFNID, gpopupMenu, IsRootPopupMenu(), MNFlushDestroyedPopups(), NULL, tagPOPUPMENU::ppopupmenuRoot, PtiCurrent, PUDF_POPUPINUSE, tagPOPUPMENU::spmenu, tagPOPUPMENU::spmenuAlternate, tagPOPUPMENU::spwndActivePopup, tagDESKTOP::spwndMenu, tagPOPUPMENU::spwndNextPopup, tagPOPUPMENU::spwndNotify, tagPOPUPMENU::spwndPopupMenu, tagPOPUPMENU::spwndPrevPopup, TEST_PUDF, TRUE, Unlock, UnlockPopupMenu(), Validateppopupmenu, and VOID().

Referenced by MNFlushDestroyedPopups(), xxxMNDestroyHandler(), xxxMNEndMenuState(), and xxxMNStartMenuState().

00167 { 00168 00169 Validateppopupmenu(ppopupmenu); 00170 00171 if (IsRootPopupMenu(ppopupmenu)) { 00172 MNFlushDestroyedPopups (ppopupmenu, TRUE); 00173 } 00174 #if DBG 00175 /* 00176 * If this is not a cached menu and it corresponds to a menu window, 00177 * then the reference to the popup must be cleared at this point since 00178 * we're going to free this popup 00179 */ 00180 if (ppopupmenu->spwndPopupMenu != NULL) { 00181 if (!ppopupmenu->fDesktopMenu && !ppopupmenu->fIsMenuBar) { 00182 UserAssert(GETFNID(ppopupmenu->spwndPopupMenu) == FNID_MENU); 00183 UserAssert(((PMENUWND)ppopupmenu->spwndPopupMenu)->ppopupmenu == NULL); 00184 } 00185 } 00186 #endif 00187 Unlock(&ppopupmenu->spwndPopupMenu); 00188 /* 00189 * if spwndNextPopup is not NULL, we're breaking the chain and spwndNext won't 00190 * get closed. I won't remove the unlock since it has 00191 * always been there. 00192 */ 00193 UserAssert(ppopupmenu->spwndNextPopup == NULL); 00194 Unlock(&ppopupmenu->spwndNextPopup); 00195 00196 Unlock(&ppopupmenu->spwndPrevPopup); 00197 UnlockPopupMenu(ppopupmenu, &ppopupmenu->spmenu); 00198 UnlockPopupMenu(ppopupmenu, &ppopupmenu->spmenuAlternate); 00199 Unlock(&ppopupmenu->spwndNotify); 00200 Unlock(&ppopupmenu->spwndActivePopup); 00201 00202 #if DBG 00203 if (!ppopupmenu->fDesktopMenu) { 00204 ppopupmenu->fFreed = TRUE; 00205 } else { 00206 PDESKTOP pdesk = PtiCurrent()->rpdesk; 00207 UserAssert(pdesk->dwDTFlags & DF_MENUINUSE); 00208 UserAssert(((PMENUWND)pdesk->spwndMenu)->ppopupmenu == ppopupmenu); 00209 } 00210 #endif 00211 00212 if (ppopupmenu->fDesktopMenu) { 00213 PtiCurrent()->rpdesk->dwDTFlags &= ~DF_MENUINUSE; 00214 /* The desktop menu window points to this popup so don't leave bogus stuff in it */ 00215 ppopupmenu->ppopupmenuRoot = NULL; 00216 } else if (ppopupmenu == &gpopupMenu) { 00217 UserAssert(TEST_PUDF(PUDF_POPUPINUSE)); 00218 CLEAR_PUDF(PUDF_POPUPINUSE); 00219 } else { 00220 UserFreePool(ppopupmenu); 00221 } 00222 }

void MNPositionSysMenu PWND  pwnd,
PMENU  pmenusys
 

Definition at line 25 of file mnstate.c.

References tagMENU::cItems, tagITEM::cxItem, tagITEM::cyItem, FALSE, GetWindowBorders(), Lock, NULL, OffsetRect(), tagMENU::rgItems, tagMENU::spwndNotify, SYSMET, TestMF, TestWF, TRUE, WEFTOOLWINDOW, WFMINIMIZED, tagITEM::xItem, and tagITEM::yItem.

Referenced by xxxMNInvertItem(), xxxMNKeyFilter(), xxxMNStartMenu(), and xxxSetSystemMenu().

00028 { 00029 RECT rc; 00030 PITEM pItem; 00031 00032 if (pmenusys == NULL) { 00033 RIPERR0(ERROR_INVALID_HANDLE, 00034 RIP_WARNING, 00035 "Invalid menu handle pmenusys (NULL) to MNPositionSysMenu"); 00036 00037 return; 00038 } 00039 00040 /* 00041 * Whoever positions the menu becomes the owner 00042 */ 00043 if (pwnd != pmenusys->spwndNotify) { 00044 Lock(&pmenusys->spwndNotify, pwnd); 00045 } 00046 00047 /* 00048 * Setup the SysMenu hit rectangle. 00049 */ 00050 rc.top = rc.left = 0; 00051 00052 if (TestWF(pwnd, WEFTOOLWINDOW)) { 00053 rc.right = SYSMET(CXSMSIZE); 00054 rc.bottom = SYSMET(CYSMSIZE); 00055 } else { 00056 rc.right = SYSMET(CXSIZE); 00057 rc.bottom = SYSMET(CYSIZE); 00058 } 00059 00060 if (!TestWF(pwnd, WFMINIMIZED)) { 00061 int cBorders; 00062 00063 cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); 00064 OffsetRect(&rc, cBorders*SYSMET(CXBORDER), cBorders*SYSMET(CYBORDER)); 00065 } 00066 00067 /* 00068 * Offset the System popup menu. 00069 */ 00070 if (!TestMF(pmenusys, MF_POPUP) && (pmenusys->cItems > 0)) { 00071 pItem = pmenusys->rgItems; 00072 if (pItem) { 00073 pItem->yItem = rc.top; 00074 pItem->xItem = rc.left; 00075 pItem->cyItem = rc.bottom - rc.top; 00076 pItem->cxItem = rc.right - rc.left; 00077 } 00078 } 00079 else 00080 // BOGUS -- MF_POPUP should never be set on a MENU -- only a MENU ITEM 00081 UserAssert(FALSE); 00082 }

BOOL MNSetupAnimationDC PMENUSTATE  pMenuState  ) 
 

Definition at line 425 of file mnstate.c.

References BOOL, FALSE, ghMenuFont, gMenuState, gpDispInfo, tagDISPLAYINFO::hdcScreen, NULL, and TRUE.

Referenced by FinalUserInit(), and xxxMNAllocMenuState().

00426 { 00427 pMenuState->hdcAni = GreCreateCompatibleDC(gpDispInfo->hdcScreen); 00428 if (pMenuState->hdcAni == NULL) { 00429 RIPMSG0(RIP_WARNING, "MNSetupAnimationDC: Failed to create hdcAnimate"); 00430 UserAssert(pMenuState != &gMenuState); 00431 return FALSE; 00432 } 00433 GreSelectFont(pMenuState->hdcAni, ghMenuFont); 00434 return TRUE; 00435 }

PMENU xxxGetInitMenuParam PWND  pwndMenu,
BOOL *  lpfSystem
 

Definition at line 808 of file mnstate.c.

References CheckLock, tagMENU::cItems, FALSE, NULL, tagWND::spmenu, TestWF, TestwndChild, TRUE, WFMINIMIZED, and xxxGetSysMenu().

Referenced by xxxMNStartMenu().

00809 { 00810 // 00811 // Find out what menu we should be sending in WM_INITMENU: 00812 // If minimized/child/empty menubar, use system menu 00813 // 00814 CheckLock(pwndMenu); 00815 00816 if (TestWF(pwndMenu, WFMINIMIZED) || 00817 TestwndChild(pwndMenu) || 00818 (pwndMenu->spmenu == NULL) || 00819 !pwndMenu->spmenu->cItems) 00820 { 00821 if (lpfSystem != NULL) 00822 *lpfSystem = TRUE; 00823 00824 return(xxxGetSysMenu(pwndMenu, FALSE)); 00825 } 00826 else 00827 { 00828 if (lpfSystem != NULL) 00829 *lpfSystem = FALSE; 00830 00831 return(pwndMenu->spmenu); 00832 } 00833 }

PMENUSTATE xxxMNAllocMenuState PTHREADINFO  ptiCurrent,
PTHREADINFO  ptiNotify,
PPOPUPMENU  ppopupmenuRoot
 

Definition at line 458 of file mnstate.c.

References BOOL, DBGIncModalMenuCount, gMenuState, IncSFWLockCount(), MENUANIDC, MENUSTATE, MNSetupAnimationDC(), NULL, PBYTE, tagMENUSTATE::pGlobalPopupMenu, tagTHREADINFO::pMenuState, tagMENUSTATE::pmnsPrev, PtiCurrent, tagMENUSTATE::ptiMenuStateOwner, PUDF_MENUSTATEINUSE, tagTHREADINFO::rpdesk, SET_PUDF, TEST_PUDF, TRUE, and xxxMNEndMenuState().

Referenced by xxxMNStartMenuState(), and xxxTrackPopupMenuEx().

00459 { 00460 BOOL fAllocate; 00461 PMENUSTATE pMenuState; 00462 00463 UserAssert(PtiCurrent() == ptiCurrent); 00464 UserAssert(ptiCurrent->rpdesk == ptiNotify->rpdesk); 00465 00466 /* 00467 * If gMenuState is already taken, allocate one. 00468 */ 00469 fAllocate = TEST_PUDF(PUDF_MENUSTATEINUSE); 00470 if (fAllocate) { 00471 pMenuState = (PMENUSTATE)UserAllocPoolWithQuota(sizeof(MENUSTATE), TAG_MENUSTATE); 00472 if (pMenuState == NULL) { 00473 return NULL; 00474 } 00475 } else { 00476 /* 00477 * Use chache global which already has the animation DC setup 00478 */ 00479 SET_PUDF(PUDF_MENUSTATEINUSE); 00480 pMenuState = &gMenuState; 00481 UserAssert(gMenuState.hdcAni != NULL); 00482 GreSetDCOwner(gMenuState.hdcAni, OBJECT_OWNER_CURRENT); 00483 } 00484 00485 /* 00486 * Prevent anyone from changing the foreground while this menu is active 00487 */ 00488 IncSFWLockCount(); 00489 DBGIncModalMenuCount(); 00490 00491 /* 00492 * Initialize pMenuState. 00493 * Animation DC stuff is already setup so don't zero init it. 00494 */ 00495 RtlZeroMemory(pMenuState, sizeof(MENUSTATE) - sizeof(MENUANIDC)); 00496 pMenuState->pGlobalPopupMenu = ppopupmenuRoot; 00497 pMenuState->ptiMenuStateOwner = ptiCurrent; 00498 00499 /* 00500 * Save previous state, if any. Then set new state 00501 */ 00502 pMenuState->pmnsPrev = ptiCurrent->pMenuState; 00503 ptiCurrent->pMenuState = pMenuState; 00504 00505 if (ptiNotify != ptiCurrent) { 00506 UserAssert(ptiNotify->pMenuState == NULL); 00507 ptiNotify->pMenuState = pMenuState; 00508 } 00509 00510 /* 00511 * If the menustate was allocated, set up animation stuff. 00512 * This is done here because in case of failure, MNEndMenuState 00513 * will find ptiCurrent->pMenuState properly. 00514 */ 00515 if (fAllocate) { 00516 RtlZeroMemory((PBYTE)pMenuState + sizeof(MENUSTATE) - 00517 sizeof(MENUANIDC), sizeof(MENUANIDC)); 00518 if (!MNSetupAnimationDC(pMenuState)) { 00519 xxxMNEndMenuState(TRUE); 00520 return NULL; 00521 } 00522 } 00523 00524 return pMenuState; 00525 }

void xxxMNEndMenuState BOOL  fFreePopup  ) 
 

Definition at line 265 of file mnstate.c.

References CLEAR_PUDF, DBGDecModalMenuCount, DecSFWLockCount(), DF_MENUINUSE, tagDESKTOP::dwDTFlags, tagMENUSTATE::dwLockCount, FALSE, tagPOPUPMENU::fDelayedFree, tagPOPUPMENU::fDestroyed, tagPOPUPMENU::fIsMenuBar, tagPOPUPMENU::fIsTrackPopup, tagMENUSTATE::fModelessMenu, GetpMenuState(), GETPTI, gMenuState, tagMENUSTATE::hbmAni, MNDestroyAnimationBitmap(), MNEndMenuStateNotify(), MNFreePopup(), NULL, tagMENUSTATE::pGlobalPopupMenu, tagTHREADINFO::pMenuState, tagMENUSTATE::pmnsPrev, PtiCurrent, tagDESKTOP::PtiList, tagMENUSTATE::ptiMenuStateOwner, PUDF_MENUSTATEINUSE, tagTHREADINFO::rpdesk, tagPOPUPMENU::spwndActivePopup, tagDESKTOP::spwndMenu, TEST_PUDF, tagMENUSTATE::uButtonDownHitArea, tagMENUSTATE::uDraggingHitArea, UnlockMFMWFPWindow(), xxxActivateThisWindow(), and xxxMNSetCapture().

Referenced by xxxCallHandleMenuMessages(), xxxDestroyThreadInfo(), xxxMenuWindowProc(), xxxMNAllocMenuState(), xxxSysCommand(), xxxTrackPopupMenuEx(), and xxxUnlockMenuState().

00266 { 00267 PTHREADINFO ptiCurrent = PtiCurrent(); 00268 PMENUSTATE pMenuState; 00269 pMenuState = ptiCurrent->pMenuState; 00270 UserAssert(ptiCurrent->pMenuState != NULL); 00271 UserAssert(ptiCurrent == pMenuState->ptiMenuStateOwner); 00272 00273 /* 00274 * If the menu is locked, someone doesn't want it to go just yet. 00275 */ 00276 if (pMenuState->dwLockCount != 0) { 00277 RIPMSG1(RIP_WARNING, "xxxMNEndMenuState Locked:%#p", pMenuState); 00278 return; 00279 } 00280 00281 MNEndMenuStateNotify(pMenuState); 00282 00283 /* 00284 * pMenuState->pGlobalPopupMenu could be NULL if xxxMNAllocMenuState failed 00285 */ 00286 if (pMenuState->pGlobalPopupMenu != NULL) { 00287 if (fFreePopup) { 00288 UserAssert(pMenuState->pGlobalPopupMenu->fIsMenuBar || pMenuState->pGlobalPopupMenu->fDestroyed); 00289 00290 MNFreePopup(pMenuState->pGlobalPopupMenu); 00291 } else { 00292 /* 00293 * This means that we're ending the menustate but the popup menu 00294 * window is still around. This can happen when called from 00295 * xxxDestroyThreadInfo. 00296 */ 00297 UserAssert(pMenuState->pGlobalPopupMenu->fIsTrackPopup); 00298 pMenuState->pGlobalPopupMenu->fDelayedFree = FALSE; 00299 } 00300 } 00301 00302 /* 00303 * Unlock MFMWFP windows. 00304 */ 00305 UnlockMFMWFPWindow(&pMenuState->uButtonDownHitArea); 00306 UnlockMFMWFPWindow(&pMenuState->uDraggingHitArea); 00307 00308 /* 00309 * Restore the previous state, if any 00310 */ 00311 ptiCurrent->pMenuState = pMenuState->pmnsPrev; 00312 00313 /* 00314 * This (modal) menu mode is off 00315 */ 00316 if (!pMenuState->fModelessMenu) { 00317 DecSFWLockCount(); 00318 DBGDecModalMenuCount(); 00319 } 00320 00321 if (pMenuState->hbmAni != NULL) { 00322 MNDestroyAnimationBitmap(pMenuState); 00323 } 00324 00325 /* 00326 * Free the menu state 00327 */ 00328 if (pMenuState == &gMenuState) { 00329 UserAssert(TEST_PUDF(PUDF_MENUSTATEINUSE)); 00330 CLEAR_PUDF(PUDF_MENUSTATEINUSE); 00331 GreSetDCOwner(gMenuState.hdcAni, OBJECT_OWNER_PUBLIC); 00332 } else { 00333 if (pMenuState->hdcAni != NULL) { 00334 GreDeleteDC(pMenuState->hdcAni); 00335 } 00336 UserFreePool(pMenuState); 00337 } 00338 00339 /* 00340 * If returning to a modeless menu, make sure have activation 00341 * If returning to a modal menu, make sure we have capture 00342 */ 00343 if (ptiCurrent->pMenuState != NULL) { 00344 if (ptiCurrent->pMenuState->fModelessMenu) { 00345 xxxActivateThisWindow(ptiCurrent->pMenuState->pGlobalPopupMenu->spwndActivePopup, 00346 0, 0); 00347 } else { 00348 xxxMNSetCapture(ptiCurrent->pMenuState->pGlobalPopupMenu); 00349 } 00350 } 00351 00352 #if DBG 00353 /* 00354 * If this thread is not in menu mode anymore, it must not be using 00355 * the desktop menu 00356 */ 00357 if ((ptiCurrent->pMenuState == NULL) && (ptiCurrent->rpdesk->spwndMenu != NULL)) { 00358 UserAssert(ptiCurrent != GETPTI(ptiCurrent->rpdesk->spwndMenu)); 00359 } 00360 /* 00361 * If someone is using the menu window, it must be in menu mode 00362 */ 00363 if (ptiCurrent->rpdesk->dwDTFlags & DF_MENUINUSE) { 00364 UserAssert(GetpMenuState(ptiCurrent->rpdesk->spwndMenu) != NULL); 00365 } 00366 /* 00367 * No pti should point to this pMenuState anymore 00368 * If guModalMenuStateCount is zero, all pMenuState must be NULL or modeless 00369 */ 00370 { 00371 PLIST_ENTRY pHead, pEntry; 00372 PTHREADINFO ptiT; 00373 00374 pHead = &(ptiCurrent->rpdesk->PtiList); 00375 for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) { 00376 ptiT = CONTAINING_RECORD(pEntry, THREADINFO, PtiLink); 00377 UserAssert(ptiT->pMenuState != pMenuState); 00378 if (guModalMenuStateCount == 0) { 00379 UserAssert(ptiT->pMenuState == NULL || ptiT->pMenuState->fModelessMenu); 00380 } 00381 } 00382 } 00383 #endif 00384 }

BOOL xxxMNStartMenu PPOPUPMENU  ppopupmenu,
int  mn
 

Definition at line 677 of file mnstate.c.

References _GetKeyState(), BOOL, FALSE, tagMENUSTATE::fAutoDismiss, tagMENUSTATE::fButtonAlwaysDown, tagMENUSTATE::fButtonDown, tagPOPUPMENU::fDestroyed, tagMENUSTATE::fDragAndDrop, tagPOPUPMENU::fIsMenuBar, tagPOPUPMENU::fIsSysMenu, tagMENUSTATE::fIsSysMenu, tagPOPUPMENU::fIsTrackPopup, tagMENUSTATE::fMenuStarted, tagMENUSTATE::fModelessMenu, tagPOPUPMENU::fNoNotify, tagMENUSTATE::fNotifyByPos, FWINABLE, GetpMenuState(), HWq, IsRootPopupMenu(), L, LockPopupMenu(), tagMENUSTATE::mnFocus, MNPositionSysMenu(), NT_SUCCESS, NULL, PtoH, tagPOPUPMENU::spmenu, tagPOPUPMENU::spmenuAlternate, tagPOPUPMENU::spwndNotify, TestMF, ThreadLock, ThreadUnlock, TRUE, xxxClientLoadOLE(), xxxGetInitMenuParam(), xxxGetSysMenu(), xxxMNRecomputeBarIfNeeded(), xxxMNReleaseCapture(), xxxMNSetCapture(), xxxSendMessage(), and xxxWindowEvent().

Referenced by xxxMNKeyFilter(), xxxMNLoop(), and xxxTrackPopupMenuEx().

00680 { 00681 PWND pwndMenu; 00682 PMENU pMenu; 00683 PMENUSTATE pMenuState; 00684 TL tlpwndMenu; 00685 TL tlpmenu; 00686 00687 UserAssert(IsRootPopupMenu(ppopupmenu)); 00688 00689 if (ppopupmenu->fDestroyed) { 00690 return FALSE; 00691 } 00692 00693 pwndMenu = ppopupmenu->spwndNotify; 00694 ThreadLock(pwndMenu, &tlpwndMenu); 00695 00696 pMenuState = GetpMenuState(pwndMenu); 00697 if (pMenuState == NULL) { 00698 RIPMSG0(RIP_ERROR, "xxxMNStartMenu: pMenuState == NULL"); 00699 ThreadUnlock(&tlpwndMenu); 00700 return FALSE; 00701 } 00702 pMenuState->mnFocus = mn; 00703 pMenuState->fMenuStarted = TRUE; 00704 pMenuState->fButtonDown = 00705 pMenuState->fButtonAlwaysDown = ((_GetKeyState(VK_LBUTTON) & 0x8000) != 0); 00706 00707 xxxMNSetCapture(ppopupmenu); 00708 00709 xxxSendMessage(pwndMenu, WM_SETCURSOR, (WPARAM)HWq(pwndMenu), 00710 MAKELONG(MSGF_MENU, 0)); 00711 00712 if (ppopupmenu->fIsMenuBar) { 00713 BOOL fSystemMenu; 00714 00715 00716 pMenu = xxxGetInitMenuParam(pwndMenu, &fSystemMenu); 00717 00718 if (pMenu == NULL) { 00719 pMenuState->fMenuStarted = FALSE; 00720 xxxMNReleaseCapture(); 00721 ThreadUnlock(&tlpwndMenu); 00722 return(FALSE); 00723 } 00724 00725 LockPopupMenu(ppopupmenu, &ppopupmenu->spmenu, pMenu); 00726 00727 ppopupmenu->fIsSysMenu = (fSystemMenu != 0); 00728 if (!fSystemMenu) { 00729 pMenu = xxxGetSysMenu(pwndMenu, FALSE); 00730 LockPopupMenu(ppopupmenu, &ppopupmenu->spmenuAlternate, pMenu); 00731 } 00732 } 00733 00734 pMenuState->fIsSysMenu = (ppopupmenu->fIsSysMenu != 0); 00735 00736 if (!ppopupmenu->fNoNotify) { 00737 00738 if (ppopupmenu->fIsTrackPopup && ppopupmenu->fIsSysMenu) { 00739 pMenu = xxxGetInitMenuParam(pwndMenu, NULL); 00740 } else { 00741 pMenu = ppopupmenu->spmenu; 00742 } 00743 00744 xxxSendMessage(pwndMenu, WM_INITMENU, (WPARAM)PtoH(pMenu), 0L); 00745 } 00746 00747 if (!ppopupmenu->fIsTrackPopup) { 00748 if (ppopupmenu->fIsSysMenu) { 00749 MNPositionSysMenu(pwndMenu, ppopupmenu->spmenu); 00750 } else if (ppopupmenu->fIsMenuBar) { 00751 ThreadLock(ppopupmenu->spmenu, &tlpmenu); 00752 xxxMNRecomputeBarIfNeeded(pwndMenu, ppopupmenu->spmenu); 00753 ThreadUnlock(&tlpmenu); 00754 MNPositionSysMenu(pwndMenu, ppopupmenu->spmenuAlternate); 00755 } 00756 } 00757 00758 /* 00759 * If returning TRUE, set menu style in pMenuState 00760 */ 00761 if (!ppopupmenu->fDestroyed) { 00762 if (TestMF(ppopupmenu->spmenu, MNS_MODELESS)) { 00763 pMenuState->fModelessMenu = TRUE; 00764 } 00765 00766 if (TestMF(ppopupmenu->spmenu, MNS_DRAGDROP)) { 00767 if (NT_SUCCESS(xxxClientLoadOLE())) { 00768 pMenuState->fDragAndDrop = TRUE; 00769 } 00770 } 00771 00772 if (TestMF(ppopupmenu->spmenu, MNS_AUTODISMISS)) { 00773 pMenuState->fAutoDismiss = TRUE; 00774 } 00775 00776 if (TestMF(ppopupmenu->spmenu, MNS_NOTIFYBYPOS)) { 00777 pMenuState->fNotifyByPos = TRUE; 00778 } 00779 00780 } 00781 00782 /* 00783 * Bogus! We don't always know that this is the system menu. We 00784 * will frequently pass on an OBJID_MENU even when you hit Alt+Space. 00785 * 00786 * Hence, MNSwitchToAlternate will send a EVENT_SYSTEM_MENUEND for the 00787 * menu bar and an EVENT_SYSTEM_MENUSTART for the sysmenu when we "switch". 00788 */ 00789 if (FWINABLE()) { 00790 xxxWindowEvent(EVENT_SYSTEM_MENUSTART, pwndMenu, 00791 (ppopupmenu->fIsSysMenu ? OBJID_SYSMENU : (ppopupmenu->fIsMenuBar ? OBJID_MENU : OBJID_WINDOW)), 00792 INDEXID_CONTAINER, 0); 00793 } 00794 00795 ThreadUnlock(&tlpwndMenu); 00796 00797 return !ppopupmenu->fDestroyed; 00798 }

PMENUSTATE xxxMNStartMenuState PWND  pwnd,
DWORD  cmd,
LPARAM  lParam
 

Definition at line 540 of file mnstate.c.

References _PostMessage(), CheckLock, FALSE, tagPOPUPMENU::fHasMenuBar, tagPOPUPMENU::fIsMenuBar, tagPOPUPMENU::fRtoL, GETPTI, L, Lock, MFMWFP_NOITEM, MFRTL, MNAllocPopup(), MNFreePopup(), NULL, tagTHREADINFO::pMenuState, tagPOPUPMENU::posSelectedItem, tagPOPUPMENU::ppopupmenuRoot, PtiCurrent, tagWND::spmenu, tagPOPUPMENU::spwndNotify, tagWND::spwndParent, tagPOPUPMENU::spwndPopupMenu, TestMF, TestWF, TestwndChild, ThreadLockAlways, ThreadUnlock, TRUE, WEFRTLREADING, WFSYSMENU, xxxMNAllocMenuState(), and xxxSendMessage().

Referenced by xxxSysCommand().

00541 { 00542 PPOPUPMENU ppopupmenu; 00543 PTHREADINFO ptiCurrent, ptiNotify; 00544 PMENUSTATE pMenuState; 00545 TL tlpwnd; 00546 PWND pwndT; 00547 00548 CheckLock(pwnd); 00549 00550 /* 00551 * Bail if the current thread is already in menu mode 00552 */ 00553 ptiCurrent = PtiCurrent(); 00554 if (ptiCurrent->pMenuState != NULL) { 00555 return NULL; 00556 } 00557 00558 /* 00559 * If pwnd is not owned by ptiCurrent, the _PostMessage call below might 00560 * send us in a loop 00561 */ 00562 UserAssert(ptiCurrent == GETPTI(pwnd)); 00563 00564 /* 00565 * If this is not a child window, use the active window on its queue 00566 */ 00567 if (!TestwndChild(pwnd)) { 00568 pwnd = GETPTI(pwnd)->pq->spwndActive; 00569 } else { 00570 /* 00571 * Search up the parents for a window with a System Menu. 00572 */ 00573 while (TestwndChild(pwnd)) { 00574 if (TestWF(pwnd, WFSYSMENU)) { 00575 break; 00576 } 00577 pwnd = pwnd->spwndParent; 00578 } 00579 } 00580 00581 if (pwnd == NULL) { 00582 return NULL; 00583 } 00584 00585 if (!TestwndChild(pwnd) && (pwnd->spmenu != NULL)) { 00586 goto hasmenu; 00587 } 00588 00589 if (!TestWF(pwnd, WFSYSMENU)) { 00590 return NULL; 00591 } 00592 00593 hasmenu: 00594 00595 /* 00596 * If the owner/notification window was created by another thread, 00597 * make sure that it's not in menu mode already 00598 * This can happen if PtiCurrent() is attached to other threads, one of 00599 * which created pwnd. 00600 */ 00601 ptiNotify = GETPTI(pwnd); 00602 if (ptiNotify->pMenuState != NULL) { 00603 return NULL; 00604 } 00605 00606 /* 00607 * If the notification window is owned by another thread, 00608 * then the menu loop wouldn't get any keyboard or mouse 00609 * messages because we set capture to the notification window. 00610 * So we pass the WM_SYSCOMMAND to that thread and bail 00611 */ 00612 if (ptiNotify != ptiCurrent) { 00613 RIPMSG2(RIP_WARNING, "Passing WM_SYSCOMMAND SC_*MENU from thread %#p to %#p", ptiCurrent, ptiNotify); 00614 _PostMessage(pwnd, WM_SYSCOMMAND, cmd, lParam); 00615 return NULL; 00616 } 00617 00618 /* 00619 * Allocate ppoupmenu and pMenuState 00620 */ 00621 ppopupmenu = MNAllocPopup(FALSE); 00622 if (ppopupmenu == NULL) { 00623 return NULL; 00624 } 00625 00626 pMenuState = xxxMNAllocMenuState(ptiCurrent, ptiNotify, ppopupmenu); 00627 if (pMenuState == NULL) { 00628 MNFreePopup(ppopupmenu); 00629 return NULL; 00630 } 00631 00632 ppopupmenu->fIsMenuBar = TRUE; 00633 ppopupmenu->fHasMenuBar = TRUE; 00634 Lock(&(ppopupmenu->spwndNotify), pwnd); 00635 ppopupmenu->posSelectedItem = MFMWFP_NOITEM; 00636 Lock(&(ppopupmenu->spwndPopupMenu), pwnd); 00637 ppopupmenu->ppopupmenuRoot = ppopupmenu; 00638 00639 pwndT = pwnd; 00640 while( TestwndChild(pwndT) ) 00641 pwndT = pwndT->spwndParent; 00642 00643 if (pwndT->spmenu) 00644 ppopupmenu->fRtoL = TestMF(pwndT->spmenu, MFRTL) ?TRUE:FALSE; 00645 else { 00646 // 00647 // no way to know, no menu, but there is a system menu. Thus arrow 00648 // keys are really not important. however lets take the next best 00649 // thing just to be safe 00650 // 00651 ppopupmenu->fRtoL = TestWF(pwnd, WEFRTLREADING) ?TRUE :FALSE; 00652 } 00653 /* 00654 * Notify the app we are entering menu mode. wParam is always 0 since this 00655 * procedure will only be called for menu bar menus not TrackPopupMenu 00656 * menus. 00657 */ 00658 ThreadLockAlways(pwnd, &tlpwnd); 00659 xxxSendMessage(pwnd, WM_ENTERMENULOOP, 0, 0L); 00660 ThreadUnlock(&tlpwnd); 00661 00662 return pMenuState; 00663 }

BOOL xxxUnlockMenuState PMENUSTATE  pMenuState  ) 
 

Definition at line 441 of file mnstate.c.

References BOOL, tagMENUSTATE::dwLockCount, ExitMenuLoop(), FALSE, tagMENUSTATE::pGlobalPopupMenu, TRUE, and xxxMNEndMenuState().

Referenced by xxxMenuWindowProc(), xxxMNDragLeave(), and xxxMNDragOver().

00442 { 00443 UserAssert(pMenuState->dwLockCount != 0); 00444 (pMenuState->dwLockCount)--; 00445 if ((pMenuState->dwLockCount == 0) && ExitMenuLoop(pMenuState, pMenuState->pGlobalPopupMenu)) { 00446 xxxMNEndMenuState(TRUE); 00447 return TRUE; 00448 } 00449 return FALSE; 00450 }


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