Exemplo n.º 1
0
void xxxClientShutdown(
    PWND pwnd,
    DWORD wParam,
    DWORD lParam)
{
    PBWL pbwl;
    PTHREADINFO ptiT;
    BOOL fExit;

    /*
     * Build a list of windows first.
     */
    fExit = TRUE;
    ptiT = GETPTI(pwnd);

    /*
     * If the request was cancelled, then do nothing.
     */
    if (ptiT->TIF_flags & TIF_SHUTDOWNCOMPLETE) {
        return;
    }

    if ((pbwl = BuildHwndList(ptiT->rpdesk->pDeskInfo->spwnd->spwndChild,
            BWL_ENUMLIST, ptiT)) == NULL) {
        /*
         * Can't allocate memory to notify this thread's windows of shutdown.
         */
        goto SafeExit;
    }

    if (wParam & WMCS_QUERYEND) {
        fExit = xxxClientShutdown2(pbwl, WM_QUERYENDSESSION, wParam);
    } else {
        xxxClientShutdown2(pbwl, WM_ENDSESSION, wParam);
        fExit = TRUE;
    }

    FreeHwndList(pbwl);

SafeExit:
    ptiT->TIF_flags |= (TIF_SHUTDOWNCOMPLETE | (fExit ? TIF_ALLOWSHUTDOWN : 0));
}
Exemplo n.º 2
0
void xxxShowOwnedWindows(
    PWND pwndOwner,
    UINT cmdShow)
{
    BOOL fShow;
    int cmdZoom;
    HWND *phwnd;
    PBWL pbwl;
    PWND pwnd, pwndTopOwner;
    TL tlpwnd;

    CheckLock(pwndOwner);

    /*
     * Not interested in child windows
     */
    if (TestwndChild(pwndOwner))
        return;

    if ((pbwl = BuildHwndList(PWNDDESKTOP(pwndOwner)->spwndChild, BWL_ENUMLIST, NULL)) == NULL)
        return;

    /*
     * NOTE: The following code assumes the values of SW_* are 1, 2, 3, and 4
     */
    fShow = (cmdShow >= SW_PARENTOPENING);

    cmdZoom = 0;
    if (cmdShow == SW_OTHERZOOM)
        cmdZoom = SIZEZOOMHIDE;

    if (cmdShow == SW_OTHERUNZOOM)
        cmdZoom = SIZEZOOMSHOW;

    /*
     * If zoom/unzoom, then open/close all popups owned by all other
     * windows.  Otherwise, open/close popups owned by pwndOwner.
     */
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {

        /*
         * Lock the window before we play with it.
         * If the window handle is invalid, skip it
         */
        if ((pwnd = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        /*
         * Kanji windows can't be owned, so skip it.
         */
        if (TestCF(pwnd, CFKANJIWINDOW))
            continue;

        /*
         * If same as window passed in, skip it.
         */
        if (pwnd == pwndOwner)
            continue;

        /*
         * Find ultimate owner of popup, but only go up as far as pwndOwner.
         */
        if ((pwndTopOwner = pwnd->spwndOwner) != NULL) {

            /*
             * The TestwndHI is needed since if it has an icon, pwndOwner
             * is invalid.
             */
            while (!TestwndHI(pwndTopOwner) && pwndTopOwner != pwndOwner &&
                    pwndTopOwner->spwndOwner != NULL)
                pwndTopOwner = pwndTopOwner->spwndOwner;
        }

        /*
         * Zoom/Unzoom case.
         */
        if (cmdZoom != 0) {

            /*
             * If no parent, or parents are the same, skip.
             */
            if (pwndTopOwner == NULL || pwndTopOwner == pwndOwner)
                continue;

            /*
             * If owner is iconic, then this window should stay hidden,
             * UNLESS the minimized window is disabled, in which case we'd
             * better show the window.
             */
            if (   cmdShow == SW_OTHERUNZOOM
                && pwndTopOwner != NULL
                && TestWF(pwndTopOwner, WFMINIMIZED)
                && !TestWF(pwndTopOwner, WFDISABLED)
               )
                continue;
        } else {
            /*
             * Hide/Iconize/Show/Open case.
             */
            /*
             * If parents aren't the same, skip.
             */
            if (pwndTopOwner != pwndOwner)
                continue;
        }

        /*
         * Hide or show if:
         * Showing & this is a hidden popup
         *   OR
         * Hiding & this is a visible window
         */
        if ((fShow && TestWF(pwnd, WFHIDDENPOPUP)) ||
                (!fShow && TestWF(pwnd, WFVISIBLE))) {
            ThreadLockAlways(pwnd, &tlpwnd);
            xxxSendMessage(pwnd, WM_SHOWWINDOW, fShow, (LONG)cmdShow);
            ThreadUnlock(&tlpwnd);
        }
    }

    /*
     * Free the window list.
     */
    FreeHwndList(pbwl);
}
Exemplo n.º 3
0
VOID xxxInternalDoSyncPaint(
    PWND  pwnd,
    DWORD flags)
{
    CheckLock(pwnd);

    /*
     * Do the paint for this window.
     */
    xxxSimpleDoSyncPaint(pwnd);

    /*
     * Normally we like to enumerate all of this window's children and have
     * them erase their backgrounds synchronously.  However, this is a bad
     * thing to do if the window is NOT CLIPCHLIDREN.  Here's the scenario
     * we want to to avoid:
     *
     * 1) Window 'A' is invalidated
     * 2) 'A' erases itself (or not, doesn't matter)
     * 3) 'A's children are enumerated and they erase themselves.
     * 4) 'A' paints over its children (remember, 'A' isn't CLIPCHILDREN)
     * 5) 'A's children paint but their backgrounds aren't their ERASEBKND
     *    color (because 'A' painted over them) and everything looks like
     *    dirt.
     */
    if ((flags & DSP_ALLCHILDREN) ||
        ((flags & DSP_ENUMCLIPPEDCHILDREN) && TestWF(pwnd, WFCLIPCHILDREN))) {

        TL   tlpwnd;
        PBWL pbwl;
        HWND *phwnd;

        if (pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL)) {

            PTHREADINFO ptiCurrent = PtiCurrent();
            HWND        hwnd;

            /*
             * If the client dies during a callback, the hwnd list
             * will be freed in xxxDestroyThreadInfo.
             */
            for (phwnd = pbwl->rghwnd; (hwnd = *phwnd) != (HWND)1; phwnd++) {

                if (hwnd == NULL)
                    continue;

                if ((pwnd = (PWND)RevalidateHwnd(hwnd)) == NULL)
                    continue;

                /*
                 * Note: testing if a window is a child automatically
                 * excludes the desktop window.
                 */
                if (TestWF(pwnd, WFCHILD) && (ptiCurrent != GETPTI(pwnd))) {

                    /*
                     * Don't cause any more intertask sendmessages cause it
                     * does bad things to cbt's windowproc hooks.  (Due to
                     * SetParent allowing child windows in the topwindow
                     * hierarchy.
                     */
                    continue;
                }

                /*
                 * Note that we pass only certain bits down as we recurse:
                 * the other bits pertain to the current window only.
                 */
                ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
                xxxInternalDoSyncPaint(pwnd, flags);
                ThreadUnlock(&tlpwnd);
            }

            FreeHwndList(pbwl);
        }
    }
}
Exemplo n.º 4
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;
}