Пример #1
0
BOOL _HasCaptionIcon(PWND pwnd)
{
    HICON hIcon;
    PCLS pcls;

    if (TestWF(pwnd, WEFTOOLWINDOW))
        // it's a tool window -- it doesn't get an icon
        return(FALSE);

    if ((TestWF(pwnd, WFBORDERMASK) != (BYTE)LOBYTE(WFDLGFRAME)) &&
            !TestWF(pwnd, WEFDLGMODALFRAME))
        // they are not trying to look like a dialog, they get an icon
        return TRUE;

    if (!TestWF(pwnd, WFWIN40COMPAT) &&
        (((PCLS)REBASEALWAYS(pwnd, pcls))->atomClassName == (ATOM)DIALOGCLASS))
        // it's an older REAL dialog -- it doesn't get an icon
        return(FALSE);

    hIcon = (HICON) _GetProp(pwnd, MAKEINTATOM(gpsi->atomIconSmProp), TRUE);

    if (hIcon) {
        // it's a 4.0 dialog with a small icon -- if that small icon is
        // something other than the generic small windows icon, it gets an icon
        return(hIcon != gpsi->hIconSmWindows);
    }
    hIcon = (HICON) _GetProp(pwnd, MAKEINTATOM(gpsi->atomIconProp), TRUE);

    if (hIcon && (hIcon != gpsi->hIcoWindows))
        // it's a 4.0 dialog with no small icon, but instead a large icon
        // that's not the generic windows icon -- it gets an icon
        return(TRUE);

    pcls = REBASEALWAYS(pwnd, pcls);
    if (pcls->spicnSm) {
        if (pcls->spicnSm != HMObjectFromHandle(gpsi->hIconSmWindows)) {
            // it's a 4.0 dialog with a class icon that's not the generic windows
            // icon -- it gets an icon
            return(TRUE);
        }
    }

    // it's a 4.0 dialog with no small or large icon -- it doesn't get an icon
    return(FALSE);
}
Пример #2
0
VOID xxxRecreateSmallIcons(PWND pwnd)
{
    BOOL    fSmQueryDrag;

    CheckLock(pwnd);

    if (DestroyClassSmIcon(pwnd->pcls))
        xxxCreateClassSmIcon(pwnd->pcls);

    fSmQueryDrag = (TestWF(pwnd, WFSMQUERYDRAGICON) != 0);
    if (DestroyWindowSmIcon(pwnd) && !fSmQueryDrag)
        xxxCreateWindowSmIcon(pwnd, (HICON)_GetProp(pwnd, MAKEINTATOM(gpsi->atomIconProp), PROPF_INTERNAL), TRUE);
}
Пример #3
0
DWORD GetContextHelpId(
    PWND pwnd)
{
    DWORD  dwContextId;

    while (!(dwContextId = (DWORD)_GetProp(pwnd,
            MAKEINTATOM(gpsi->atomContextHelpIdProp), PROPF_INTERNAL))) {
        pwnd = (TestwndChild(pwnd) ?
                REBASEPWND(pwnd, spwndParent) :
                REBASEPWND(pwnd, spwndOwner));
        if (!pwnd || (GETFNID(pwnd) == FNID_DESKTOP))
            break;
    }

    return dwContextId;
}
Пример #4
0
/*
 * Modal loop for when the user has selected the help icon from the titlebar
 *
 */
