예제 #1
0
파일: winable2.c 프로젝트: conioh/os-design
/*****************************************************************************\
* xxxGetMenuBarInfo()
*
* This succeeds if the menu/menu item exists.
*
* Parameters:
*     pwnd        window
*     idObject    this can be OBJID_MENU, OBJID_SYSMENU, or OBJID_CLIENT
*     idItem      which thing do we need info on? 0..cItems. 0 indicates
*                 the menu itself, 1 is the first item on the menu...
*     pmbi        Pointer to a MENUBARINFO structure that gets filled in
*
\*****************************************************************************/
BOOL WINAPI
xxxGetMenuBarInfo(PWND pwnd, long idObject, long idItem, PMENUBARINFO pmbi)
{
    PMENU       pMenu;
    int         cBorders;
    PITEM       pItem;
    PPOPUPMENU  ppopup;

    CheckLock(pwnd);

    /*
     * Validate menubarinfo structure
     */
    if (pmbi->cbSize != sizeof(MENUBARINFO)) {
        RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "MENUBARINFO.cbSize %d is wrong", pmbi->cbSize);
        return FALSE;
    }

    /*
     * Initialize the fields
     */
    SetRectEmpty(&pmbi->rcBar);
    pmbi->hMenu = NULL;
    pmbi->hwndMenu = NULL;
    pmbi->fBarFocused = FALSE;
    pmbi->fFocused = FALSE;

    /*
     * Get the menu handle we will deal with.
     */
    if (idObject == OBJID_MENU) {
        int cBorders;

        if (TestWF(pwnd, WFCHILD) || !pwnd->spmenu)
            return FALSE;

        pMenu = pwnd->spmenu;
        if (!pMenu)
            return FALSE;

        // If we have an item, is it in the valid range?
        if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems))
            return FALSE;

        /*
         * Menu handle
         */
        pmbi->hMenu = PtoHq(pMenu);

        /*
         * Menu rect
         */
        if (pMenu->cxMenu && pMenu->cyMenu) {
            if (!idItem) {
                cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE);
                pmbi->rcBar.left = pwnd->rcWindow.left + cBorders * SYSMET(CXBORDER);
                pmbi->rcBar.top = pwnd->rcWindow.top + cBorders * SYSMET(CYBORDER);

                if (TestWF(pwnd, WFCPRESENT)) {
                    pmbi->rcBar.top += (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMCAPTION) : SYSMET(CYCAPTION));
                }

                pmbi->rcBar.right = pmbi->rcBar.left + pMenu->cxMenu;
                pmbi->rcBar.bottom = pmbi->rcBar.top + pMenu->cyMenu;
            } else {
                pItem = pMenu->rgItems + idItem - 1;

                pmbi->rcBar.left = pwnd->rcWindow.left + pItem->xItem;
                pmbi->rcBar.top = pwnd->rcWindow.top + pItem->yItem;
                pmbi->rcBar.right = pmbi->rcBar.left + pItem->cxItem;
                pmbi->rcBar.bottom = pmbi->rcBar.top + pItem->cyItem;
            }
        }

        /*
         * Are we currently in app menu bar mode?
         */
        ppopup = GetpGlobalPopupMenu(pwnd);
        if (ppopup && ppopup->fHasMenuBar && !ppopup->fIsSysMenu &&
            (ppopup->spwndNotify == pwnd))
        {
            // Yes, we are.
            pmbi->fBarFocused = TRUE;

            if (!idItem) {
                pmbi->fFocused = TRUE;
            } else if (ppopup->ppopupmenuRoot->posSelectedItem == (UINT)idItem-1) {
                pmbi->fFocused = TRUE;
                UserAssert(ppopup->ppopupmenuRoot);
                pmbi->hwndMenu = HW(ppopup->ppopupmenuRoot->spwndNextPopup);
            }
        }

    } else if (idObject == OBJID_SYSMENU) {
        if (!TestWF(pwnd, WFSYSMENU))
            return FALSE;

        pMenu = xxxGetSysMenu(pwnd, FALSE);
        if (!pMenu)
            return FALSE;

        // If we have an item, is it in the valid range?
        if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems))
            return FALSE;

        pmbi->hMenu = PtoHq(pMenu);

        /*
         * Menu rect
         */
        if (_HasCaptionIcon(pwnd)) {
            // The menu and single item take up the same space
            cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE);
            pmbi->rcBar.left = pwnd->rcWindow.left + cBorders * SYSMET(CXBORDER);
            pmbi->rcBar.top = pwnd->rcWindow.top + cBorders * SYSMET(CYBORDER);

            pmbi->rcBar.right = pmbi->rcBar.left +
                (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CXSMSIZE) : SYSMET(CXSIZE));

            pmbi->rcBar.bottom = pmbi->rcBar.top +
                (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMSIZE) : SYSMET(CYSIZE));
        }

        /*
         * Are we currently in system menu bar mode?
         */
        ppopup = GetpGlobalPopupMenu(pwnd);
        if (ppopup && ppopup->fHasMenuBar && ppopup->fIsSysMenu &&
            (ppopup->spwndNotify == pwnd))
        {
            // Yes, we are.
            pmbi->fBarFocused = TRUE;

            if (!idItem) {
                pmbi->fFocused = TRUE;
            } else if (ppopup->ppopupmenuRoot->posSelectedItem == (UINT)idItem - 1) {
                pmbi->fFocused = TRUE;
                UserAssert(ppopup->ppopupmenuRoot);
                pmbi->hwndMenu = HW(ppopup->ppopupmenuRoot->spwndNextPopup);
            }
        }
    }
    else if (idObject == OBJID_CLIENT)
    {
        HMENU hMenu;
        hMenu = (HMENU)xxxSendMessage(pwnd, MN_GETHMENU, 0, 0);
        pMenu = HtoP(hMenu);
        if (!pMenu)
            return FALSE;

        // If we have an item, is it in the valid range?
        if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems))
            return FALSE;

        pmbi->hMenu = hMenu;

        if (!idItem) {
            pmbi->rcBar = pwnd->rcClient;
        } else {
            pItem = pMenu->rgItems + idItem - 1;

            pmbi->rcBar.left = pwnd->rcClient.left + pItem->xItem;
            pmbi->rcBar.top = pwnd->rcClient.top + pItem->yItem;
            pmbi->rcBar.right = pmbi->rcBar.left + pItem->cxItem;
            pmbi->rcBar.bottom = pmbi->rcBar.top + pItem->cyItem;
        }

        /*
         * Are we currently in popup mode with us as one of the popups
         * showing?
         */
        ppopup = ((PMENUWND)pwnd)->ppopupmenu;
        if (ppopup && (ppopup->ppopupmenuRoot == GetpGlobalPopupMenu(pwnd))) {
            pmbi->fBarFocused = TRUE;

            if (!idItem) {
                pmbi->fFocused = TRUE;
            } else if ((UINT)idItem == ppopup->posSelectedItem + 1) {
                pmbi->fFocused = TRUE;
                pmbi->hwndMenu = HW(ppopup->spwndNextPopup);
            }
        }
    } else {
        return FALSE;
    }

    return TRUE;
}
예제 #2
0
파일: winmgr.c 프로젝트: Gaikokujin/WinNT4
int FindNCHit(
    PWND pwnd,
    LONG lPt)
{
    POINT pt;
    RECT rcWindow;
    RECT rcClient;
    RECT rcClientAdj;
    int cBorders;
    int dxButton;

    pt.x = LOWORD(lPt);
    pt.y = HIWORD(lPt);

    if (!PtInRect(&pwnd->rcWindow, pt))
        return HTNOWHERE;

    if (TestWF(pwnd, WFMINIMIZED)) {
        CopyInflateRect(&rcWindow, &pwnd->rcWindow,
            -(SYSMET(CXFIXEDFRAME) + SYSMET(CXBORDER)), -(SYSMET(CYFIXEDFRAME) + SYSMET(CYBORDER)));

        if (!PtInRect(&rcWindow, pt))
            return HTCAPTION;

        goto CaptionHit;
    }

    // Get client rectangle
    rcClient = pwnd->rcClient;
    if (PtInRect(&rcClient, pt))
        return HTCLIENT;

    // Are we in "pseudo" client, i.e. the client & scrollbars & border
    if (TestWF(pwnd, WEFCLIENTEDGE))
        CopyInflateRect(&rcClientAdj, &rcClient, SYSMET(CXEDGE), SYSMET(CYEDGE));
    else
        rcClientAdj = rcClient;

    if (TestWF(pwnd, WFVPRESENT))
        rcClientAdj.right += SYSMET(CXVSCROLL);
    if (TestWF(pwnd, WFHPRESENT))
        rcClientAdj.bottom += SYSMET(CYHSCROLL);

    if (!PtInRect(&rcClientAdj, pt))
    {
        // Subtract out window borders
        cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE);
        CopyInflateRect(&rcWindow, &pwnd->rcWindow,
            -cBorders*SYSMET(CXBORDER), -cBorders*SYSMET(CYBORDER));

        // Are we on the border?
        if (!PtInRect(&rcWindow, pt))
        {
            // On a sizing border?
            if (!TestWF(pwnd, WFSIZEBOX)) {
                //
                // Old compatibility thing:  For 3.x windows that just had
                // a border, we returned HTNOWHERE, believe it or not,
                // because our hit-testing code was so brain dead.
                //
                if (!TestWF(pwnd, WFWIN40COMPAT) &&
                        !TestWF(pwnd, WFDLGFRAME)    &&
                        !TestWF(pwnd, WEFDLGMODALFRAME)) {
                    return(HTNOWHERE);

                } else {
                    return(HTBORDER);  // We are on a dlg frame.
                }
            } else {

                int ht;

                //
                // Note this improvement.  The HT codes are numbered so that
                // if you subtract HTSIZEFIRST-1 from them all, they sum up.  I.E.,
                // (HTLEFT - HTSIZEFIRST + 1) + (HTTOP - HTSIZEFIRST + 1) ==
                // (HTTOPLEFT - HTSIZEFIRST + 1).
                //

                if (TestWF(pwnd, WEFTOOLWINDOW))
                    InflateRect(&rcWindow, -SYSMET(CXSMSIZE), -SYSMET(CYSMSIZE));
                else
                    InflateRect(&rcWindow, -SYSMET(CXSIZE), -SYSMET(CYSIZE));

                if (pt.y < rcWindow.top)
                    ht = (HTTOP - HTSIZEFIRST + 1);
                else if (pt.y >= rcWindow.bottom)
                    ht = (HTBOTTOM - HTSIZEFIRST + 1);
                else
                    ht = 0;

                if (pt.x < rcWindow.left)
                    ht += (HTLEFT - HTSIZEFIRST + 1);
                else if (pt.x >= rcWindow.right)
                    ht += (HTRIGHT - HTSIZEFIRST + 1);

                return (ht + HTSIZEFIRST - 1);
            }
        }

        // Are we above the client area?
        if (pt.y < rcClientAdj.top)
        {
            // Are we in the caption?
            if (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION))
            {
CaptionHit:
                if (pt.y >= rcWindow.top)
                {
                    if (TestWF(pwnd, WEFTOOLWINDOW))
                    {
                        rcWindow.top += SYSMET(CYSMCAPTION);
                        dxButton = SYSMET(CXSMSIZE);
                    }
                    else
                    {
                        rcWindow.top += SYSMET(CYCAPTION);
                        dxButton = SYSMET(CXSIZE);
                    }

                    if ((pt.y >= rcWindow.top) && TestWF(pwnd, WFMPRESENT))
                        return(HTMENU);

                    if ((pt.x >= rcWindow.left)  &&
                        (pt.x <  rcWindow.right) &&
                        (pt.y <  rcWindow.top))
                    {
                        // Are we in the window menu?
                        if (TestWF(pwnd, WFSYSMENU))
                        {
                            rcWindow.left += dxButton;
                            if (pt.x < rcWindow.left)
                            {
                                if (!_HasCaptionIcon(pwnd))
                                // iconless windows have no sysmenu hit rect
                                    return(HTCAPTION);

                                return(HTSYSMENU);
                            }
                        }
                        else if (TestWF(pwnd, WFWIN40COMPAT))
                            return(HTCAPTION);

                        // only a close button if window has a system menu

                        // Are we in the close button?
                        rcWindow.right -= dxButton;
                        if (pt.x >= rcWindow.right)
                            return HTCLOSE;

                        if ((pt.x < rcWindow.right) && !TestWF(pwnd, WEFTOOLWINDOW))
                        {
                            // Are we in the maximize/restore button?
                            if (TestWF(pwnd, (WFMAXBOX | WFMINBOX)))
                            {
                                // Note that sizing buttons are same width for both
                                // big captions and small captions.
                                rcWindow.right -= dxButton;
                                if (pt.x >= rcWindow.right)
                                    return HTZOOM;

                                // Are we in the minimize button?
                                rcWindow.right -= dxButton;
                                if (pt.x >= rcWindow.right)
                                    return HTREDUCE;
                            }
                            else if (TestWF(pwnd, WEFCONTEXTHELP))
                            {
                                rcWindow.right -= dxButton;
                                if (pt.x >= rcWindow.right)
                                    return HTHELP;
                            }
                        }
                    }
                }

                // We're in the caption proper
                return HTCAPTION;
            }

            //
            // Are we in the menu?
            //
            if (TestWF(pwnd, WFMPRESENT))
                return HTMENU;
        }
    }
    else
    {
        //
        // NOTE:
        // We can only be here if we are on the client edge, horz scroll,
        // sizebox, or vert scroll.  Hence, if we are not on the first 3,
        // we must be on the last one.
        //

        //
        // Are we on the client edge?
        //
        if (TestWF(pwnd, WEFCLIENTEDGE))
        {
            InflateRect(&rcClientAdj, -SYSMET(CXEDGE), -SYSMET(CYEDGE));
            if (!PtInRect(&rcClientAdj, pt))
                return(HTBORDER);
        }

        //
        // Are we on the scrollbars?
        //
        if (TestWF(pwnd, WFHPRESENT) && (pt.y >= rcClient.bottom))
        {
            UserAssert(pt.y < rcClientAdj.bottom);
            if (TestWF(pwnd, WFVPRESENT) && (pt.x >= rcClient.right))
                return(SizeBoxHwnd(pwnd) ? HTBOTTOMRIGHT : HTGROWBOX);
            else
                return(HTHSCROLL);
        }
        else
        {
            UserAssert(TestWF(pwnd, WFVPRESENT));
            UserAssert(pt.x >= rcClient.right);
            UserAssert(pt.x < rcClientAdj.right);
            return(HTVSCROLL);
        }
    }

    //
    // We give up.
    //
    // Win31 returned HTNOWHERE in this case; For compatibility, we will
    // keep it that way.
    //
    return(HTNOWHERE);

}
예제 #3
0
파일: winable2.c 프로젝트: conioh/os-design
/****************************************************************************\
*
* _GetTitleBarInfo()
*
* Gets info about a window's title bar.  If the window is bogus or
* doesn't have a titlebar, this will fail.
*
\****************************************************************************/
BOOL WINAPI
xxxGetTitleBarInfo(PWND pwnd, PTITLEBARINFO ptbi)
{
    int     cxB;

    CheckLock(pwnd);

    /*
     * Validate titlebarinfo structure
     */
    if (ptbi->cbSize != sizeof(TITLEBARINFO)) {
        RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "TITLEBARINFO.cbSize %d is wrong", ptbi->cbSize);
        return FALSE;
    }

    RtlZeroMemory(&ptbi->rgstate, sizeof(ptbi->rgstate));

    ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_FOCUSABLE;
    if (TestWF(pwnd, WFBORDERMASK) != LOBYTE(WFCAPTION))
    {
        // No titlebar.
        ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_INVISIBLE;
        return TRUE;
    }

    if (!TestWF(pwnd, WFMINIMIZED) && !TestWF(pwnd, WFCPRESENT))
    {
        // Off screen (didn't fit)
        ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_OFFSCREEN;
        SetRectEmpty(&ptbi->rcTitleBar);
        return TRUE;
    }

    /*
     * Get titlebar rect
     */
    ptbi->rcTitleBar = pwnd->rcWindow;
    cxB = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE);
    InflateRect(&ptbi->rcTitleBar, -cxB * SYSMET(CXBORDER), -cxB * SYSMET(CYBORDER));
    if (TestWF(pwnd, WEFTOOLWINDOW)) {
        ptbi->rcTitleBar.bottom = ptbi->rcTitleBar.top + SYSMET(CYSMCAPTION);
    } else {
        ptbi->rcTitleBar.bottom = ptbi->rcTitleBar.top + SYSMET(CYCAPTION);
    }

    /*
     * Don't include the system menu area!
     */
    if (TestWF(pwnd, WFSYSMENU) && _HasCaptionIcon(pwnd))
        ptbi->rcTitleBar.left += (ptbi->rcTitleBar.bottom - ptbi->rcTitleBar.top - SYSMET(CYBORDER));

    /*
     * Close button
     */
    if (!TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) {
        ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_INVISIBLE;
    } else {
        if (!xxxMNCanClose(pwnd))
            ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_UNAVAILABLE;

        if (TestWF(pwnd, WFCLOSEBUTTONDOWN))
            ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_PRESSED;
    }


    /*
     * Max button
     */
    if (! TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) {
        ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_INVISIBLE;
    } else {
        if (! TestWF(pwnd, WFMAXBOX)) {
            if (! TestWF(pwnd, WFMINBOX)) {
                ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_INVISIBLE;
            } else {
                ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_UNAVAILABLE;
            }
        }

        if (TestWF(pwnd, WFZOOMBUTTONDOWN))
            ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_PRESSED;
    }


    /*
     * Min button
     */
    if (! TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) {
        ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_INVISIBLE;
    } else {
        if (! TestWF(pwnd, WFMINBOX)) {
            if (! TestWF(pwnd, WFMAXBOX)) {
                ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_INVISIBLE;
            } else {
                ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_UNAVAILABLE;
            }
        }

        if (TestWF(pwnd, WFREDUCEBUTTONDOWN))
            ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_PRESSED;
    }


    /*
     * Help button
     */
    if (!TestWF(pwnd, WEFCONTEXTHELP) || TestWF(pwnd, WFMINBOX) ||
            TestWF(pwnd, WFMAXBOX)) {
        ptbi->rgstate[INDEX_TITLEBAR_HELPBUTTON] |= STATE_SYSTEM_INVISIBLE;
    } else {
        if (TestWF(pwnd, WFHELPBUTTONDOWN))
            ptbi->rgstate[INDEX_TITLEBAR_HELPBUTTON] |= STATE_SYSTEM_PRESSED;
    }

    // IME button BOGUS!
    ptbi->rgstate[INDEX_TITLEBAR_IMEBUTTON] = STATE_SYSTEM_INVISIBLE;

#if 0
    /*
     * System menu
     */
    if (!TestWF(pwnd, WFSYSMENU) || !_HasCaptionIcon(pwnd))
        ptbi->stateSysMenu |= STATE_SYSTEM_INVISIBLE;
#endif

    return TRUE;
}