Exemplo n.º 1
0
/***************************************************************************\
* 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;
}
Exemplo n.º 2
0
// ============================================================================
//
//  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);
}
Exemplo n.º 3
0
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));
}
Exemplo n.º 4
0
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;
}