/***************************************************************************\ * xxxHotTrackMenu * * Hot-track a menu item in the menu bar. \***************************************************************************/ BOOL xxxHotTrackMenu(PWND pwnd, UINT nItem, BOOL fDraw) { PMENU pmenu = pwnd->spmenu; PITEM pItem; HDC hdc; UINT oldAlign; TL tlpmenu; CheckLock(pwnd); /* * The window may have lied about the hit-test code on * WM_NCHITTEST. Make sure it does indeed have a menu. */ if (!TestWF(pwnd, WFMPRESENT) || pmenu == NULL) return FALSE; if (nItem >= pmenu->cItems) { RIPMSG0(RIP_WARNING, "xxxHotTrackMenu: menu too large"); return FALSE; } pItem = &pmenu->rgItems[nItem]; /* * Make sure we draw on the right spot */ ThreadLock(pmenu, &tlpmenu); xxxMNRecomputeBarIfNeeded(pwnd, pmenu); ValidateThreadLocks(NULL, PtiCurrent()->ptl, (ULONG_PTR)&tlpmenu, TRUE); if (fDraw) { if (TestMFS(pItem, MF_GRAYED)) { ThreadUnlock(&tlpmenu); return FALSE; } SetMFS(pItem, MFS_HOTTRACK); } else { ClearMFS(pItem, MFS_HOTTRACK); } hdc = _GetDCEx(pwnd, NULL, DCX_WINDOW | DCX_USESTYLE | DCX_CACHE); GreSelectBrush(hdc, SYSHBR(MENUTEXT)); GreSelectFont(hdc, ghMenuFont); oldAlign = GreGetTextAlign(hdc); if (pmenu->rgItems && TestMFT(pmenu->rgItems, MFT_RIGHTORDER)) GreSetTextAlign(hdc, oldAlign | TA_RTLREADING); /* * When the item is not owner draw, xxxDrawMenuItem does not * call back and does not leave the critical section. */ xxxDrawMenuItem(hdc, pmenu, pItem, 0); GreSetTextAlign(hdc, oldAlign); ThreadUnlock(&tlpmenu); _ReleaseDC(hdc); return TRUE; }
// ============================================================================ // // GetMenuItemRect() // // ============================================================================ BOOL xxxGetMenuItemRect(PWND pwnd, PMENU pMenu, UINT uIndex, LPRECT lprcScreen) { PITEM pItem; int dx, dy; CheckLock(pwnd); CheckLock(pMenu); SetRectEmpty(lprcScreen); if (uIndex >= pMenu->cItems) return(FALSE); /* * Raid #315084: Compatiblity with NT4/Win95/98 * * WordPerfect does a long complex way to calc the menu rect * by calling this API. It calls GetMenuItemRect() with the app's * window. */ if (pwnd == NULL || TestWF(pwnd, WFWIN50COMPAT)) { pwnd = GetMenuPwnd(pwnd, pMenu); } /* * If no pwnd, no go. * IMPORTANT: for MFISPOPUP we might get a different pwnd but we don't lock * it because we won't call back */ if (pwnd == NULL) { return FALSE; } if (TestMF(pMenu, MFISPOPUP)) { dx = pwnd->rcClient.left; dy = pwnd->rcClient.top; } else { xxxMNRecomputeBarIfNeeded(pwnd, pMenu); dx = pwnd->rcWindow.left; dy = pwnd->rcWindow.top; } if (uIndex >= pMenu->cItems) return(FALSE); pItem = pMenu->rgItems + uIndex; lprcScreen->right = pItem->cxItem; lprcScreen->bottom = pItem->cyItem; OffsetRect(lprcScreen, dx + pItem->xItem, dy + pItem->yItem); return(TRUE); }
int xxxMenuItemFromPoint(PWND pwnd, PMENU pMenu, POINT ptScreen) { CheckLock(pwnd); CheckLock(pMenu); /* * If no pwnd, no go. * IMPORTANT: for MFISPOPUP we might get a different pwnd but we don't lock * it because we won't call back */ pwnd = GetMenuPwnd(pwnd, pMenu); if (pwnd == NULL) { return MFMWFP_NOITEM; } if (!TestMF(pMenu, MFISPOPUP)) { xxxMNRecomputeBarIfNeeded(pwnd, pMenu); } return(MNItemHitTest(pMenu, pwnd, ptScreen)); }
BOOL xxxMNStartState( PPOPUPMENU ppopupmenu, int mn) { PWND pwndMenu; PMENUSTATE pMenuState; TL tlpwndMenu; TL tlpmenu; UserAssert(IsRootPopupMenu(ppopupmenu)); if (ppopupmenu->fDestroyed) { return FALSE; } pwndMenu = ppopupmenu->spwndNotify; ThreadLock(pwndMenu, &tlpwndMenu); pMenuState = GetpMenuState(pwndMenu); if (pMenuState == NULL) { RIPMSG0(RIP_ERROR, "xxxMNStartState: pMenuState == NULL"); return FALSE; } pMenuState->mnFocus = mn; pMenuState->fMenuStarted = TRUE; pMenuState->fButtonDown = FALSE; /* * Lotus Freelance demo programs depend on GetCapture returning their hwnd * when in menumode. */ xxxCapture(PtiCurrent(), ppopupmenu->spwndNotify, SCREEN_CAPTURE); xxxSendMessage(pwndMenu, WM_SETCURSOR, (DWORD)HWq(pwndMenu), MAKELONG(MSGF_MENU, 0)); if (ppopupmenu->fIsMenuBar) { BOOL fSystemMenu; PMENU pMenu; pMenu = GetInitMenuParam(pwndMenu, &fSystemMenu); if (pMenu == NULL) { pMenuState->fMenuStarted = FALSE; xxxSetCapture(NULL); ThreadUnlock(&tlpwndMenu); return(FALSE); } Lock(&(ppopupmenu->spmenu), pMenu); ppopupmenu->fIsSysMenu = (fSystemMenu != 0); if (!fSystemMenu) Lock(&(ppopupmenu->spmenuAlternate), GetSysMenu(pwndMenu, FALSE)); } pMenuState->fIsSysMenu = (ppopupmenu->fIsSysMenu != 0); if (!ppopupmenu->fNoNotify) { PMENU pMenu; if (ppopupmenu->fIsTrackPopup && ppopupmenu->fIsSysMenu) pMenu = GetInitMenuParam(pwndMenu, NULL); else pMenu = ppopupmenu->spmenu; xxxSendMessage(pwndMenu, WM_INITMENU, (DWORD)PtoH(pMenu), 0L); } if (!ppopupmenu->fIsTrackPopup) { if (ppopupmenu->fIsSysMenu) { MNPositionSysMenu(pwndMenu, ppopupmenu->spmenu); } else if (ppopupmenu->fIsMenuBar) { ThreadLock(ppopupmenu->spmenu, &tlpmenu); xxxMNRecomputeBarIfNeeded(pwndMenu, ppopupmenu->spmenu); ThreadUnlock(&tlpmenu); MNPositionSysMenu(pwndMenu, ppopupmenu->spmenuAlternate); } } ThreadUnlock(&tlpwndMenu); return !ppopupmenu->fDestroyed; }