test: movesize.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# movesize.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Defines

#define | DRAG_START 0
#define | DRAG_MOVE 1
#define | DRAG_END 2
#define | MAX_THREADS 12

## Functions

void | GetMonitorMaxArea (PWND pwnd, PMONITOR pMonitor, LPRECT *pprc)
BOOL | SizeRect (PMOVESIZEDATA pmsd, DWORD pt)
BOOL | MoveRect (PMOVESIZEDATA pmsd, DWORD pt)
VOID | xxxTM_MoveDragRect (PMOVESIZEDATA pmsd, LPARAM lParam)
PCHECKPOINT | CkptRestore (PWND pwnd, LPCRECT lprcWindow)
void | xxxMS_TrackMove (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, PMOVESIZEDATA pmsd)
VOID | xxxMS_FlushWigglies (VOID)
BOOL | xxxTrackInitSize (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, PMOVESIZEDATA pmsd)
VOID | xxxMoveSize (PWND pwnd, UINT cmdMove, DWORD wptStart)
VOID | xxxUpdateOtherThreadsWindows (PWND pwnd, HRGN hrgnFullDrag)
VOID | xxxUpdateThreadsWindows (PTHREADINFO pti, PWND pwnd, HRGN hrgnFullDrag)
VOID | xxxDrawDragRect (PMOVESIZEDATA pmsd, LPRECT lprc, UINT type)
VOID | xxxCancelTrackingForThread (PTHREADINFO ptiCancel)
VOID | xxxCancelTracking (VOID)

## Variables

const int | rgimpimpiw [] = {1, 3, 2, 6}
const int | rgimpiwx [] = {0, 0, 2, -1, 0, 2, -1, 0, 2, 0}
const int | rgimpiwy [] = {0, -1, -1, 1, 1, 1, 3, 3, 3, 1}
const int | rgcmdmpix [] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 1}
const int | rgcmdmpiy [] = {0, 0, 0, 3, 3, 3, 6, 6, 6, 3}

## Define Documentation

#define DRAG_END 2

| Definition at line 19 of file movesize.c.

#define DRAG_MOVE 1

| Definition at line 18 of file movesize.c. Referenced by xxxTM_MoveDragRect().

#define DRAG_START 0

| Definition at line 17 of file movesize.c.

#define MAX_THREADS 12

| Definition at line 1889 of file movesize.c. Referenced by xxxCancelTracking().

## Function Documentation

PCHECKPOINT CkptRestore | ( | PWND | pwnd,
|  | LPCRECT | lprcWindow
| ) |

Definition at line 335 of file movesize.c.

References _GetProp(), _MonitorFromRect(), CopyRect, FALSE, tagCHECKPOINT::fMaxInitialized, tagCHECKPOINT::fMinInitialized, GetMonitorMaxArea(), HMIsMarkDestroy, InternalSetProp(), NULL, PROP_CHECKPOINT, PROPF_INTERNAL, tagCHECKPOINT::ptMax, tagCHECKPOINT::ptMin, PWNDDESKTOP, tagCHECKPOINT::rcNormal, tagWND::spwndParent, TestWF, TRUE, WFMAXIMIZED, WFMINIMIZED, and WFREALLYMAXIMIZABLE.

Referenced by UpdateCheckpoint(), xxxMinMaximize(), and xxxMS_TrackMove().

    00338 {
    00339     PCHECKPOINT pcp;
    00340
    00341     /*
    00342      * Don't return or create a checkpoint if the window is dying.
    00343      */
    00344     if (HMIsMarkDestroy(pwnd))
    00345         return NULL;
    00346
    00347     /*
    00348      * If it doesn't exist, create it.
    00349      */
    00350     if ((pcp = (PCHECKPOINT)_GetProp(pwnd,
    00351                                      PROP_CHECKPOINT,
    00352                                      PROPF_INTERNAL)) == NULL) {
    00353
    00354         if ((pcp = (PCHECKPOINT)UserAllocPoolWithQuota(sizeof(CHECKPOINT),
    00355                                                        TAG_CHECKPT)) == NULL) {
    00356             return NULL;
    00357         }
    00358
    00359         if (!InternalSetProp(pwnd,
    00360                              PROP_CHECKPOINT,
    00361                              (HANDLE)pcp,
    00362                              PROPF_INTERNAL)) {
    00363
    00364             UserFreePool(pcp);
    00365             return NULL;
    00366         }
    00367
    00368         /*
    00369          * Initialize it to -1 so first minimize will park the icon.
    00370          */
    00371         pcp->ptMin.x = -1;
    00372         pcp->ptMin.y = -1;
    00373         pcp->ptMax.x = -1;
    00374         pcp->ptMax.y = -1;
    00375
    00376         /*
    00377          * Initialize pwndTitle to NULL so we create a title window on the
    00378          * first minimize of the window
    00379          */
    00380         pcp->fDragged                     = FALSE;
    00381         pcp->fWasMaximizedBeforeMinimized = FALSE;
    00382         pcp->fWasMinimizedBeforeMaximized = FALSE;
    00383         pcp->fMinInitialized              = FALSE;
    00384         pcp->fMaxInitialized              = FALSE;
    00385
    00386         /*
    00387          * BOGUS!  We're going to copy this twice if the window isn't
    00388          * minimized or maximized.  But if it isn't, we're going to get
    00389          * a weird size in rcNormal...
    00390          */
    00391         CopyRect(&pcp->rcNormal, lprcWindow);
    00392     }
    00393
    00394     /*
    00395      * If the window is minimized/maximized, then set the min/max
    00396      * point.  Otherwise use checkpoint the window-size.
    00397      */
    00398     if (TestWF(pwnd, WFMINIMIZED)) {
    00399         pcp->fMinInitialized = TRUE;
    00400         pcp->ptMin.x = lprcWindow->left;
    00401         pcp->ptMin.y = lprcWindow->top;
    00402     } else if (TestWF(pwnd, WFMAXIMIZED)) {
    00403         pcp->fMaxInitialized = TRUE;
    00404
    00405         if (pwnd->spwndParent == PWNDDESKTOP(pwnd)) {
    00406             if (TestWF(pwnd, WFREALLYMAXIMIZABLE)) {
    00407                 pcp->fMaxInitialized = FALSE;
    00408                 pcp->ptMax.x = -1;
    00409                 pcp->ptMax.y = -1;
    00410             } else {
    00411                 PMONITOR pMonitor;
    00412                 LPRECT   lprc;
    00413
    00414                 pMonitor = _MonitorFromRect(lprcWindow, MONITOR_DEFAULTTOPRIMARY);
    00415                 GetMonitorMaxArea(pwnd, pMonitor, &lprc);
    00416                 pcp->ptMax.x = lprcWindow->left - lprc->left;
    00417                 pcp->ptMax.y = lprcWindow->top - lprc->top;
    00418             }
    00419         } else {
    00420             pcp->ptMax.x = lprcWindow->left;
    00421             pcp->ptMax.y = lprcWindow->top;
    00422         }
    00423     } else {
    00424         CopyRect(&pcp->rcNormal, lprcWindow);
    00425     }
    00426
    00427     return pcp;
    00428 }

void GetMonitorMaxArea | ( | PWND | pwnd,
|  | PMONITOR | pMonitor,
|  | LPRECT * | pprc
| ) |

Definition at line 62 of file movesize.c.

References tagMONITOR::cFullScreen, tagMONITOR::rcMonitor, tagMONITOR::rcWork, TestWF, WFCPRESENT, and WFMAXBOX.

Referenced by CkptRestore(), and xxxInitSendValidateMinMaxInfo().

    00063 {
    00064     if (    !TestWF(pwnd, WFMAXBOX) ||
    00065             !TestWF(pwnd, WFCPRESENT) ||
    00066             pMonitor->cFullScreen) {
    00067
    00068         *pprc = &pMonitor->rcMonitor;
    00069     } else {
    00070         *pprc = &pMonitor->rcWork;
    00071     }
    00072 }

BOOL MoveRect | ( | PMOVESIZEDATA | pmsd,
|  | DWORD | pt
| ) |

Definition at line 242 of file movesize.c.

References BOOL, _MOVESIZEDATA::fOffScreen, HISHORT, tagWND::hrgnClip, IntersectRect(), LOSHORT, OffsetRect(), _MOVESIZEDATA::rcDragCursor, _MOVESIZEDATA::rcParent, _MOVESIZEDATA::spwnd, tagWND::spwndParent, and TRUE.

Referenced by xxxTM_MoveDragRect().

    00245 {
    00246     RECT rcAnd;
    00247
    00248     OffsetRect(&pmsd->rcDragCursor,
    00249                LOSHORT(pt) - pmsd->rcDragCursor.left,
    00250                HISHORT(pt) - pmsd->rcDragCursor.top);
    00251
    00252     /*
    00253      * Don't move the entire rectangle off the screen.
    00254      * However, if the window started offscreen completely, let it move.
    00255      */
    00256     if (pmsd->fOffScreen)
    00257         return TRUE;
    00258
    00259     if (pmsd->spwnd->spwndParent->hrgnClip) {
    00260         return GreRectInRegion(
    00261                 pmsd->spwnd->spwndParent->hrgnClip, &pmsd->rcDragCursor);
    00262     }
    00263
    00264     return IntersectRect(&rcAnd, &pmsd->rcDragCursor, &pmsd->rcParent);
    00265 }

BOOL SizeRect | ( | PMOVESIZEDATA | pmsd,
|  | DWORD | pt
| ) |

Definition at line 84 of file movesize.c.

References abs, BOOL, _MOVESIZEDATA::cmd, HISHORT, LOSHORT, PINT, _MOVESIZEDATA::ptMaxTrack, _MOVESIZEDATA::ptMinTrack, _MOVESIZEDATA::rcDragCursor, _MOVESIZEDATA::rcParent, rgimpiwx, rgimpiwy, _MOVESIZEDATA::spwnd, TestWF, TRUE, and WFCHILD.