VOID xxxHelpLoop(PWND pwnd)
{
    HWND        hwndChild;
    PWND        pwndChild;
    PWND        pwndControl;
    MSG         msg;
    RECT        rc;
    int         cBorders;
    PTHREADINFO ptiCurrent = PtiCurrent();
    DLGENUMDATA DlgEnumData;
    TL          tlpwndChild;

    CheckLock(pwnd);
    UserAssert(IsWinEventNotifyDeferredOK());

    if (FWINABLE()) {
        xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPSTART, pwnd, OBJID_WINDOW,
            INDEXID_CONTAINER, 0);
    }

    zzzSetCursor(SYSCUR(HELP));
    xxxCapture(ptiCurrent, pwnd, SCREEN_CAPTURE);

    cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE);

    CopyInflateRect(&rc, &pwnd->rcWindow, -cBorders * SYSMET(CXBORDER), -cBorders * SYSMET(CYBORDER));

    while (ptiCurrent->pq->spwndCapture == pwnd) {
        if (!xxxPeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_NOREMOVE)) {
            xxxWaitMessage();
            continue;
        }

        if (msg.message == WM_NCLBUTTONDOWN) {
            break;
        } else if (msg.message == WM_LBUTTONDOWN) {
            /*
             *  If user clicked outside of window client, bail out now.
             */
            if (!PtInRect(&rc, msg.pt))
                break;

            /*
             *  WindowHitTest() won't return a static control's handle
             */
            hwndChild = xxxWindowHitTest(pwnd, msg.pt, NULL, 0);
            pwndChild = ValidateHwnd( hwndChild );
            ThreadLock(pwndChild, &tlpwndChild);

            if (pwndChild && FIsParentDude(pwndChild))
            {
                /*
                 * If this is a dialog class, then one of three things has
                 * happened:
                 *
                 *  o   This is a static text control
                 *  o   This is the background of the dialog box.
                 *
                 * What we do is enumerate the child windows and see if
                 * any of them contain the current cursor point. If they do,
                 * change our window handle and continue on. Otherwise,
                 * return doing nothing -- we don't want context-sensitive
                 * help for a dialog background.
                 *
                 * If this is a group box, then we might have clicked on a
                 * disabled control, so we enumerate child windows to see
                 * if we get another control.
                 */

                /*
                 *  We're enumerating a dialog's children.  So, if we don't
                 *  find any matches, hwndChild will be NULL and the check
                 *  below will drop out.
                 */
                DlgEnumData.pwndDialog = pwndChild;
                DlgEnumData.pwndControl = NULL;
                DlgEnumData.ptCurHelp = msg.pt;
                xxxInternalEnumWindow(pwndChild, EnumPwndDlgChildProc, (LPARAM)&DlgEnumData, BWL_ENUMCHILDREN);
                pwndControl = DlgEnumData.pwndControl;
            } else {
                pwndControl = pwndChild;
            }

            /*
             * If we click on nothing, just exit.
             */
            if (pwndControl == pwnd) {
                pwndControl = NULL;
            }

            /*
             *  HACK ALERT (Visual Basic 4.0) - they have their own non-window
             *    based controls that draw directly on the main dialog.  In order
             *    to provide help for these controls, we pass along the WM_HELP
             *    message iff the main dialog has a context id assigned.
             *
             *  If the top level window has its own context help ID,
             *  then pass it in the context help message.
             */
            if (!pwndControl) {
                if (_GetProp(pwnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), TRUE))
                    pwndControl = pwnd;
            }

            if (pwndControl) {
                PWND    pwndSend;
                int     id;
                TL      tlpwndSend;
                TL      tlpwndControl;

                ThreadLockAlways(pwndControl, &tlpwndControl);

                zzzSetCursor(SYSCUR(ARROW));
                xxxReleaseCapture();
                xxxRedrawTitle(pwnd, DC_BUTTONS);
                ClrWF(pwnd, WFHELPBUTTONDOWN);
                xxxGetMessage(&msg, NULL, 0, 0);

                if (FWINABLE()) {
                    xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR,
                        INDEX_TITLEBAR_HELPBUTTON, FALSE);

                    xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW,
                        INDEXID_CONTAINER, FALSE);
                }

                /*
                 * Determine the ID of the control
                 * We used to always sign extend, but Win98 doesn't do that
                 * so we only sign extend 0xffff.  MCostea #218711
                 */
                if (TestwndChild(pwndControl)) {
                    id = PTR_TO_ID(pwndControl->spmenu);
                    if (id == 0xffff) {
                        id = -1;
                    }
                } else {
                    id = -1;
                }

                /*
                 * Disabled controls and static controls won't pass this
                 * on to their parent, so instead, we send the message to
                 * their parent.
                 */

                if (TestWF(pwndControl, WFDISABLED)) {
                    PWND pwndParent = _GetParent(pwndControl);
                    if (!pwndParent)
                    {
                        ThreadUnlock( &tlpwndControl );
                        ThreadUnlock( &tlpwndChild );
                        return;
                    }
                    pwndSend = pwndParent;
                } else {
                    pwndSend = pwndControl;
                }

                ThreadLockAlways(pwndSend, &tlpwndSend);
                xxxSendHelpMessage( pwndSend, HELPINFO_WINDOW, id,
                    (HANDLE)HWq(pwndControl), GetContextHelpId(pwndControl));
                ThreadUnlock(&tlpwndSend);
                ThreadUnlock(&tlpwndControl);
                ThreadUnlock(&tlpwndChild);
                return;
            }
            ThreadUnlock(&tlpwndChild);
            break;

        }
        else if ((msg.message == WM_RBUTTONDOWN) || 
                 (msg.message == WM_MBUTTONDOWN) || 
                 (msg.message == WM_XBUTTONDOWN)) {
            /*
             *  fix bug 29852; break the loop for right and middle buttons
             *  and pass along the messages to the control
             */
            break;
        }
        else if (msg.message == WM_MOUSEMOVE) {
            if (PtInRect(&rc, msg.pt))
                zzzSetCursor(SYSCUR(HELP));
            else
                zzzSetCursor(SYSCUR(ARROW));
        }
        else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)
        {
            xxxGetMessage( &msg, NULL, 0, 0 );
            break;
        }

        xxxGetMessage(&msg, NULL, 0, 0);
        xxxTranslateMessage(&msg, 0);
        xxxDispatchMessage(&msg);
    }

    xxxReleaseCapture();
    zzzSetCursor(SYSCUR(ARROW));
    xxxRedrawTitle(pwnd, DC_BUTTONS);

    ClrWF(pwnd, WFHELPBUTTONDOWN);
    if (FWINABLE()) {
        xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR,
                INDEX_TITLEBAR_HELPBUTTON, 0);

        xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW,
                INDEXID_CONTAINER, 0);
    }
}
Пример #5
0
DWORD _GetWindowContextHelpId(PWND pWnd)
{
    return (DWORD)(ULONG_PTR)_GetProp(pWnd, MAKEINTATOM(gpsi->atomContextHelpIdProp),
            PROPF_INTERNAL);
}
Пример #6
0
UINT xxxArrangeIconicWindows(
    PWND pwnd)
{
    PBWL pbwl;
    PSMWP psmwp;
    PWND pwndTest, pwndSort, pwndSwitch;
    HWND *phwnd, *phwndSort;
    CHECKPOINT *pcp, *pcpSort;
    POINT ptSort, ptSrc;
    WORD  nIcons = 0;
    RECT  rc;
    POINT ptMin;
    int   xOrg, yOrg;
    int   dx, dy;
    int   dxSlot, dySlot;
    int   cIconsPerPass, iIconPass;
    BOOL  fHorizontal, fBreak;
    TL tlpwndTest;
    BOOL fHideMe;

    CheckLock(pwnd);

    /*
     * Create a window list of all children of pwnd
     */
    if ((pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL)) == NULL)
        return 0;

    fHideMe = IsTrayWindow(pwnd->spwndChild);

    //
    // Put these into local vars for efficiency (see ParkIcon())
    //
    dxSlot = SYSMET(CXMINSPACING);
    dySlot = SYSMET(CYMINSPACING);

    //
    // We need to adjust the client rectangle if the parent has scrollbars.
    //
    GetRealClientRect(pwnd, &rc, GRC_SCROLLS);

    /*
     * find all icons
     */
    pwndSwitch = RevalidateHwnd(ghwndSwitch);
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
        if (((pwndTest = RevalidateHwnd(*phwnd)) == NULL) ||
                !TestWF(pwndTest , WFVISIBLE) ||
                pwndTest == pwndSwitch ||
                (pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                        PROPF_INTERNAL)) == NULL) {
            *phwnd = NULL;
            continue;
        }

        if (!TestWF(pwndTest, WFMINIMIZED)) {
            pcp->fMinInitialized = FALSE;
            pcp->ptMin.x = pcp->ptMin.y = -1;
            *phwnd = NULL;
            continue;
        }

        /*
         * inc count of icons
         */
        nIcons++;

        /*
         * we will park in default position again...
         */
        pcp->fDragged = FALSE;

        /*
         * ensure the original position is up to date
         */
        pcp->ptMin.x = pwndTest->rcWindow.left - pwnd->rcClient.left;
        pcp->ptMin.y = pwndTest->rcWindow.top - pwnd->rcClient.top;

        // Slide into the nearest row or column
        switch (SYSMET(ARRANGE) & ~ARW_HIDE) {
            case ARW_TOPLEFT | ARW_RIGHT:
            case ARW_TOPRIGHT | ARW_LEFT:
                // Slide into top row
                pcp->ptMin.y += dySlot / 2;
                pcp->ptMin.y -= pcp->ptMin.y % dySlot;
                break;

            case ARW_TOPLEFT | ARW_DOWN:
            case ARW_BOTTOMLEFT | ARW_UP:
                // Slide into left column
                pcp->ptMin.x += dxSlot / 2;
                pcp->ptMin.x -= pcp->ptMin.x % dxSlot;
                break;

            case ARW_BOTTOMLEFT | ARW_RIGHT:
            case ARW_BOTTOMRIGHT | ARW_LEFT:
                // Slide into bottom row
                pcp->ptMin.y = rc.bottom - pcp->ptMin.y;
                pcp->ptMin.y += dySlot / 2;
                pcp->ptMin.y -= pcp->ptMin.y % dySlot;
                pcp->ptMin.y = rc.bottom - pcp->ptMin.y;
                break;

            case ARW_BOTTOMRIGHT | ARW_UP:
            case ARW_TOPRIGHT | ARW_DOWN:
                // Slide into right column
                pcp->ptMin.x = rc.right - pcp->ptMin.x;
                pcp->ptMin.x += dxSlot / 2;
                pcp->ptMin.x -= pcp->ptMin.x % dxSlot;
                pcp->ptMin.x = rc.right - pcp->ptMin.x;
                break;
        }
    }

    if (nIcons == 0) {

        /*
         * no icons were found...  break out
         */
        FreeHwndList(pbwl);
        return 0;
    }

    if (fHideMe) {
        ptMin.x = WHERE_NOONE_CAN_SEE_ME;
        ptMin.y = WHERE_NOONE_CAN_SEE_ME;
        goto JustParkEm;
    }

    //
    // Get gravity && move vars
    //
    if (SYSMET(ARRANGE) & ARW_STARTRIGHT) {
        // Starting on right side
        ptMin.x = xOrg = rc.right - dxSlot;
        dx = -dxSlot;
    } else {
        // Starting on left
        ptMin.x = xOrg = rc.left + DX_GAP;
        dx = dxSlot;
    }

    if (SYSMET(ARRANGE) & ARW_STARTTOP) {
        // Starting on top
        ptMin.y = yOrg = rc.top + DY_GAP;
        dy = dySlot;
    } else {
        // Starting on bottom
        ptMin.y = yOrg = rc.bottom - dySlot;
        dy = -dySlot;
    }

    //
    // Get arrange dir
    //
    fHorizontal = ( (SYSMET(ARRANGE) & ARW_DOWN) ? FALSE : TRUE );

    iIconPass = fHorizontal ? (rc.right / dxSlot) : (rc.bottom / dySlot);
    cIconsPerPass = iIconPass = max(1, iIconPass);

    /*
     * insertion sort of windows by y, and by x within a row.
     */
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {

        /*
         * Check for 0 (window was not icon) and
         * Check for invalid HWND (window has been destroyed)
         */
        if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);
        ptSrc = pcp->ptMin;

        fBreak = FALSE;
        for (phwndSort = pbwl->rghwnd; phwndSort < phwnd; phwndSort++) {
            if (*phwndSort == NULL ||
                    (pwndSort = RevalidateHwnd(*phwndSort)) == NULL)
                continue;

            pcpSort = (CHECKPOINT*)_GetProp(pwndSort, PROP_CHECKPOINT,
                    PROPF_INTERNAL);

            ptSort = pcpSort->ptMin;

            //
            // Is this the position in which to sort this min window?
            //
            switch (SYSMET(ARRANGE) & ~ARW_HIDE) {
                case ARW_BOTTOMLEFT | ARW_RIGHT:
                    // Lower left, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x > ptSrc.x)) ||
                        (ptSort.y < ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_BOTTOMLEFT | ARW_UP:
                    // Lower left, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y < ptSrc.y)) ||
                        (ptSort.x > ptSrc.x))
                        fBreak = TRUE;
                    break;

                case ARW_BOTTOMRIGHT | ARW_LEFT:
                    // Lower right, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x < ptSrc.x)) ||
                        (ptSort.y < ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_BOTTOMRIGHT | ARW_UP:
                    // Lower right, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y < ptSrc.y)) ||
                        (ptSort.x < ptSrc.x))
                        fBreak = TRUE;
                    break;

                case ARW_TOPLEFT | ARW_RIGHT:
                    // Top left, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x > ptSrc.x)) ||
                        (ptSort.y > ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_TOPLEFT | ARW_DOWN:
                    // Top left, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y > ptSrc.y)) ||
                        (ptSort.x > ptSrc.x))
                        fBreak = TRUE;
                    break;

                case ARW_TOPRIGHT | ARW_LEFT:
                    // Top right, moving horizontally
                    if (((ptSort.y == ptSrc.y) && (ptSort.x < ptSrc.x)) ||
                        (ptSort.y > ptSrc.y))
                        fBreak = TRUE;
                    break;

                case ARW_TOPRIGHT | ARW_DOWN:
                    // Top right, moving vertically
                    if (((ptSort.x == ptSrc.x) && (ptSort.y > ptSrc.y)) ||
                        (ptSort.x < ptSrc.x))
                        fBreak = TRUE;
                    break;
            }

            if (fBreak)
                break;
        }

        /*
         * insert the window at this position by sliding the rest up.
         * LATER IanJa, use hwnd intermediate variables, avoid PW() & HW()
         */
        while (phwndSort < phwnd) {
            pwndSort = PW(*phwndSort);
            *phwndSort = HW(pwndTest);
            pwndTest = pwndSort;
            phwndSort++;
        }

        /*
         * replace the window handle in the original position
         */
        *phwnd = HW(pwndTest);
    }

    //
    // Now park the icons.
    //

