Beispiel #1
0
PWND xxxSetCapture(
    PWND pwnd)
{
    PQ   pq;
    PWND pwndCaptureOld;
    HWND hwndCaptureOld;

    pq = (PQ)PtiCurrent()->pq;

    /*
     * Don't allow the app to set capture to a window
     * from another queue.
     */
    if ((pwnd != NULL) && GETPTI(pwnd)->pq != pq)
        return NULL;

    /*
     * If full screen capture don't allow any other capture
     */
    if (gspwndScreenCapture)
        return NULL;

    pwndCaptureOld = pq->spwndCapture;
    hwndCaptureOld = HW(pwndCaptureOld);

    xxxCapture(PtiCurrent(), pwnd, CLIENT_CAPTURE);

    if (hwndCaptureOld != NULL) {

        if (RevalidateHwnd(hwndCaptureOld))
            return pwndCaptureOld;
    }

    return NULL;
}
Beispiel #2
0
/***************************************************************************\
* xxxMessageEvent
*
* Description:  Called when a hooked DDE message is sent or posted.  flags
*   specifies the applicable MF_ flag.  This is called in the server side
*   context of the sender or poster which may or may not be a DDEML process.
*   pdmhd contains DDE data extracted and copied from the client side.
*
* History:
* 12-1-91   sanfords    Created.
\***************************************************************************/
VOID xxxMessageEvent(
PWND pwndTo,
UINT message,
WPARAM wParam,
LPARAM lParam,
DWORD flag,
PDDEML_MSG_HOOK_DATA pdmhd)
{
    PEVENT_PACKET pep;
    PWND pwndFrom;
    TL tlpep;
    PTHREADINFO pti;

    CheckCritIn();

    pep = (PEVENT_PACKET)UserAllocPoolWithQuota(sizeof(EVENT_PACKET) -
            sizeof(DWORD) + sizeof(MONMSGSTRUCT), TAG_DDE8);
    if (pep == NULL) {
        return;
    }
    pep->EventType = flag;
    pep->fSense = TRUE;
    pep->cbEventData = sizeof(MONMSGSTRUCT);
#define pmsgs ((MONMSGSTRUCT *)&pep->Data)
    pmsgs->cb = sizeof(MONMSGSTRUCT);
    pmsgs->hwndTo = PtoH(pwndTo);
    pmsgs->dwTime = NtGetTickCount();

    pwndFrom = RevalidateHwnd((HWND)wParam);
    if (pwndFrom != NULL) {
        pmsgs->hTask = GETPTI(pwndFrom)->pEThread->Cid.UniqueThread;
    } else {
        pmsgs->hTask = 0;
    }

    pmsgs->wMsg = message;
    pmsgs->wParam = wParam;
    pmsgs->lParam = lParam;
    if (pdmhd != NULL) {
        pmsgs->dmhd = *pdmhd;
    }
#undef pmsgs
    pti = PtiCurrent();
    ThreadLockPool(pti, pep, &tlpep);
    xxxCsEvent(pep, sizeof(MONMSGSTRUCT));
    ThreadUnlockAndFreePool(pti, &tlpep);
}
Beispiel #3
0
LONG SfnINLBOXSTRING(
    PWND pwnd,
    UINT msg,
    DWORD wParam,
    LONG lParam,
    DWORD xParam,
    PROC xpfn,
    DWORD dwSCMSFlags,
    PSMS psms)
{
    DWORD dw;

    /*
     * See if the control is ownerdraw and does not have the LBS_HASSTRINGS
     * style.  If so, treat lParam as a DWORD.
     */
    if (!RevalidateHwnd(HW(pwnd))) {
        return 0L;
    }
    dw = pwnd->style;

    if (!(dw & LBS_HASSTRINGS) &&
            (dw & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))) {

        /*
         * Treat lParam as a dword.
         */
        return SfnDWORD(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms);
    }

    /*
     * Treat as a string pointer.   Some messages allowed or had certain
     * error codes for NULL so send them through the NULL allowed thunk.
     * Ventura Publisher does this
     */
    switch (msg) {
        default:
            return SfnINSTRING(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms);
            break;

        case LB_FINDSTRING:
            return SfnINSTRINGNULL(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms);
            break;
    }
}
Beispiel #4
0
LONG SfnOUTLBOXSTRING(
    PWND pwnd,
    UINT msg,
    DWORD wParam,
    LONG lParam,
    DWORD xParam,
    PROC xpfn,
    DWORD dwSCMSFlags,
    PSMS psms)
{
    DWORD dw;
    BOOL bNotString;
    DWORD dwRet;
    TL tlpwnd;

    /*
     * See if the control is ownerdraw and does not have the LBS_HASSTRINGS
     * style.  If so, treat lParam as a DWORD.
     */
    if (!RevalidateHwnd(HW(pwnd))) {
        return 0L;
    }
    dw = pwnd->style;

    /*
     * See if the control is ownerdraw and does not have the LBS_HASSTRINGS
     * style.  If so, treat lParam as a DWORD.
     */
    bNotString =  (!(dw & LBS_HASSTRINGS) &&
            (dw & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)));

    /*
     * Make this special call which'll know how to copy this string.
     */
    ThreadLock(pwnd, &tlpwnd);
    dwRet = ClientGetListboxString(pwnd, msg, wParam,
            (PLARGE_UNICODE_STRING)lParam,
            xParam, xpfn, dwSCMSFlags, bNotString, psms);
    ThreadUnlock(&tlpwnd);
    return dwRet;
}
Beispiel #5
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);
}
Beispiel #6
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);
        }
    }
}
Beispiel #7
0
BOOL xxxClientShutdown2(
    PBWL pbwl,
    UINT msg,
    DWORD wParam)
{
    HWND *phwnd;
    PWND pwnd;
    TL tlpwnd;
    BOOL fEnd;
    PTHREADINFO ptiCurrent;
    BOOL fDestroyTimers;
    LPARAM lParam;


    ptiCurrent = PtiCurrent();

    /*
     * Make sure we don't send this window any more WM_TIMER
     * messages if the session is ending. This was causing
     * AfterDark to fault when it freed some memory on the
     * WM_ENDSESSION and then tried to reference it on the
     * WM_TIMER.
     * LATER GerardoB: Do we still need to do this??
     * Do this horrible thing only if the process is in the
     * context being logged off.
     * Perhaps someday we should post a WM_CLOSE so the app
     * gets a better chance to clean up (if this process is in
     * the context being logged off, winsrv is going to call
     * TerminateProcess soon after this).
     */
     fDestroyTimers = (wParam & WMCS_EXIT) && (wParam & WMCS_CONTEXTLOGOFF);

     /*
      * fLogOff and fEndSession parameters (WM_ENDSESSION only)
      */
     lParam = wParam & ENDSESSION_LOGOFF;
     wParam &= WMCS_EXIT;

    /*
     * Now enumerate these windows and send the WM_QUERYENDSESSION or
     * WM_ENDSESSION messages.
     */
    for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
        if ((pwnd = RevalidateHwnd(*phwnd)) == NULL)
            continue;

        ThreadLockAlways(pwnd, &tlpwnd);

        /*
         * Send the message.
         */
        switch (msg) {
        case WM_QUERYENDSESSION:

            /*
             * Windows does not send the WM_QUERYENDSESSION to the app
             * that called ExitWindows
             */
            if (ptiCurrent == gptiShutdownNotify) {
                fEnd = TRUE;
            } else {
                fEnd = xxxSendMessage(pwnd, WM_QUERYENDSESSION, FALSE, lParam);
            }
            break;

        case WM_ENDSESSION:
            xxxSendMessage(pwnd, WM_ENDSESSION, wParam, lParam);
            fEnd = TRUE;

            if (fDestroyTimers) {
                DestroyWindowsTimers(pwnd);
            }

            break;
        }

        ThreadUnlock(&tlpwnd);

        if (!fEnd)
            return FALSE;
    }

    return TRUE;
}
Beispiel #8
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;
}