Referenced by xxxTM_MoveDragRect().

    00087 {
    00088     int  ax;
    00089     int  dx;
    00090     int  index;
    00091     int  indexOpp;
    00092     PINT psideDragCursor = ((PINT)(&pmsd->rcDragCursor));
    00093     PINT psideParent     = ((PINT)(&pmsd->rcParent));
    00094
    00095
    00096     /*
    00097      * DO HORIZONTAL
    00098      */
    00099
    00100     /*
    00101      * We know what part of the rect we're moving based on
    00102      * what's in cmd.  We use cmd as an index into rgimpiw? which
    00103      * tells us what part of the rect we're dragging.
    00104      */
    00105
    00106     /*
    00107      * Get the approriate array entry.
    00108      */
    00109     index = (int)rgimpiwx[pmsd->cmd];   // AX
    00110
    00111     /*
    00112      * Is it one of the entries we don't map (i.e.  -1)?
    00113      */
    00114     if (index < 0)
    00115         goto mrLoopBottom;
    00116
    00117     psideDragCursor[index] = LOSHORT(pt);
    00118
    00119     indexOpp = index ^ 0x2;
    00120
    00121     /*
    00122      * Now check to see if we're below the min or above the max. Get the width
    00123      * of the rect in this direction (either x or y) and see if it's bad. If
    00124      * so, map the side we're moving to the min or max.
    00125      */
    00126     ax = psideDragCursor[index] - psideDragCursor[indexOpp];
    00127
    00128     if (indexOpp & 0x2)
    00129         ax = -ax;
    00130
    00131     if ((ax >= (dx = pmsd->ptMinTrack.x)) &&
    00132         (ax <= (dx = pmsd->ptMaxTrack.x))) {
    00133
    00134         /*
    00135          * Only test for the parent's client boundary if we are a child
    00136          * window...Otherwise we are bound to the client of the desktop
    00137          * which causes strange drag problems.
    00138          */
    00139         if (!TestWF(pmsd->spwnd,WFCHILD))
    00140             goto mrLoopBottom;
    00141
    00142         /*
    00143          * Now see if we're extending beyond our parent's client rect.
    00144          * Compute the size the rect can be expanded to in this direction.
    00145          */
    00146         dx = abs(psideParent[index] - psideDragCursor[indexOpp]);
    00147
    00148         if (ax <= dx)
    00149             goto mrLoopBottom;
    00150
    00151         /*
    00152          * The width is invalid - map the side we're moving to the other
    00153          * side +/- the width.
    00154          */
    00155     }
    00156
    00157     if (indexOpp & 0x2)
    00158         dx = -dx;
    00159
    00160     psideDragCursor[index] = dx + psideDragCursor[indexOpp];
    00161
    00162 mrLoopBottom:
    00163
    00164     /*
    00165      * DO VERTICAL
    00166      */
    00167
    00168     /*
    00169      * We know what part of the rect we're moving based on
    00170      * what's in cmd.  We use cmd as an index into rgimpiw? which
    00171      * tells us what part of the rect we're dragging.
    00172      */
    00173
    00174     /*
    00175      * Get the approriate array entry.
    00176      */
    00177     index = (int)rgimpiwy[pmsd->cmd];   // AX
    00178
    00179     /*
    00180      * Is it one of the entries we don't map (i.e.  -1)?
    00181      */
    00182     if (index < 0)
    00183         return TRUE;
    00184
    00185     psideDragCursor[index] = HISHORT(pt);
    00186
    00187     indexOpp = index ^ 0x2;
    00188
    00189     /*
    00190      * Now check to see if we're below the min or above the max. Get the width
    00191      * of the rect in this direction (either x or y) and see if it's bad. If
    00192      * so, map the side we're moving to the min or max.
    00193      */
    00194     ax = psideDragCursor[index] - psideDragCursor[indexOpp];
    00195
    00196     if (indexOpp & 0x2)
    00197         ax = -ax;
    00198
    00199     if ((ax >= (dx = pmsd->ptMinTrack.y)) &&
    00200         (ax <= (dx = pmsd->ptMaxTrack.y))) {
    00201
    00202         /*
    00203          * Only test for the parent's client boundary if we are a child
    00204          * window...Otherwise we are bound to the client of the desktop
    00205          * which causes strange drag problems.
    00206          */
    00207         if (!TestWF(pmsd->spwnd,WFCHILD))
    00208             return TRUE;
    00209
    00210         /*
    00211          * Now see if we're extending beyond our parent's client rect.
    00212          * Compute the size the rect can be expanded to in this direction.
    00213          */
    00214         dx = abs(psideParent[index] - psideDragCursor[indexOpp]);
    00215
    00216         if (ax <= dx)
    00217             return TRUE;
    00218
    00219         /*
    00220          * The width is invalid - map the side we're moving to the other
    00221          * side +/- the width.
    00222          */
    00223     }
    00224
    00225     if (indexOpp & 0x2)
    00226         dx = -dx;
    00227
    00228     psideDragCursor[index] = dx + psideDragCursor[indexOpp];
    00229
    00230     return TRUE;
    00231 }

VOID xxxCancelTracking | ( | VOID |  | ) |

Definition at line 1891 of file movesize.c.

References grpdeskRitInput, INT, MAX_THREADS, NULL, tagTHREADINFO::pmsd, PtiCurrent, tagDESKTOP::PtiList, _MOVESIZEDATA::spwnd, ThreadLockAlwaysWithPti, ThreadLockPti, ThreadUnlock, ThreadUnlockPti, tagTHREADINFO::TIF_flags, TIF_INCLEANUP, UINT, VOID(), and xxxCancelTrackingForThread().

Referenced by xxxProcessEventMessage(), and xxxSetForegroundWindow2().

    01892 {
    01893     PTHREADINFO pti;
    01894     PTHREADINFO ptiList[MAX_THREADS];
    01895     TL          tlptiList[MAX_THREADS];
    01896     TL          tlspwndList[MAX_THREADS];
    01897     UINT        cThreads = 0;
    01898     INT         i;
    01899     PLIST_ENTRY pHead;
    01900     PLIST_ENTRY pEntry;
    01901     PTHREADINFO ptiCurrent = PtiCurrent();
    01902
    01903     /*
    01904      * Build a list of threads that we need to look at. We can't just
    01905      * walk the pointer list while we're doing the work, because we
    01906      * might leave the critical section and the pointer could get
    01907      * deleted out from under us.
    01908      */
    01909     pHead = &grpdeskRitInput->PtiList;
    01910     for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
    01911
    01912         pti = CONTAINING_RECORD(pEntry, THREADINFO, PtiLink);
    01913
    01914         if (pti->pmsd != NULL) {
    01915
    01916             UserAssert(cThreads < MAX_THREADS);
    01917
    01918             if (cThreads < MAX_THREADS) {
    01919                 ThreadLockPti(ptiCurrent, pti, &tlptiList[cThreads]);
    01920                 ThreadLockAlwaysWithPti(ptiCurrent, pti->pmsd->spwnd, &tlspwndList[cThreads]);
    01921                 ptiList[cThreads++] = pti;
    01922             }
    01923         }
    01924     }
    01925
    01926     /*
    01927      * Walk the list backwards so the unlocks will be done in the right order.
    01928      */
    01929     for (i = cThreads - 1; i >= 0; i--) {
    01930         if (!(ptiList[i]->TIF_flags & TIF_INCLEANUP)) {
    01931             xxxCancelTrackingForThread(ptiList[i]);
    01932         }
    01933
    01934         ThreadUnlock(&tlspwndList[i]);
    01935         ThreadUnlockPti(ptiCurrent, &tlptiList[i]);
    01936     }
    01937 }

VOID xxxCancelTrackingForThread | ( | PTHREADINFO | ptiCancel | ) |

Definition at line 1826 of file movesize.c.

References _PostMessage(), DDR_ENDCANCEL, _MOVESIZEDATA::fDragFullWindows, _MOVESIZEDATA::fTrackCancelled, gpDispInfo, tagDISPLAYINFO::hDev, IsInsideMenuLoop(), NO_CAP_CLIENT, NULL, tagTHREADINFO::pmsd, tagTHREADINFO::pq, SetWakeBit(), _MOVESIZEDATA::spwnd, tagTHREADINFO::TIF_flags, TIF_TRACKRECTVISIBLE, TRUE, VOID(), xxxCapture(), and xxxDrawDragRect().

Referenced by xxxCancelTracking(), and xxxDestroyThreadInfo().

    01828 {
    01829     PMOVESIZEDATA pmsdCancel;
    01830
    01831     UserAssert(ptiCancel);
    01832
    01833     /*
    01834      * If this thread isn't around any more, skip it.
    01835      */
    01836     if (ptiCancel == NULL)
    01837         return;
    01838
    01839     if ((pmsdCancel = ptiCancel->pmsd) != NULL) {
    01840
    01841         /*
    01842          * Found one, now stop tracking.
    01843          */
    01844         pmsdCancel->fTrackCancelled = TRUE;
    01845
    01846         /*
    01847          * Only remove the tracking rectangle if it's
    01848          * been made visible.
    01849          */
    01850         if (ptiCancel->TIF_flags & TIF_TRACKRECTVISIBLE) {
    01851             bSetDevDragRect(gpDispInfo->hDev, NULL, NULL);
    01852             if (!(pmsdCancel->fDragFullWindows)) {
    01853                 xxxDrawDragRect(pmsdCancel, NULL, DDR_ENDCANCEL);
    01854             }
    01855         }
    01856
    01857         /*
    01858          * Leave TIF_TRACKING set to prevent xxxMoveSize()
    01859          * recursion.
    01860          */
    01861         ptiCancel->TIF_flags &= ~TIF_TRACKRECTVISIBLE;
    01862         if (ptiCancel->pq) {
    01863             SetWakeBit(ptiCancel, QS_MOUSEMOVE);
    01864         }
    01865
    01866         /*
    01867          * If the tracking window is still in menuloop, send the
    01868          * WM_CANCELMODE message so that it can exit the menu.
    01869          * This fixes the bug where we have 2 icons with their
    01870          * system menu up.
    01871          * 8/5/94 johannec
    01872          */
    01873         if (IsInsideMenuLoop(ptiCancel) && ptiCancel->pmsd)
    01874             _PostMessage(ptiCancel->pmsd->spwnd, WM_CANCELMODE, 0, 0);
    01875
    01876         /*
    01877          * Turn off capture
    01878          */
    01879         xxxCapture(ptiCancel, NULL, NO_CAP_CLIENT);
    01880     }
    01881 }

VOID xxxDrawDragRect | ( | PMOVESIZEDATA | pmsd,
|  | LPRECT | lprc,
|  | UINT | type
| ) |

Definition at line 1562 of file movesize.c.

References _GetDCEx(), _ReleaseDC(), _ScreenToClient(), CheckLock, CopyRect, DDR_START, EqualRect, _MOVESIZEDATA::fDragFullWindows, _MOVESIZEDATA::fForeground, FindSpb(), FreeSpb(), FTopLevel, GETPTI, gpDispInfo, gpsi, tagDISPLAYINFO::hDev, HRGN_FULL, tagWND::hrgnClip, IntersectRect(), IntersectRgn, NULL, tagTHREADINFO::pmsd, PtiCurrent, PWNDDESKTOP, _MOVESIZEDATA::rcDrag, _MOVESIZEDATA::rcParent, tagWND::rcWindow, _MOVESIZEDATA::spwnd, tagWND::spwndParent, SubtractRgn, TestWF, ThreadLock, ThreadUnlock, tagTHREADINFO::TIF_flags, TIF_MOVESIZETRACKING, type, VOID(), WFHASSPB, WFMINIMIZED, WFSIZEBOX, xxxSetWindowPos(), and xxxUpdateThreadsWindows().