JustParkEm:

    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
        if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        if (fHideMe) {
            pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);
            if (pcp != NULL) {
                pcp->fMinInitialized = TRUE;
                pcp->ptMin.x = ptMin.x;
                pcp->ptMin.y = ptMin.y;
            }

            continue;
        }

        pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);
        if (pcp != NULL) {
            pcp->fMinInitialized = TRUE;
            pcp->ptMin.x = ptMin.x;
            pcp->ptMin.y = ptMin.y;
        }

        // Setup to process the next position
        if (--iIconPass <= 0) {
            // Need to setup next pass
            iIconPass = cIconsPerPass;

            if (fHorizontal) {
                ptMin.x = xOrg;
                ptMin.y += dy;
            } else {
                ptMin.x += dx;
                ptMin.y = yOrg;
            }
        } else {
            // Same pass
            if (fHorizontal)
                ptMin.x += dx;
            else
                ptMin.y += dy;
        }
    }

    psmwp = _BeginDeferWindowPos(2 * nIcons);
    if (psmwp == NULL)
        goto ParkExit;

    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {

        /*
         * Check for a NULL (window has gone away)
         */
        if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT,
                PROPF_INTERNAL);


        ThreadLockAlways(pwndTest, &tlpwndTest);

        psmwp = _DeferWindowPos(psmwp, pwndTest, NULL,
                pcp->ptMin.x, pcp->ptMin.y, rgptMinMaxWnd[MMI_MINSIZE].x, rgptMinMaxWnd[MMI_MINSIZE].y,
                SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);

        ThreadUnlock(&tlpwndTest);

        if (psmwp == NULL)
            break;
    }
    if (psmwp != NULL) {
        /*
         * Make the swp async so we don't hang waiting for hung apps.
         */
        xxxEndDeferWindowPosEx(psmwp, TRUE);
    }

ParkExit:
    FreeHwndList(pbwl);
    return nIcons;
}