Referenced by xxxCancelTrackingForThread(), xxxMoveSize(), xxxMS_TrackMove(), xxxReleaseCapture(), xxxTM_MoveDragRect(), and xxxTrackInitSize().

    01566 {
    01567     HDC  hdc;
    01568     int  lvBorder;
    01569     HRGN hrgnClip;
    01570
    01571     /*
    01572      * If we're dragging an icon, or we're not foreground, don't draw
    01573      * the dragging rect.
    01574      */
    01575     if (!pmsd->fForeground) {
    01576
    01577         if (lprc != NULL)
    01578             CopyRect(&pmsd->rcDrag, lprc);
    01579
    01580         return;
    01581     }
    01582
    01583     /*
    01584      * If it already equals, just return.
    01585      */
    01586     if ((lprc != NULL) && EqualRect(&pmsd->rcDrag, lprc))
    01587         return;
    01588
    01589     if (!(pmsd->fDragFullWindows)) {
    01590
    01591         /*
    01592          * If we were not able to lock the screen (because some other process
    01593          * or thread had the screen locked), then get a dc but make sure
    01594          * it is totally clipped to nothing.
    01595          * NO longer a posibility
    01596          */
    01597
    01598         /*
    01599          * Clip to client rect of parent.  (Client given in screen coords.)
    01600          */
    01601         hrgnClip = GreCreateRectRgnIndirect(&pmsd->rcParent);
    01602
    01603         /*
    01604          * Clip to the parent's window clipping rgn if it has one.
    01605          */
    01606         if (hrgnClip != NULL && pmsd->spwnd->spwndParent->hrgnClip != NULL)
    01607             IntersectRgn(hrgnClip,
    01608                          hrgnClip,
    01609                          pmsd->spwnd->spwndParent->hrgnClip);
    01610
    01611         if (hrgnClip == NULL)
    01612             hrgnClip = HRGN_FULL;
    01613
    01614         /*
    01615          * If lprc == NULL, just draw rcDrag once.  If lprc != NULL,
    01616          * undraw *lprc, draw rcDrag, copy in *lprc.
    01617          */
    01618
    01619         /*
    01620          * Use size 1 for minimized or non-sizeable windows.  Otherwise
    01621          * use the # of borders (2 for outer edge, 1 for border, clBorder for
    01622          * size border.
    01623          */
    01624         if (TestWF(pmsd->spwnd, WFMINIMIZED) || !TestWF(pmsd->spwnd, WFSIZEBOX))
    01625             lvBorder = 1;
    01626         else
    01627             lvBorder = 3 + gpsi->gclBorder;
    01628
    01629         /*
    01630          * Get a screen DC clipped to the parent, select in a gray brush.
    01631          */
    01632         hdc = _GetDCEx(
    01633                 PWNDDESKTOP(pmsd->spwnd),
    01634                 hrgnClip,
    01635                 DCX_WINDOW | DCX_CACHE | DCX_INTERSECTRGN | DCX_LOCKWINDOWUPDATE);
    01636
    01637         if (lprc != NULL) {
    01638
    01639             /*
    01640              * Move the frame to a new location by delta drawing
    01641              */
    01642             GreLockDisplay(gpDispInfo->hDev);
    01643             bMoveDevDragRect(gpDispInfo->hDev, (PRECTL) lprc);
    01644             CopyRect(&pmsd->rcDrag, lprc);
    01645             GreUnlockDisplay(gpDispInfo->hDev);
    01646
    01647         } else {
    01648
    01649             if (type == DDR_START) {
    01650                 bSetDevDragRect(gpDispInfo->hDev,
    01651                                 (PRECTL)&pmsd->rcDrag,
    01652                                 (PRECTL)&pmsd->rcParent);
    01653             }
    01654         }
    01655
    01656         /*
    01657          * Release the DC & delete hrgnClip
    01658          */
    01659         _ReleaseDC(hdc);
    01660
    01661     } else {
    01662
    01663         RECT        rcSWP;
    01664         HRGN        hrgnFullDragNew;
    01665         HRGN        hrgnFullDragOld;
    01666         PTHREADINFO ptiCancel = GETPTI(pmsd->spwnd);
    01667         PTHREADINFO ptiCurrent = PtiCurrent();
    01668         PWND        pwnd;
    01669         TL          tlpwnd;
    01670
    01671 #if DBG
    01672         /*
    01673          * If ptiCancel != ptiCurrent, we must have come from xxxCancelTracking,
    01674          * which has already locked ptiCancel.
    01675          */
    01676         if (ptiCancel != ptiCurrent) {
    01677             CheckLock(ptiCancel);
    01678         }
    01679 #endif
    01680
    01681         /*
    01682          * To prevent applications (like Micrografx Draw) from doing
    01683          * a PeekMessage loop and getting the mouse move messages that
    01684          * are destined for the xxxMoveSize PeekMessage loop, we OR in
    01685          * this flag. See comments in input.c for xxxInternalGetMessage.
    01686          */
    01687         ptiCancel->TIF_flags |= TIF_MOVESIZETRACKING;
    01688
    01689         if (lprc != NULL)
    01690             CopyRect(&(pmsd->rcDrag), lprc);
    01691
    01692         CopyRect(&rcSWP, &(pmsd->rcDrag));
    01693
    01694         /*
    01695          * Convert coordinates to client if the window is a child window or
    01696          * if it's a popup-with parent.  The test for the popup is necessary
    01697          * to solve a problem where a popup was assigned a parent of a MDI-
    01698          * CLIENT window.
    01699          */
    01700         if (pmsd->spwnd->spwndParent != NULL && !FTopLevel(pmsd->spwnd)) {
    01701             _ScreenToClient(pmsd->spwnd->spwndParent, (LPPOINT)&rcSWP);
    01702             _ScreenToClient(pmsd->spwnd->spwndParent, ((LPPOINT)&rcSWP)+1);
    01703
    01704 #if defined(USE_MIRRORING)
    01705             //
    01706             // If the parent of this window is mirrored, then mirror the
    01707             // rectangle coordinates so that child MDI windows work
    01708             // properly
    01709             //
    01710             if( TestWF(pmsd->spwnd->spwndParent,WEFLAYOUTRTL) )
    01711             {
    01712               int iLeft   = rcSWP.left;
    01713               rcSWP.left  = rcSWP.right;
    01714               rcSWP.right = iLeft;
    01715             }
    01716 #endif
    01717         }
    01718
    01719         /*
    01720          * Don't bother being optimal here.  There's one case where we
    01721          * really shouldn't blow away the SPB--the window is being sized
    01722          * bigger.  We do want to do this when moving or sizing the window
    01723          * smaller.  Why bother detecting the first case?
    01724          */
    01725         if (TestWF(pmsd->spwnd, WFHASSPB)){
    01726
    01727             PSPB pspb;
    01728             RECT rc;
    01729
    01730             /*
    01731              * If we're intersecting the original window rect and the window
    01732              * has an SPB saved onboard, then just free it.  Otherwise the
    01733              * window will move, the entire SPB will blt over it, we'll
    01734              * invalidate the intersection, and the window will repaint,
    01735              * causing mad flicker.
    01736              */
    01737             pspb = FindSpb(pmsd->spwnd);
    01738
    01739             CopyRect(&rc, &pmsd->spwnd->rcWindow);
    01740             if (lprc && IntersectRect(&rc, &rc, lprc)){
    01741                 FreeSpb(pspb);
    01742             }
    01743         }
    01744
    01745         hrgnFullDragOld = GreCreateRectRgnIndirect(&pmsd->spwnd->rcWindow);
    01746
    01747         if (pmsd->spwnd->hrgnClip != NULL)
    01748             IntersectRgn(hrgnFullDragOld,
    01749                          hrgnFullDragOld,
    01750                          pmsd->spwnd->hrgnClip);
    01751
    01752         xxxSetWindowPos(pmsd->spwnd,
    01753                         NULL,
    01754                         rcSWP.left, rcSWP.top,
    01755                         rcSWP.right-rcSWP.left, rcSWP.bottom-rcSWP.top,
    01756                         SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
    01757
    01758         /*
    01759          * We locked ptiCancel, so ptiCancel->pmsd has not been unexpectedly
    01760          * freed in DeleteThreadInfo(), but xxxMoveSize() may have terminated
    01761          * during our callback to xxxSetWindowPos and freed the pmsd there.
    01762          */
    01763         if (ptiCancel->pmsd != pmsd) {
    01764             RIPMSG3(RIP_ERROR,
    01765                     "xxxDrawDragRect: ptiCancel(%#p)->pmsd(%#p) != pmsd(%#p)\n",
    01766                     ptiCancel, ptiCancel->pmsd, pmsd);
    01767             goto CleanupAfterPmsdDisappearance;
    01768         }
    01769         hrgnFullDragNew = GreCreateRectRgnIndirect(&pmsd->spwnd->rcWindow);
    01770
    01771         if (pmsd->spwnd->hrgnClip != NULL) {
    01772             IntersectRgn(hrgnFullDragNew,
    01773                          hrgnFullDragNew,
    01774                          pmsd->spwnd->hrgnClip);
    01775         }
    01776
    01777         /*
    01778          * Set the full drag update region that is used in xxxRedrawHungWindow.
    01779          */
    01780         if (hrgnFullDragNew == NULL) {
    01781
    01782             /*
    01783              * We couldn't create the new full drag region so don't
    01784              * use the full drag region to xxxRedrawHungWindow. Using
    01785              * NULL with force a redraw of the entire window's hrgnUpdate.
    01786              * (which is what we used to do, overdrawing but at least
    01787              * covering the invalidated areas).
    01788              */
    01789             if (hrgnFullDragOld != NULL) {
    01790                 GreDeleteObject(hrgnFullDragOld);
    01791                 hrgnFullDragOld = NULL;
    01792             }
    01793
    01794         } else {
    01795
    01796             if (hrgnFullDragOld != NULL) {
    01797
    01798                 /*
    01799                  * Subtract the new window rect from the old window rect
    01800                  * to create the update region caused by the drag.
    01801                  */
    01802                 SubtractRgn(hrgnFullDragOld, hrgnFullDragOld, hrgnFullDragNew);
    01803             }
    01804         }
    01805
    01806         pwnd = PWNDDESKTOP(pmsd->spwnd)->spwndChild;
    01807         ThreadLock(pwnd, &tlpwnd);
    01808         xxxUpdateThreadsWindows(ptiCurrent, pwnd, hrgnFullDragOld);
    01809         ThreadUnlock(&tlpwnd);
    01810
    01811         GreDeleteObject(hrgnFullDragNew);
    01812
    01813 CleanupAfterPmsdDisappearance:
    01814         GreDeleteObject(hrgnFullDragOld);
    01815
    01816         ptiCancel->TIF_flags &= ~TIF_MOVESIZETRACKING;
    01817     }
    01818 }

VOID xxxMoveSize | ( | PWND | pwnd,
|  | UINT | cmdMove,
|  | DWORD | wptStart
| ) |

Definition at line 1053 of file movesize.c.

References _CallMsgFilter(), BORDER_EXTRA, CheckLock, CLEAR_PUDF, CLIENT_CAPTURE_INTERNAL, _MOVESIZEDATA::cmd, tagDISPLAYINFO::cMonitors, CopyRect, DDR_START, DWORD, _MOVESIZEDATA::dxMouse, _MOVESIZEDATA::dyMouse, FALSE, _MOVESIZEDATA::fDragFullWindows, _MOVESIZEDATA::fForeground, _MOVESIZEDATA::fInitSize, _MOVESIZEDATA::fmsKbd, FNID_COMBOBOX, _MOVESIZEDATA::fOffScreen, _MOVESIZEDATA::fTrackCancelled, FWINABLE, GetCaptionHeight(), GETFNID, GetPrimaryMonitor(), GETPTI, ghrgnUpdateSave, gnUpdateSave, gpDispInfo, gpqForeground, gpsi, gptiForeground, tagDISPLAYINFO::hDev, HISHORT, tagWND::hrgnClip, _MOVESIZEDATA::impx, _MOVESIZEDATA::impy, IntersectRect(), IsWinEventNotifyDeferredOK, L, Lock, LOSHORT, MOVESIZEDATA, msg, NULL, tagTHREADINFO::pmsd, tagTHREADINFO::pq, PtiCurrent, _MOVESIZEDATA::ptMaxTrack, _MOVESIZEDATA::ptMinTrack, _MOVESIZEDATA::ptRestore, PUDF_DRAGFULLWINDOWS, PUDF_DRAGGINGFULLWINDOW, PWNDDESKTOP, tagWND::rcClient, _MOVESIZEDATA::rcDrag, _MOVESIZEDATA::rcDragCursor, _MOVESIZEDATA::rcParent, tagDISPLAYINFO::rcScreen, _MOVESIZEDATA::rcWindow, tagWND::rcWindow, tagMONITOR::rcWork, rgcmdmpix, rgcmdmpiy, rgimpiwx, rgimpiwy, SET_OR_CLEAR_PUDF, SetForegroundPriority(), _MOVESIZEDATA::spwnd, tagQ::spwndCapture, tagQ::spwndFocus, tagWND::spwndParent, SYSCUR, SYSMET, TEST_BOOL_PUDF, TestWF, ThreadLockAlwaysWithPti, ThreadUnlock, tagTHREADINFO::TIF_flags, TIF_MOVESIZETRACKING, TIF_TRACKRECTVISIBLE, TRUE, Unlock, VOID(), WEFTOOLWINDOW, WEFTOPMOST, WFMINIMIZED, WFSIZEBOX, xxxCallHook(), xxxCapture(), xxxDispatchMessage(), xxxDrawDragRect(), xxxInitSendValidateMinMaxInfo(), xxxMS_FlushWigglies(), xxxMS_TrackMove(), xxxPeekMessage, xxxSendMessage(), xxxTrackInitSize(), xxxTranslateMessage(), xxxWaitMessage(), xxxWindowEvent(), zzzClipCursor(), zzzInternalSetCursorPos(), zzzSetCursor(), zzzSetFMouseMoved(), and zzzShowCursor().

Referenced by xxxSysCommand().

    01057 {
    01058     MSG             msg;
    01059     int             x;
    01060     int             y;
    01061     int             i;
    01062     RECT            rcSys;
    01063     PTHREADINFO     ptiCurrent = PtiCurrent();
    01064     PMOVESIZEDATA   pmsd;
    01065     TL              tlpwndT;
    01066     PWND            pwndT;
    01067     POINT           ptStart;
    01068     MINMAXINFO      mmi;
    01069
    01070     CheckLock(pwnd);
    01071     UserAssert(IsWinEventNotifyDeferredOK());
    01072
    01073     /*
    01074      * Don't allow the app to track a window
    01075      * from another queue.
    01076      */
    01077     if (GETPTI(pwnd)->pq != ptiCurrent->pq)
    01078         return;
    01079
    01080     if (ptiCurrent->pmsd != NULL)
    01081         return;
    01082
    01083     /*
    01084      * If the window with the focus is a combobox, hide the dropdown
    01085      * listbox before tracking starts.  The dropdown listbox is not a
    01086      * child of the window being moved, therefore it won't be moved along
    01087      * with the window.
    01088      *
    01089      * NOTE: Win 3.1 doesn't perform this check.
    01090      */
    01091     if ((pwndT = ptiCurrent->pq->spwndFocus) != NULL) {
    01092
    01093         if (GETFNID(pwndT) == FNID_COMBOBOX) {
    01094             ;
    01095         } else if ((pwndT->spwndParent != NULL) &&
    01096                 (GETFNID(pwndT->spwndParent) == FNID_COMBOBOX)) {
    01097
    01098             pwndT = pwndT->spwndParent;
    01099         } else {
    01100             pwndT = NULL;
    01101         }
    01102
    01103         if (pwndT != NULL) {
    01104             ThreadLockAlwaysWithPti(ptiCurrent, pwndT, &tlpwndT);
    01105             xxxSendMessage(pwndT, CB_SHOWDROPDOWN, FALSE, 0);
    01106             ThreadUnlock(&tlpwndT);
    01107         }
    01108     }
    01109
    01110     /*
    01111      * Allocate and zero the movesize data structure
    01112      */
    01113     pmsd = (PMOVESIZEDATA)UserAllocPoolWithQuotaZInit(
    01114             sizeof(MOVESIZEDATA), TAG_MOVESIZE);
    01115
    01116     if (pmsd == NULL)
    01117         return;
    01118
    01119     /*
    01120      * Assign the move data into the pti.  If the thread is destroyed before
    01121      * we free the data the DestroyThreadInfo() routine will free the move data
    01122      */
    01123     ptiCurrent->pmsd = pmsd;
    01124
    01125     Lock(&(pmsd->spwnd), pwnd);
    01126
    01127     /*
    01128      * Set fForeground so we know whether to draw or not.
    01129      */
    01130     pmsd->fForeground = (ptiCurrent->pq == gpqForeground) ? TRUE : FALSE;
    01131
    01132     /*
    01133      * Lower the priority of the thread doing the dragging to make sure
    01134      * that we don't starve other threads and they get to repaint more often.
    01135      */
    01136     if (ptiCurrent == gptiForeground) {
    01137         SetForegroundPriority(ptiCurrent, FALSE);
    01138     }
    01139
    01140     /*
    01141      * Get the client and window rects.
    01142      */
    01143     CopyRect(&pmsd->rcWindow, &pwnd->rcWindow);
    01144
    01145     if (pwnd->spwndParent == PWNDDESKTOP(pwnd)) {
    01146         if (    TestWF(pwnd, WEFTOPMOST) ||
    01147                 TestWF(pwnd, WEFTOOLWINDOW) ||
    01148                 gpDispInfo->cMonitors > 1) {
    01149
    01150             pmsd->rcParent = gpDispInfo->rcScreen;
    01151          } else {
    01152             pmsd->rcParent = GetPrimaryMonitor()->rcWork;
    01153          }
    01154     } else {
    01155         CopyRect(&pmsd->rcParent, &pwnd->spwndParent->rcClient);
    01156
    01157         /*
    01158          * If the parent does have a region, intersect with its bounding rect.
    01159          */
    01160         if (pwnd->spwndParent->hrgnClip != NULL) {
    01161
    01162             RECT rcT;
    01163
    01164             GreGetRgnBox(pwnd->spwndParent->hrgnClip, &rcT);
    01165             IntersectRect(&pmsd->rcParent, &pmsd->rcParent, &rcT);
    01166         }
    01167     }
    01168
    01169     /*
    01170      * This works for multiple monitors _and_ regional windows
    01171      */
    01172     if (pwnd->spwndParent->hrgnClip) {
    01173         pmsd->fOffScreen = !GreRectInRegion(pwnd->spwndParent->hrgnClip, &pmsd->rcWindow);
    01174     } else {
    01175         pmsd->fOffScreen = !IntersectRect(&rcSys, &pmsd->rcWindow, &pmsd->rcParent);
    01176     }
    01177
    01178     /*
    01179      * No need to DeferWinEventNotify(), judging by xxxInitSendValidateMinMaxInfo below
    01180      */
    01181     zzzClipCursor(&pmsd->rcParent);
    01182     CopyRect(&rcSys, &pmsd->rcWindow);
    01183
    01184     if (TestWF(pwnd, WFMINIMIZED)) {
    01185
    01186         /*
    01187          * No need to send WM_GETMINMAXINFO since we know the minimized size.
    01188          */
    01189         pmsd->ptMinTrack.x = pmsd->ptMaxTrack.x = SYSMET(CXMINIMIZED);
    01190         pmsd->ptMinTrack.y = pmsd->ptMaxTrack.y = SYSMET(CYMINIMIZED);
    01191
    01192     } else {
    01193         xxxInitSendValidateMinMaxInfo(pwnd, &mmi);
    01194         pmsd->ptMinTrack = mmi.ptMinTrackSize;
    01195         pmsd->ptMaxTrack = mmi.ptMaxTrackSize;
    01196     }
    01197
    01198     /*
    01199      * Set up the drag rectangle.
    01200      */
    01201     CopyRect(&pmsd->rcDrag, &pmsd->rcWindow);
    01202     CopyRect(&pmsd->rcDragCursor, &pmsd->rcDrag);
    01203
    01204     ptStart.x = LOSHORT(wptStart);
    01205     ptStart.y = HISHORT(wptStart);
    01206
    01207     /*
    01208      * Assume Move/Size from mouse.
    01209      */
    01210     pmsd->fInitSize = FALSE;
    01211     pmsd->fmsKbd = FALSE;
    01212
    01213     /*
    01214      * Get the mouse position for this move/size command.
    01215      */
    01216     switch (pmsd->cmd = cmdMove) {
    01217     case WMSZ_KEYMOVE:
    01218         pmsd->cmd = cmdMove = WMSZ_MOVE;
    01219
    01220         /*
    01221          ** FALL THRU **
    01222          */
    01223
    01224     case WMSZ_KEYSIZE:
    01225         /*
    01226          * No need to DeferWinEventNotify() - pmsd won't go away, and pwnd is locked
    01227          */
    01228         zzzSetCursor(SYSCUR(SIZEALL));
    01229
    01230         if (!TestWF(pwnd, WFMINIMIZED))
    01231             pmsd->fInitSize = TRUE;
    01232
    01233         /*
    01234          * Workaround: always behave as if the command is
    01235          * issued using keyboard.
    01236          * if it's found as the wrong way, the behavior is defined as:
    01237          * if (mnFocus == KEYBDHOLD) ||
    01238          *   ((mnFocus == MOUSEHOLD) && TestWF(pwnd, WFMINIMIZED))) {
    01239          * In order to do this, mnFocus should be saved somewhere.
    01240          * originally, mnFocus was saved in MenuState.
    01241          */
    01242         pmsd->fmsKbd      = TRUE;
    01243         pmsd->ptRestore.x = LOSHORT(wptStart);
    01244         pmsd->ptRestore.y = HISHORT(wptStart);
    01245
    01246         /*
    01247          * Center cursor in caption area of window
    01248          */
    01249
    01250         /*
    01251          * Horizontally
    01252          */
    01253         ptStart.x = (pmsd->rcDrag.left + pmsd->rcDrag.right) / 2;
    01254
    01255         /*
    01256          * Vertically
    01257          */
    01258         if (TestWF(pwnd,WFMINIMIZED) || (pmsd->cmd != WMSZ_MOVE)) {
    01259             ptStart.y = (pmsd->rcDrag.top + pmsd->rcDrag.bottom) / 2;
    01260         } else {
    01261             int dy;
    01262
    01263             dy = GetCaptionHeight(pwnd);
    01264             ptStart.y = pmsd->rcDrag.top + SYSMET(CYFIXEDFRAME) + dy / 2;
    01265         }
    01266
    01267         zzzInternalSetCursorPos(ptStart.x, ptStart.y);
    01268         xxxMS_FlushWigglies();
    01269         break;
    01270
    01271     default:
    01272         break;
    01273     }
    01274
    01275     pmsd->fDragFullWindows = TEST_BOOL_PUDF(PUDF_DRAGFULLWINDOWS);
    01276     SET_OR_CLEAR_PUDF(PUDF_DRAGGINGFULLWINDOW, pmsd->fDragFullWindows);
    01277
    01278     /*
    01279      * If we hit with the mouse, set up impx and impy so that we
    01280      * can use the keyboard too.
    01281      */
    01282     pmsd->impx = rgcmdmpix[cmdMove];
    01283     pmsd->impy = rgcmdmpiy[cmdMove];
    01284
    01285     /*
    01286      * Setup dxMouse and dyMouse - If we're sizing with the keyboard these
    01287      * guys are set to zero down in the keyboard code.
    01288      */
    01289     if ((i = rgimpiwx[cmdMove]) != (-1))
    01290         pmsd->dxMouse = *((int *)&pmsd->rcWindow + (short)i) - ptStart.x;
    01291
    01292     if ((i = rgimpiwy[cmdMove]) != (-1))
    01293         pmsd->dyMouse = *((int *)&pmsd->rcWindow + (short)i) - ptStart.y;
    01294
    01295     /*
    01296      * Tell Gdi the width of the drag rect (if its a special size)
    01297      * Turn the drag rect on.  0 specifies start drag.
    01298      */
    01299     if (!TestWF(pwnd, WFSIZEBOX))
    01300         bSetDevDragWidth(gpDispInfo->hDev, 1);
    01301
    01302     if (FWINABLE()) {
    01303         xxxWindowEvent(EVENT_SYSTEM_MOVESIZESTART, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0);
    01304     }
    01305
    01306     xxxDrawDragRect(pmsd, NULL, DDR_START);
    01307     ptiCurrent->TIF_flags |= TIF_TRACKRECTVISIBLE;
    01308
    01309     msg.lParam = MAKELONG(ptStart.x, ptStart.y);
    01310
    01311     /*
    01312      * Right here win3.1 calls LockWindowUpdate(). This calls zzzSetFMouseMoved()
    01313      * which ensures that the next message in the queue is a mouse message.
    01314      * We need that mouse message as the first message because the first
    01315      * call to TrackInitSize() assumes that lParam is an x, y from a mouse
    01316      * message - scottlu.
    01317      */
    01318     zzzSetFMouseMoved();
    01319
    01320     /*
    01321      * Send this message for winoldapp support
    01322      */
    01323     xxxSendMessage(pwnd, WM_ENTERSIZEMOVE, 0L, 0L);
    01324     xxxCapture(ptiCurrent, pwnd, CLIENT_CAPTURE_INTERNAL);
    01325
    01326     /*
    01327      * Show the move cursor for non-mouse systems.
    01328      */
    01329     zzzShowCursor(TRUE);
    01330
    01331     while (!(pmsd->fTrackCancelled)) {
    01332
    01333         /*
    01334          * Let other messages not related to dragging be dispatched
    01335          * to the application window.
    01336          * In the case of clock, clock will now receive messages to
    01337          * update the time displayed instead of having the time display
    01338          * freeze while we are dragging.
    01339          */
    01340         while (ptiCurrent->pq->spwndCapture == pwnd) {
    01341
    01342             if (xxxPeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
    01343
    01344                 if ((msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
    01345                     || (msg.message == WM_QUEUESYNC)
    01346                     || (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)) {
    01347
    01348                     break;
    01349                 }
    01350
    01351                 if (_CallMsgFilter(&msg, cmdMove == WMSZ_MOVE ? MSGF_MOVE : MSGF_SIZE)) {
    01352                     continue;
    01353                 }
    01354
    01355                 xxxTranslateMessage(&msg, 0);
    01356                 /*
    01357                  * To prevent applications from doing
    01358                  * a PeekMessage loop and getting the mouse move messages that
    01359                  * are destined for the xxxMoveSize PeekMessage loop, we OR in
    01360                  * this flag. See comments in input.c for xxxInternalGetMessage.
    01361                  */
    01362                 ptiCurrent->TIF_flags |= TIF_MOVESIZETRACKING;
    01363                 xxxDispatchMessage(&msg);
    01364                 ptiCurrent->TIF_flags &= ~TIF_MOVESIZETRACKING;
    01365
    01366             } else {
    01367                 /*
    01368                  * If we've been cancelled by someone else, or our pwnd
    01369                  * has been destroyed, blow out of here.
    01370                  */
    01371                 if (pmsd->fTrackCancelled)
    01372                     break;
    01373
    01374                 if (!xxxWaitMessage())
    01375                     break;
    01376             }
    01377         }
    01378
    01379         /*
    01380          * If we've lost capture while tracking,
    01381          * cancel the move/size operation.
    01382          */
    01383         if (ptiCurrent->pq->spwndCapture != pwnd) {
    01384
    01385             /*
    01386              * Fake a key-down of the escape key to cancel.
    01387              */
    01388             xxxMS_TrackMove(pwnd, WM_KEYDOWN, (DWORD)VK_ESCAPE, 1, pmsd);
    01389             goto MoveSizeCleanup;
    01390         }
    01391
    01392         /*
    01393          * If we've been cancelled by someone else, or our pwnd
    01394          * has been destroyed, blow out of here.
    01395          */
    01396         if (pmsd->fTrackCancelled) {
    01397             pmsd->fTrackCancelled = FALSE;
    01398             goto MoveSizeCleanup;
    01399         }
    01400
    01401         /*
    01402          * If we get a WM_QUEUESYNC, let the CBT hook know.
    01403          */
    01404         if (msg.message == WM_QUEUESYNC) {
    01405             xxxCallHook(HCBT_QS, 0, 0, WH_CBT);
    01406         }
    01407
    01408         if (pmsd->fInitSize) {
    01409             if (!xxxTrackInitSize(pwnd, msg.message, msg.wParam, msg.lParam,
    01410                     pmsd)) {
    01411                 break;
    01412             }
    01413         }
    01414
    01415         /*
    01416          * Convert captured mouse into screen coordinates.
    01417          */
    01418         x = msg.pt.x + pmsd->dxMouse;
    01419         y = msg.pt.y + pmsd->dyMouse;
    01420
    01421         /*
    01422          * This is checked twice so the same message is not processed both
    01423          * places.
    01424          */
    01425         if (!pmsd->fInitSize) {
    01426             xxxMS_TrackMove(pwnd, msg.message, msg.wParam, MAKELONG(x, y),
    01427                     pmsd);
    01428         }
    01429     }
    01430
    01431 MoveSizeCleanup:
    01432
    01433     /*
    01434      * Reset priority if still in the foreground thread.
    01435      */
    01436
    01437     if (ptiCurrent == gptiForeground) {
    01438         SetForegroundPriority(ptiCurrent, TRUE);
    01439     }
    01440
    01441     /*
    01442      * Reset the border size if it was abnormal
    01443      */
    01444
    01445     if (!TestWF(pwnd, WFSIZEBOX))
    01446         bSetDevDragWidth(gpDispInfo->hDev, gpsi->gclBorder + BORDER_EXTRA);
    01447
    01448     /*
    01449      * Revalidation: If pwnd is deleted unexpectedly, jump here to cleanup.
    01450      */
    01451
    01452     bSetDevDragRect(gpDispInfo->hDev, NULL, NULL);
    01453     ptiCurrent->TIF_flags &= ~(TIF_TRACKRECTVISIBLE);
    01454
    01455     if (pmsd->fDragFullWindows) {
    01456         if (ghrgnUpdateSave != NULL) {
    01457             GreDeleteObject(ghrgnUpdateSave);
    01458             ghrgnUpdateSave = NULL;
    01459             gnUpdateSave = 0;
    01460         }
    01461     }
    01462
    01463     CLEAR_PUDF(PUDF_DRAGGINGFULLWINDOW);
    01464
    01465     ptiCurrent->pmsd = NULL;
    01466
    01467     Unlock(&pmsd->spwnd);
    01468
    01469
    01470     zzzShowCursor(FALSE);
    01471
    01472     /*
    01473      * Free the move/size data structure
    01474      */
    01475     UserFreePool(pmsd);
    01476 }

VOID xxxMS_FlushWigglies | ( | VOID |  | ) |

Definition at line 844 of file movesize.c.

References msg, NULL, VOID(), and xxxPeekMessage.

Referenced by xxxMoveSize().

    00845 {
    00846     MSG msg;
    00847
    00848     /*
    00849      * HACK!
    00850      *
    00851      * Calling zzzInternalSetCursorPos() while initializing the cursor
    00852      * position appears to be posting a bogus MouseMove
    00853      * message...  don't really have the time
    00854      * now to figure out why...  so spit out all the mouse move messages
    00855      * before entering the main move/size loop.  CraigC.
    00856      */
    00857     while (xxxPeekMessage(&msg,
    00858                           NULL,
    00859                           WM_MOUSEMOVE,
    00860                           WM_MOUSEMOVE,
    00861                           PM_REMOVE | PM_NOYIELD));
    00862 }

void xxxMS_TrackMove | ( | PWND | pwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam,
|  | PMOVESIZEDATA | pmsd
| ) |

Definition at line 437 of file movesize.c.

References _GetKeyState(), _GetMessagePos(), _MonitorFromRect(), BOOL, CheckLock, CkptRestore(), ClrWF, _MOVESIZEDATA::cmd, tagDISPLAYINFO::cMonitors, CopyOffsetRect(), CopyRect, DDR_ENDACCEPT, DDR_ENDCANCEL, tagMONITOR::dwMONFlags, DWORD, _MOVESIZEDATA::dxMouse, _MOVESIZEDATA::dyMouse, EqualRect, FALSE, tagCHECKPOINT::fDragged, _MOVESIZEDATA::fmsKbd, _MOVESIZEDATA::fTrackCancelled, FWINABLE, GetPrimaryMonitor(), gpDispInfo, tagDISPLAYINFO::hDev, HIBYTE, HISHORT, tagWND::hrgnClip, HW, HWq, _MOVESIZEDATA::impx, _MOVESIZEDATA::impy, IsWinEventNotifyDeferredOK, L, LockWindowUpdate2(), LOSHORT, max, MONF_VISIBLE, NULL, OffsetRect(), tagDISPLAYINFO::pMonitorFirst, tagMONITOR::pMonitorNext, tagTHREADINFO::pmsd, PtiCurrent, PtInRect(), _MOVESIZEDATA::ptRestore, PWNDDESKTOP, tagWND::rcClient, _MOVESIZEDATA::rcDrag, _MOVESIZEDATA::rcDragCursor, tagMONITOR::rcMonitor, _MOVESIZEDATA::rcParent, _MOVESIZEDATA::rcWindow, tagMONITOR::rcWork, rgimpimpiw, rgimpiwx, rgimpiwy, SetMinimize(), SHORT, SMIN_CLEAR, tagWND::spwndParent, SYSMET, TestWF, tagTHREADINFO::TIF_flags, TIF_TRACKRECTVISIBLE, TRUE, WEFTOOLWINDOW, WEFTOPMOST, WFMAXIMIZED, WFMINIMIZED, xxxCallHook(), xxxDrawDragRect(), xxxReleaseCapture(), xxxSendMessage(), xxxSetWindowPos(), xxxTM_MoveDragRect(), xxxWindowEvent(), zzzClipCursor(), and zzzInternalSetCursorPos().

Referenced by xxxMoveSize().

    00443 {
    00444     int         dxMove;
    00445     int         dyMove;
    00446     POINT       pt;
    00447     BOOL        fSlower;
    00448     RECT        rc;
    00449     PCHECKPOINT pcp;
    00450     LPWORD      ps;
    00451     PTHREADINFO ptiCurrent = PtiCurrent();
    00452
    00453     CheckLock(pwnd);
    00454     UserAssert(IsWinEventNotifyDeferredOK());
    00455     UserAssert(pmsd == ptiCurrent->pmsd);
    00456
    00457     pt.x = LOSHORT(lParam);
    00458     pt.y = HISHORT(lParam);
    00459
    00460     switch (message) {
    00461     case WM_LBUTTONUP:
    00462
    00463         /*
    00464          * Do final move!
    00465          */
    00466         xxxTM_MoveDragRect(pmsd, lParam);
    00467
    00468
    00469         /*
    00470          * Don't reset the mouse position when done.
    00471          */
    00472         pmsd->fmsKbd = FALSE;
    00473
    00474 Accept:
    00475
    00476         /*
    00477          * Turn off rect, unlock screen, release capture, and stop tracking.
    00478          * 1 specifies end and accept drag.
    00479          */
    00480         bSetDevDragRect(gpDispInfo->hDev, NULL, NULL);
    00481         if (ptiCurrent->TIF_flags & TIF_TRACKRECTVISIBLE) {
    00482             xxxDrawDragRect(pmsd, NULL, DDR_ENDACCEPT);
    00483             ptiCurrent->TIF_flags &= ~TIF_TRACKRECTVISIBLE;
    00484         }
    00485
    00486 TrackMoveCancel:
    00487
    00488         /*
    00489          * Revalidation: if pwnd is unexpectedly deleted, jump here to cleanup.
    00490          * If pwnd is/becomes invalid between here and return, continue with
    00491          * cleanup as best as possible.
    00492          */
    00493         zzzClipCursor((LPRECT)NULL);
    00494         LockWindowUpdate2(NULL, TRUE);
    00495         xxxReleaseCapture();
    00496
    00497         /*
    00498          * First unlock task and reset cursor.
    00499          */
    00500         pmsd->fTrackCancelled = TRUE;
    00501
    00502         /*
    00503          * If using the keyboard, restore the initial mouse position.
    00504          */
    00505         if (pmsd->fmsKbd) {
    00506             /*
    00507              * No DeferWinEventNotify required - xxx calls above & below
    00508              */
    00509             zzzInternalSetCursorPos(pmsd->ptRestore.x,
    00510                                  pmsd->ptRestore.y
    00511                                  );
    00512         }
    00513
    00514         /*
    00515          * Move to new location relative to parent.
    00516          */
    00517         if (pwnd->spwndParent == PWNDDESKTOP(pwnd)) {
    00518             rc.left = rc.top = 0;
    00519         } else {
    00520             rc.left = pwnd->spwndParent->rcClient.left;
    00521             rc.top = pwnd->spwndParent->rcClient.top;
    00522         }
    00523
    00524         if (!EqualRect(&pmsd->rcDrag, &pmsd->rcWindow)) {
    00525
    00526             if (!xxxCallHook(HCBT_MOVESIZE,
    00527                              (WPARAM)HWq(pwnd),
    00528                              (LPARAM)&pmsd->rcDrag,
    00529                              WH_CBT)) {
    00530
    00531                 RECT rcT;
    00532
    00533                 if (pmsd->cmd != WMSZ_MOVE) {
    00534
    00535                     if (TestWF(pwnd, WFMINIMIZED)) {
    00536
    00537                         CopyOffsetRect(&rcT,
    00538                                        &pmsd->rcWindow,
    00539                                        -rc.left,
    00540                                        -rc.top);
    00541
    00542                         /*
    00543                          * Save the minimized position.
    00544                          */
    00545                         CkptRestore(pwnd, &rcT);
    00546                         SetMinimize(pwnd, SMIN_CLEAR);
    00547
    00548                     } else if (TestWF(pwnd, WFMAXIMIZED)) {
    00549                         ClrWF(pwnd, WFMAXIMIZED);
    00550                     }
    00551
    00552                 } else if (TestWF(pwnd, WFMINIMIZED)) {
    00553
    00554                     CopyOffsetRect(&rcT,
    00555                                    &pmsd->rcWindow,
    00556                                    -rc.left,
    00557                                    -rc.top);
    00558
    00559
    00560                     if (pcp = CkptRestore(pwnd, &rcT))
    00561                         pcp->fDragged = TRUE;
    00562                 }
    00563
    00564             } else {
    00565                 CopyRect(&pmsd->rcDrag, &pmsd->rcWindow);
    00566             }
    00567         }
    00568
    00569         /*
    00570          * Move to new location relative to parent.
    00571          */
    00572 #if defined(USE_MIRRORING)
    00573         if (TestWF(pwnd->spwndParent,WEFLAYOUTRTL)) {
    00574             /*
    00575              * If this is a mirrored window, then measure the client
    00576              * coordinates from the parent's right edge, not the left one.
    00577              */
    00578             int iLeft;
    00579
    00580             OffsetRect(&pmsd->rcDrag, -pwnd->spwndParent->rcClient.right, -rc.top);
    00581             iLeft = pmsd->rcDrag.left;
    00582             pmsd->rcDrag.left  = (pmsd->rcDrag.right * -1);
    00583             pmsd->rcDrag.right = (iLeft * -1);
    00584         }
    00585         else
    00586 #endif
    00587             OffsetRect(&pmsd->rcDrag, -rc.left, -rc.top);
    00588
    00589         /*
    00590          * For top level windows, make sure at least part of the caption
    00591          * caption is always visible in the desktop area.  This will
    00592          * ensure that once moved, the window can be moved back.
    00593          */
    00594         if (pwnd->spwndParent == PWNDDESKTOP(pwnd)) {
    00595
    00596             int         dy;
    00597             BOOL        fMonitor;
    00598             PMONITOR    pMonitor;
    00599
    00600             UserAssert(HIBYTE(WEFTOPMOST) == HIBYTE(WEFTOOLWINDOW));
    00601             fMonitor = TestWF(pwnd, WEFTOPMOST | WEFTOOLWINDOW);
    00602             dy = (TestWF(pwnd, WEFTOOLWINDOW) ?
    00603                     SYSMET(CYSMCAPTION) : SYSMET(CYCAPTION)) - SYSMET(CYBORDER);
    00604
    00605             if (gpDispInfo->cMonitors == 1) {
    00606                 pMonitor = GetPrimaryMonitor();
    00607             } else {
    00608                 int     y;
    00609                 LPRECT  lprc;
    00610
    00611                 y = pmsd->rcDrag.top + dy;
    00612
    00613                 /*
    00614                  * Make sure that some part of the caption is showing on some
    00615                  * monitor...
    00616                  */
    00617                 for (   pMonitor = gpDispInfo->pMonitorFirst;
    00618                         pMonitor;
    00619                         pMonitor = pMonitor->pMonitorNext) {
    00620
    00621                     if (!(pMonitor->dwMONFlags & MONF_VISIBLE))
    00622                         continue;
    00623
    00624                     if (fMonitor) {
    00625                         lprc = &pMonitor->rcMonitor;
    00626                     } else {
    00627                         lprc = &pMonitor->rcWork;
    00628                     }
    00629
    00630                     /*
    00631                      * Is the Y coordinate visible on screen somewhere?
    00632                      */
    00633                     if (y >= lprc->top && y < lprc->bottom)
    00634                         goto AllSet;
    00635                 }
    00636
    00637                 /*
    00638                  * Oops, have to move the window so that some part of
    00639                  * the caption is visible on screen.
    00640                  */
    00641                 pMonitor = _MonitorFromRect(&pmsd->rcDrag, MONITOR_DEFAULTTONEAREST);
    00642             }
    00643
    00644             if (fMonitor) {
    00645                 pmsd->rcDrag.top = max(pmsd->rcDrag.top, pMonitor->rcMonitor.top - dy);
    00646             } else {
    00647                 pmsd->rcDrag.top = max(pmsd->rcDrag.top, pMonitor->rcWork.top - dy);
    00648             }
    00649
    00650 AllSet:
    00651             ;
    00652         }
    00653
    00654         /*
    00655          * OR in SWP_NOSIZE so it doesn't redraw if we're just moving.
    00656          */
    00657         xxxSetWindowPos(
    00658                 pwnd,
    00659                 NULL,
    00660                 pmsd->rcDrag.left,
    00661                 pmsd->rcDrag.top,
    00662                 pmsd->rcDrag.right - pmsd->rcDrag.left,
    00663                 pmsd->rcDrag.bottom - pmsd->rcDrag.top,
    00664                 (DWORD)((pmsd->cmd == (int)WMSZ_MOVE) ? SWP_NOSIZE : 0));
    00665
    00666         if (TestWF(pwnd, WFMINIMIZED)) {
    00667             CkptRestore(pwnd, &pmsd->rcDrag);
    00668         }
    00669
    00670         if (FWINABLE()) {
    00671             xxxWindowEvent(EVENT_SYSTEM_MOVESIZEEND, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0);
    00672         }
    00673
    00674         /*
    00675          * Send this message for winoldapp support
    00676          */
    00677         xxxSendMessage(pwnd, WM_EXITSIZEMOVE, 0L, 0L);
    00678         break;
    00679
    00680     case WM_KEYDOWN:
    00681     case WM_SYSKEYDOWN:
    00682
    00683         /*
    00684          * Assume we're not moving the drag rectangle.
    00685          */
    00686         dxMove =
    00687         dyMove = 0;
    00688
    00689         /*
    00690          * We move or size slower if the control key is down.
    00691          */
    00692         fSlower = (_GetKeyState(VK_CONTROL) < 0);
    00693
    00694         switch (wParam) {
    00695         case VK_RETURN:
    00696             lParam = _GetMessagePos();
    00697             goto Accept;
    00698
    00699         case VK_ESCAPE:
    00700
    00701             /*
    00702              * 2 specifies end and cancel drag.
    00703              */
    00704             bSetDevDragRect(gpDispInfo->hDev, NULL, NULL);
    00705             if (ptiCurrent->TIF_flags & TIF_TRACKRECTVISIBLE) {
    00706                 xxxDrawDragRect(pmsd, NULL, DDR_ENDCANCEL);
    00707                 ptiCurrent->TIF_flags &= ~TIF_TRACKRECTVISIBLE;
    00708             }
    00709
    00710             CopyRect(&pmsd->rcDrag, &pmsd->rcWindow);
    00711
    00712             goto TrackMoveCancel;
    00713
    00714         case VK_LEFT:
    00715         case VK_RIGHT:
    00716
    00717             if (pmsd->impx == 0) {
    00718
    00719                 pmsd->impx = rgimpimpiw[wParam - VK_LEFT];
    00720                 goto NoOffset;
    00721
    00722             } else {
    00723
    00724                 dxMove = (fSlower ? 1 : max(SYSMET(CXSIZE) / 2, 1));
    00725
    00726                 if (wParam == VK_LEFT)
    00727                     dxMove = -dxMove;
    00728
    00729                 goto KeyMove;
    00730             }
    00731
    00732         case VK_UP:
    00733         case VK_DOWN:
    00734
    00735             if (pmsd->impy == 0) {
    00736
    00737                 pmsd->impy = rgimpimpiw[wParam - VK_LEFT];
    00738 NoOffset:
    00739                 pmsd->dxMouse = pmsd->dyMouse = 0;
    00740
    00741             } else {
    00742
    00743                 dyMove = (fSlower ? 1 : max(SYSMET(CYSIZE) / 2, 1));
    00744
    00745                 if (wParam == VK_UP) {
    00746                     dyMove = -dyMove;
    00747                 }
    00748             }
    00749
    00750 KeyMove:
    00751             if (pmsd->cmd == WMSZ_MOVE) {
    00752
    00753                 /*
    00754                  * Use the current rect position as the current mouse
    00755                  * position
    00756                  */
    00757                 lParam = (DWORD)(POINTTOPOINTS(*((POINT *)&pmsd->rcDrag)));
    00758
    00759             } else {
    00760
    00761                 /*
    00762                  * Get the current mouse position
    00763                  */
    00764                 lParam = _GetMessagePos();
    00765             }
    00766
    00767             /*
    00768              * Calc the new 'mouse' pos
    00769              */
    00770             if (pmsd->impx != 0) {
    00771                 ps = ((WORD *)(&lParam)) + 0;
    00772                 *ps = (WORD)(*((int *)&pmsd->rcDragCursor +
    00773                              rgimpiwx[pmsd->impx])        +
    00774                              dxMove);
    00775             }
    00776
    00777             if (pmsd->impy != 0) {
    00778                 ps = ((WORD *)(&lParam)) + 1;
    00779                 *ps = (WORD)(*((int *)&pmsd->rcDragCursor +
    00780                              rgimpiwy[pmsd->impy])        +
    00781                              dyMove);
    00782             }
    00783
    00784             if (pmsd->cmd != WMSZ_MOVE) {
    00785
    00786                 /*
    00787                  * Calculate the new move command.
    00788                  */
    00789                 pmsd->cmd = pmsd->impx + pmsd->impy;
    00790
    00791                 /*
    00792                  * Change the mouse cursor for this condition.
    00793                  */
    00794                 xxxSendMessage(
    00795                         pwnd,
    00796                         WM_SETCURSOR,
    00797                         (WPARAM)HW(pwnd),
    00798                         MAKELONG((SHORT)(pmsd->cmd + HTSIZEFIRST - WMSZ_SIZEFIRST), WM_MOUSEMOVE));
    00799             }
    00800
    00801             /*
    00802              * We don't want to call zzzInternalSetCursorPos() if the
    00803              * rect position is outside of rcParent because that'll
    00804              * generate a mouse move which will jerk the rect back
    00805              * again.  This is here so we can move rects partially off
    00806              * screen without regard to the mouse position.
    00807              */
    00808             pt.x = LOSHORT(lParam) - pmsd->dxMouse;
    00809             pt.y = HISHORT(lParam) - pmsd->dyMouse;
    00810
    00811             if (pwnd->spwndParent->hrgnClip) {
    00812                 if (GrePtInRegion(pwnd->spwndParent->hrgnClip, pt.x, pt.y)) {
    00813                     zzzInternalSetCursorPos(pt.x, pt.y);
    00814                 }
    00815             } else {
    00816                 if (PtInRect(&pmsd->rcParent, pt)) {
    00817                     zzzInternalSetCursorPos(pt.x, pt.y);
    00818                 }
    00819             }
    00820
    00821             /*
    00822              * Move or size the rect using lParam as our mouse
    00823              * coordinates
    00824              */
    00825             xxxTM_MoveDragRect(pmsd, lParam);
    00826             break;
    00827
    00828         }  // of inner switch
    00829         break;
    00830
    00831     case WM_MOUSEMOVE:
    00832         xxxTM_MoveDragRect(pmsd, lParam);
    00833         break;
    00834     }
    00835 }

VOID xxxTM_MoveDragRect | ( | PMOVESIZEDATA | pmsd,
|  | LPARAM | lParam
| ) |

Definition at line 274 of file movesize.c.

References CopyRect, DRAG_MOVE, DWORD, HISHORT, LOSHORT, MoveRect(), msg, PtiCurrent, SizeRect(), UINT, VOID(), xxxDrawDragRect(), and xxxSendMessage().

Referenced by xxxMS_TrackMove().

    00277 {
    00278     UINT msg;
    00279     RECT rc;
    00280
    00281     UserAssert(pmsd == PtiCurrent()->pmsd);
    00282     UserAssert(pmsd->cmd != WMSZ_KEYSIZE);
    00283
    00284     CopyRect(&pmsd->rcDragCursor, &pmsd->rcDrag);
    00285
    00286     if (pmsd->cmd == WMSZ_MOVE) {
    00287
    00288         if (!MoveRect(pmsd, (DWORD)lParam))
    00289             return;
    00290
    00291         msg = WM_MOVING;
    00292
    00293     } else {
    00294
    00295         if (!SizeRect(pmsd, (DWORD)lParam))
    00296             return;
    00297
    00298         msg = WM_SIZING;
    00299     }
    00300
    00301     CopyRect(&rc, &pmsd->rcDragCursor);
    00302     xxxSendMessage(pmsd->spwnd, msg, pmsd->cmd, (LPARAM)(LPRECT)&rc);
    00303     xxxDrawDragRect(pmsd, &rc, DRAG_MOVE);
    00304
    00305     if (pmsd->cmd == WMSZ_MOVE) {
    00306
    00307         /*
    00308          * Keep dxMouse & dxMouse relative to the offset from the top left
    00309          * corner, the rectangle could've changed on WM_MOVING
    00310          */
    00311         pmsd->dxMouse += (rc.left - LOSHORT(lParam));
    00312         pmsd->dyMouse += (rc.top - HISHORT(lParam));
    00313     }
    00314 }

BOOL xxxTrackInitSize | ( | PWND | pwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam,
|  | PMOVESIZEDATA | pmsd
| ) |

Definition at line 873 of file movesize.c.

References _ClientToScreen(), BOOL, CheckLock, _MOVESIZEDATA::cmd, CopyRect, DDR_ENDCANCEL, _MOVESIZEDATA::dxMouse, _MOVESIZEDATA::dyMouse, FALSE, FAR, FindNCHit(), _MOVESIZEDATA::fInitSize, _MOVESIZEDATA::fTrackCancelled, gpDispInfo, tagDISPLAYINFO::hDev, HW, _MOVESIZEDATA::impx, _MOVESIZEDATA::impy, IsWinEventNotifyDeferredOK, NULL, tagTHREADINFO::pmsd, PtiCurrent, PtInRect(), _MOVESIZEDATA::rcDrag, tagWND::rcWindow, _MOVESIZEDATA::rcWindow, rgcmdmpix, rgcmdmpiy, rgimpiwx, rgimpiwy, SYSCUR, tagTHREADINFO::TIF_flags, TIF_TRACKRECTVISIBLE, TRUE, UINT, xxxDrawDragRect(), xxxReleaseCapture(), xxxSendMessage(), zzzClipCursor(), and zzzSetCursor().

Referenced by xxxMoveSize().

    00879 {
    00880     int   ht;
    00881     POINT pt;
    00882     RECT  rc;
    00883     PTHREADINFO  ptiCurrent = PtiCurrent();
    00884
    00885     CheckLock(pwnd);
    00886     UserAssert(pmsd == ptiCurrent->pmsd);
    00887     UserAssert(IsWinEventNotifyDeferredOK());
    00888
    00889     POINTSTOPOINT(pt, lParam);
    00890
    00891     _ClientToScreen(pwnd, (LPPOINT)&pt);
    00892     ht = FindNCHit(pwnd, POINTTOPOINTS(pt));
    00893
    00894     switch (message) {
    00895
    00896     case WM_KEYDOWN:
    00897         if (pmsd->cmd == WMSZ_MOVE) {
    00898             xxxSendMessage(pwnd,
    00899                            WM_SETCURSOR,
    00900                            (WPARAM)HW(pwnd),
    00901                            MAKELONG(WMSZ_KEYSIZE, WM_MOUSEMOVE));
    00902         }
    00903         /* keys below are only allowed */
    00904         switch (wParam) {
    00905         case VK_RETURN:
    00906         case VK_ESCAPE:
    00907         case VK_LEFT:
    00908         case VK_RIGHT:
    00909         case VK_UP:
    00910         case VK_DOWN:
    00911             pmsd->fInitSize = FALSE;
    00912             break;
    00913         }
    00914         return TRUE;
    00915
    00916     case WM_LBUTTONDOWN:
    00917         if (!PtInRect(&pmsd->rcDrag, pt)) {
    00918
    00919             /*
    00920              *** FALL THRU ***
    00921              */
    00922
    00923     case WM_LBUTTONUP:
    00924
    00925             /*
    00926              * Cancel everything.
    00927              */
    00928             {
    00929                 PTHREADINFO ptiCurrent = PtiCurrent();
    00930
    00931                 bSetDevDragRect(gpDispInfo->hDev, NULL, NULL);
    00932                 if (ptiCurrent->TIF_flags & TIF_TRACKRECTVISIBLE) {
    00933                     xxxDrawDragRect(pmsd, NULL, DDR_ENDCANCEL);
    00934                     ptiCurrent->TIF_flags &= ~TIF_TRACKRECTVISIBLE;
    00935                 }
    00936
    00937                 pmsd->fInitSize = FALSE;
    00938                 zzzClipCursor(NULL);
    00939             }
    00940
    00941             xxxReleaseCapture();
    00942             pmsd->fTrackCancelled = TRUE;
    00943             return FALSE;
    00944
    00945         } else {
    00946
    00947             /*
    00948              * Now start hit testing for a border.
    00949              */
    00950             goto CheckFrame;
    00951         }
    00952
    00953     case WM_MOUSEMOVE:
    00954
    00955         /*
    00956          * The mouse is down, hit test for a border on mouse moves.
    00957          */
    00958         if (wParam == MK_LBUTTON) {
    00959
    00960 CheckFrame:
    00961
    00962             switch (pmsd->cmd) {
    00963             case WMSZ_MOVE:
    00964
    00965                 /*
    00966                  * If we are on the caption bar, exit.
    00967                  */
    00968                 if (ht == HTCAPTION) {
    00969
    00970                     /*
    00971                      * Change the mouse cursor.
    00972                      */
    00973                     xxxSendMessage(pwnd,
    00974                                    WM_SETCURSOR,
    00975                                    (WPARAM)HW(pwnd),
    00976                                    MAKELONG(WMSZ_KEYSIZE, WM_MOUSEMOVE));
    00977
    00978                     pmsd->dxMouse   = pmsd->rcWindow.left - pt.x;
    00979                     pmsd->dyMouse   = pmsd->rcWindow.top - pt.y;
    00980                     pmsd->fInitSize = FALSE;
    00981                     return TRUE;
    00982                 }
    00983                 break;
    00984
    00985             case WMSZ_KEYSIZE:
    00986
    00987                 /*
    00988                  * If we are on a frame control, change the cursor and exit.
    00989                  */
    00990                 if (ht >= HTSIZEFIRST && ht <= HTSIZELAST) {
    00991
    00992                     /*
    00993                      * Change the mouse cursor
    00994                      */
    00995                     xxxSendMessage(pwnd,
    00996                                    WM_SETCURSOR,
    00997                                    (WPARAM)HW(pwnd),
    00998                                    MAKELONG(ht, WM_MOUSEMOVE));
    00999
    01000                     pmsd->fInitSize = FALSE;
    01001
    01002                     /*
    01003                      * Set the proper cmd for SizeRect().
    01004                      *
    01005                      * HACK! Depends on order of HTSIZE* defines!
    01006                      */
    01007                     pmsd->impx = rgcmdmpix[ht - HTSIZEFIRST + 1];
    01008                     pmsd->impy = rgcmdmpiy[ht - HTSIZEFIRST + 1];
    01009                     pmsd->cmd  = pmsd->impx + pmsd->impy;
    01010
    01011                     pmsd->dxMouse = *((UINT FAR *)&pmsd->rcWindow + rgimpiwx[pmsd->cmd]) - pt.x;
    01012                     pmsd->dyMouse = *((UINT FAR *)&pmsd->rcWindow + rgimpiwy[pmsd->cmd]) - pt.y;
    01013
    01014                     return TRUE;
    01015                 }
    01016             }
    01017
    01018         } else {
    01019
    01020             /*
    01021              * If button not down, and we are moving the window, change the
    01022              * cursor shape depending upon where the mouse is pointing.  This
    01023              * allows the cursor to change to the arrows when over the window
    01024              * frame.
    01025              */
    01026             CopyRect(&rc, &pwnd->rcWindow);
    01027             if (PtInRect(&rc, pt)) {
    01028                 if ((ht >= HTSIZEFIRST) && (ht <= HTSIZELAST)) {
    01029                     xxxSendMessage(pwnd,
    01030                                    WM_SETCURSOR,
    01031                                    (WPARAM)HW(pwnd),
    01032                                    MAKELONG(ht, WM_MOUSEMOVE));
    01033
    01034                     break;
    01035                 }
    01036             }
    01037
    01038             zzzSetCursor(SYSCUR(SIZEALL));
    01039         }
    01040         break;
    01041     }
    01042
    01043     return TRUE;
    01044 }

VOID xxxUpdateOtherThreadsWindows | ( | PWND | pwnd,
|  | HRGN | hrgnFullDrag
| ) |

Definition at line 1485 of file movesize.c.

References CheckLock, NULL, PtiCurrent, tagWND::spwndChild, tagWND::spwndNext, TestWF, ThreadLockExchangeAlways(), ThreadLockNever, ThreadUnlock, VOID(), WFCLIPCHILDREN, and xxxRedrawHungWindow().

Referenced by xxxUpdateThreadsWindows().

    01488 {
    01489     PWND        pwndChild;
    01490     TL          tlpwndChild;
    01491     PTHREADINFO ptiCurrent = PtiCurrent();
    01492
    01493     CheckLock(pwnd);
    01494
    01495     xxxRedrawHungWindow(pwnd, hrgnFullDrag);
    01496
    01497     /*
    01498      * If the parent window does not have the flag WFCLIPCHILDREN set,
    01499      * there is no need to redraw its children.
    01500      */
    01501     if (!TestWF(pwnd, WFCLIPCHILDREN))
    01502         return;
    01503
    01504     pwndChild = pwnd->spwndChild;
    01505     ThreadLockNever(&tlpwndChild);
    01506     while (pwndChild != NULL) {
    01507         ThreadLockExchangeAlways(pwndChild, &tlpwndChild);
    01508         xxxUpdateOtherThreadsWindows(pwndChild, hrgnFullDrag);
    01509         pwndChild = pwndChild->spwndNext;
    01510     }
    01511
    01512     ThreadUnlock(&tlpwndChild);
    01513 }

VOID xxxUpdateThreadsWindows | ( | PTHREADINFO | pti,
|  | PWND | pwnd,
|  | HRGN | hrgnFullDrag
| ) |

Definition at line 1523 of file movesize.c.

References CheckLock, GETPTI, NULL, tagWND::spwndNext, ThreadLockExchangeAlways(), ThreadLockNever, ThreadUnlock, VOID(), xxxUpdateOtherThreadsWindows(), and xxxUpdateWindow().

Referenced by xxxDrawDragRect(), and xxxUpdateWindows().

    01527 {
    01528     TL   tlpwnd;
    01529
    01530     CheckLock(pwnd);
    01531
    01532     ThreadLockNever(&tlpwnd);
    01533     while (pwnd != NULL) {
    01534         ThreadLockExchangeAlways(pwnd, &tlpwnd);
    01535         if (GETPTI(pwnd) == pti) {
    01536             xxxUpdateWindow(pwnd);
    01537         } else {
    01538             xxxUpdateOtherThreadsWindows(pwnd, hrgnFullDrag);
    01539         }
    01540
    01541         pwnd = pwnd->spwndNext;
    01542     }
    01543
    01544     ThreadUnlock(&tlpwnd);
    01545 }

## Variable Documentation

const int rgcmdmpix[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 1}`[static]`

| Definition at line 48 of file movesize.c. Referenced by xxxMoveSize(), and xxxTrackInitSize().

const int rgcmdmpiy[] = {0, 0, 0, 3, 3, 3, 6, 6, 6, 3}`[static]`

| Definition at line 49 of file movesize.c. Referenced by xxxMoveSize(), and xxxTrackInitSize().

const int rgimpimpiw[] = {1, 3, 2, 6}`[static]`

| Definition at line 45 of file movesize.c. Referenced by xxxMS_TrackMove().

const int rgimpiwx[] = {0, 0, 2, -1, 0, 2, -1, 0, 2, 0}`[static]`

| Definition at line 46 of file movesize.c. Referenced by SizeRect(), xxxMoveSize(), xxxMS_TrackMove(), and xxxTrackInitSize().

const int rgimpiwy[] = {0, -1, -1, 1, 1, 1, 3, 3, 3, 1}`[static]`

| Definition at line 47 of file movesize.c. Referenced by SizeRect(), xxxMoveSize(), xxxMS_TrackMove(), and xxxTrackInitSize().