test: mmrtl.c File Reference

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

# mmrtl.c File Reference

Go to the source code of this file.

## Defines

#define | Int32x32To32(x, y) ((x) * (y))
#define | BEGIN_EXCEPTION_HANDLER try {
#define | END_EXCEPTION_HANDLER
#define | END_EXCEPTION_HANDLER_EMPTY
#define | MONITORFROMPOINTALGORITHM(SUMSQUARESMAX, SUMSQUARESTYPE, POINTMULTIPLY)
#define | MONITORFROMRECTALGORITHM(SUMSQUARESMAX, SUMSQUARESTYPE, POINTMULTIPLY)

## Functions

PMONITOR | _MonitorFromPoint (POINT pt, DWORD dwFlags)
PMONITOR | _MonitorFromRect (LPCRECT lprc, DWORD dwFlags)
PMONITOR | _MonitorFromWindow (PWND pwnd, DWORD dwFlags)

## Define Documentation

#define BEGIN_EXCEPTION_HANDLER try {

| Definition at line 23 of file mmrtl.c. Referenced by _MonitorFromPoint(), _MonitorFromRect(), and _MonitorFromWindow().

#define END_EXCEPTION_HANDLER

Value:

    } except (W32ExceptionHandler(TRUE, RIP_WARNING)) { \
            pMonitorResult = NULL; \
        }

Definition at line 24 of file mmrtl.c.

Referenced by _MonitorFromPoint(), _MonitorFromRect(), and _MonitorFromWindow().

#define END_EXCEPTION_HANDLER_EMPTY

Value:

    } except (W32ExceptionHandler(TRUE, RIP_WARNING)) { \
        }

Definition at line 28 of file mmrtl.c.

Referenced by _MonitorFromPoint().

#define Int32x32To32 | ( | x,
|  | y |  | ) | ((x) * (y))

| Definition at line 12 of file mmrtl.c. Referenced by _MonitorFromPoint(), and _MonitorFromWindow().

#define MONITORFROMPOINTALGORITHM | ( | SUMSQUARESMAX,
|  | SUMSQUARESTYPE,
|  | POINTMULTIPLY |  | ) |

| Referenced by _MonitorFromPoint().

#define MONITORFROMRECTALGORITHM | ( | SUMSQUARESMAX,
|  | SUMSQUARESTYPE,
|  | POINTMULTIPLY |  | ) |

| Referenced by _MonitorFromRect(), and _MonitorFromWindow().

## Function Documentation

PMONITOR _MonitorFromPoint | ( | POINT | pt,
|  | DWORD | dwFlags
| ) |

Definition at line 56 of file mmrtl.c.

References BEGIN_EXCEPTION_HANDLER, tagDISPLAYINFO::cMonitors, dwFlags, tagMONITOR::dwMONFlags, END_EXCEPTION_HANDLER, END_EXCEPTION_HANDLER_EMPTY, FALSE, GetDispInfo(), GetPrimaryMonitor(), Int32x32To32, MONF_VISIBLE, MONITORFROMPOINTALGORITHM, NULL, tagMONITOR::pMonitorNext, PtInRect(), REBASESHAREDPTR, REBASESHAREDPTRALWAYS, and UINT.

Referenced by _MonitorFromRect(), ClipPointToDesktop(), InternalCreateDialog(), MonitorFromPoint(), TooltipGetPosition(), and xxxTrackPopupMenuEx().

    00057 {
    00058     PMONITOR        pMonitor, pMonitorResult;
    00059     int             dx;
    00060     int             dy;
    00061
    00062     UserAssert(dwFlags == MONITOR_DEFAULTTONULL ||
    00063                dwFlags == MONITOR_DEFAULTTOPRIMARY ||
    00064                dwFlags == MONITOR_DEFAULTTONEAREST);
    00065
    00066     if (GetDispInfo()->cMonitors == 1 && dwFlags != MONITOR_DEFAULTTONULL)
    00067         return GetPrimaryMonitor();
    00068
    00069     switch (dwFlags) {
    00070     case MONITOR_DEFAULTTONULL:
    00071     case MONITOR_DEFAULTTOPRIMARY:
    00072         /*
    00073          * Return the monitor the point is in.
    00074          */
    00075
    00076         BEGIN_EXCEPTION_HANDLER
    00077
    00078         for (   pMonitor = REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorFirst);
    00079                 pMonitor;
    00080                 pMonitor = REBASESHAREDPTR(pMonitor->pMonitorNext)) {
    00081
    00082             if (!(pMonitor->dwMONFlags & MONF_VISIBLE))
    00083                 continue;
    00084
    00085             if (PtInRect(&((MONITOR *)pMonitor)->rcMonitor, pt)) {
    00086                 return pMonitor;
    00087             }
    00088         }
    00089
    00090         END_EXCEPTION_HANDLER_EMPTY
    00091
    00092         /*
    00093          * Return what the user wants if it's not found.
    00094          */
    00095         switch (dwFlags) {
    00096         case MONITOR_DEFAULTTONULL:
    00097             return NULL;
    00098
    00099         case MONITOR_DEFAULTTOPRIMARY:
    00100             return GetPrimaryMonitor();
    00101
    00102         default:
    00103             UserAssertMsg0(FALSE, "Logic error in _MonitorFromPoint");
    00104             break;
    00105         }
    00106
    00107     case MONITOR_DEFAULTTONEAREST:
    00108
    00109 #define MONITORFROMPOINTALGORITHM(SUMSQUARESMAX, SUMSQUARESTYPE, POINTMULTIPLY)     \
    00110         SUMSQUARESTYPE  sumsquare;                                                  \
    00111         SUMSQUARESTYPE  leastsumsquare;                                             \
    00112         leastsumsquare = SUMSQUARESMAX;                                             \
    00113         for (   pMonitor = REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorFirst);     \
    00114                 pMonitor;                                                           \
    00115                 pMonitor = REBASESHAREDPTR(pMonitor->pMonitorNext)) {               \
    00116                                                                                     \
    00117             if (!(pMonitor->dwMONFlags & MONF_VISIBLE))                             \
    00118                 continue;                                                           \
    00119                                                                                     \
    00120             /*                                                                      \
    00121              * Determine distance from monitor along x axis.                        \
    00122              */                                                                     \
    00123             if (pt.x < pMonitor->rcMonitor.left) {                                  \
    00124                 dx = pMonitor->rcMonitor.left - pt.x;                               \
    00125             } else if (pt.x < pMonitor->rcMonitor.right) {                          \
    00126                 dx = 0;                                                             \
    00127             } else {                                                                \
    00128                 /*                                                                  \
    00129                  * Monitor rectangles do not include the rightmost edge.            \
    00130                  */                                                                 \
    00131                 dx = pt.x - (pMonitor->rcMonitor.right - 1);                        \
    00132             }                                                                       \
    00133                                                                                     \
    00134             /*                                                                      \
    00135              * Skip this monitor if dx is greater than dx^2 + dy^2.                 \
    00136              * We do this check to avoid multiplication operations.                 \
    00137              */                                                                     \
    00138             if ((SUMSQUARESTYPE) dx >= leastsumsquare)                              \
    00139                 continue;                                                           \
    00140                                                                                     \
    00141             /*                                                                      \
    00142              * Determine distance from monitor along y axis.                        \
    00143              */                                                                     \
    00144             if (pt.y < pMonitor->rcMonitor.top) {                                   \
    00145                 dy = pMonitor->rcMonitor.top - pt.y;                                \
    00146             } else if (pt.y < pMonitor->rcMonitor.bottom) {                         \
    00147                 /*                                                                  \
    00148                  * The point is in the monitor and we're done                       \
    00149                  * if both dx and dy are zero.                                      \
    00150                  */                                                                 \
    00151                 if (dx == 0)                                                        \
    00152                     return pMonitor;                                                \
    00153                                                                                     \
    00154                 dy = 0;                                                             \
    00155             } else {                                                                \
    00156                 dy = pt.y - (pMonitor->rcMonitor.bottom - 1);                       \
    00157             }                                                                       \
    00158                                                                                     \
    00159             /*                                                                      \
    00160              * Calculate dx^2. Skip this monitor if dx is greater                   \
    00161              * than dx^2 + dy^2. We do this check to avoid                          \
    00162              * multiplication operations.                                           \
    00163              */                                                                     \
    00164             sumsquare = POINTMULTIPLY(dx, dx);                                      \
    00165             if (sumsquare >= leastsumsquare)                                        \
    00166                 continue;                                                           \
    00167                                                                                     \
    00168             /*                                                                      \
    00169              * Skip this monitor if dx^2 + y is greater than dx^2 + dy^2.           \
    00170              * We do this check to avoid multiplication operations.                 \
    00171              */                                                                     \
    00172             if (sumsquare + (SUMSQUARESTYPE) dy >= leastsumsquare)                  \
    00173                 continue;                                                           \
    00174                                                                                     \
    00175             /*                                                                      \
    00176              * Compute dx^2 + dy^2. Skip this monitor if it's not the least.        \
    00177              */                                                                     \
    00178             sumsquare += (SUMSQUARESTYPE) POINTMULTIPLY(dy, dy);                    \
    00179             if (sumsquare >= leastsumsquare)                                        \
    00180                 continue;                                                           \
    00181                                                                                     \
    00182             /*                                                                      \
    00183              * This is the closest monitor so far.                                  \
    00184              */                                                                     \
    00185             leastsumsquare = sumsquare;                                             \
    00186             pMonitorResult = pMonitor;                                              \
    00187         }
    00188
    00189 #if DBG
    00190         pMonitorResult = (PMONITOR) -1;
    00191 #endif
    00192
    00193         if (    pt.x < SHRT_MIN || SHRT_MAX < pt.x ||
    00194                 pt.y < SHRT_MIN || SHRT_MAX < pt.y) {
    00195

PMONITOR _MonitorFromRect | ( | LPCRECT | lprc,
|  | DWORD | dwFlags
| ) |

Definition at line 221 of file mmrtl.c.

References _MonitorFromPoint(), BEGIN_EXCEPTION_HANDLER, tagDISPLAYINFO::cMonitors, dwFlags, tagMONITOR::dwMONFlags, END_EXCEPTION_HANDLER, EqualRect, GetDispInfo(), GetPrimaryMonitor(), IntersectRect(), IsRectEmpty(), MONF_VISIBLE, MONITORFROMRECTALGORITHM, NULL, tagMONITOR::pMonitorNext, tagDISPLAYINFO::rcScreen, REBASESHAREDPTR, and REBASESHAREDPTRALWAYS.

Referenced by _GetWindowPlacement(), CkptRestore(), CreateSpb(), DefDlgProcWorker(), InternalCreateDialog(), MonitorFromRect(), xxxCheckFullScreen(), xxxMNPositionHierarchy(), xxxMS_TrackMove(), xxxSetInternalWindowPos(), xxxSetWindowPlacement(), and xxxSystemParametersInfo().

    00227            :
    00228 *     lprc    - The rect.
    00229 *     dwFlags - One of:
    00230 *         MONITOR_DEFAULTTONULL - If the rect doesn't intersect a monitor,
    00231 *             return NULL.
    00232 *
    00233 *         MONITOR_DEFAULTTOPRIMARY - If the rect doesn't intersect a monitor,
    00234 *             return the primary monitor.
    00235 *
    00236 *         MONITOR_DEFAULTTONEAREST - Return the monitor nearest the rect.
    00237 *
    00238 * History:
    00239 * 22-Sep-1996 adams     Created.
    00240 * 29-Mar-1997 adams     Moved to rtl.
    00241 \***************************************************************************/
    00242
    00243 PMONITOR
    00244 _MonitorFromRect(LPCRECT lprc, DWORD dwFlags)
    00245 {
    00246     PDISPLAYINFO    pDispInfo;
    00247     PMONITOR        pMonitor, pMonitorResult;
    00248     RECT            rc;
    00249     int             area, areaMost;
    00250
    00251     UserAssert(dwFlags == MONITOR_DEFAULTTONULL ||
    00252                dwFlags == MONITOR_DEFAULTTOPRIMARY ||
    00253                dwFlags == MONITOR_DEFAULTTONEAREST);
    00254
    00255     /*
    00256      * Special case the most common case - 1 monitor.
    00257      */
    00258     pDispInfo = GetDispInfo();
    00259     if (pDispInfo->cMonitors == 1 && dwFlags != MONITOR_DEFAULTTONULL)
    00260         return GetPrimaryMonitor();
    00261
    00262     /*
    00263      * If rect is empty, use topleft point.
    00264      */
    00265     if (IsRectEmpty(lprc)) {
    00266         return _MonitorFromPoint(*(LPPOINT)lprc, dwFlags);
    00267     }
    00268
    00269     /*
    00270      * Return the primary monitor if the rectangle covers the desktop.
    00271      */
    00272     if (    lprc->left   <= pDispInfo->rcScreen.left &&
    00273             lprc->top    <= pDispInfo->rcScreen.top &&
    00274             lprc->right  >= pDispInfo->rcScreen.right &&
    00275             lprc->bottom >= pDispInfo->rcScreen.bottom) {
    00276
    00277         return GetPrimaryMonitor();
    00278     }
    00279
    00280     /*
    00281      * Calculate the nearest rectangle by determining which
    00282      * monitor has the greatest intersection with the rectangle.
    00283      */
    00284
    00285     BEGIN_EXCEPTION_HANDLER
    00286
    00287     areaMost = 0;
    00288     for (   pMonitor = REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorFirst);
    00289             pMonitor;
    00290             pMonitor = REBASESHAREDPTR(pMonitor->pMonitorNext)) {
    00291
    00292         if (!(pMonitor->dwMONFlags & MONF_VISIBLE))
    00293             continue;
    00294
    00295         if (IntersectRect(&rc, lprc, &((MONITOR *)pMonitor)->rcMonitor)) {
    00296             if (EqualRect(&rc, lprc))
    00297                 return pMonitor;
    00298
    00299             /*
    00300              * Calculate the area of the intersection. Note that
    00301              * the intersection must be in 16bit coordinats, since
    00302              * we limit monitor rects to 16bit coordinate space.
    00303              * So the result of any area calculation will fit in
    00304              * in an int.
    00305              */
    00306             area = (rc.right - rc.left) * (rc.bottom - rc.top);
    00307             if (area > areaMost) {
    00308                 areaMost = area;
    00309                 pMonitorResult = pMonitor;
    00310             }
    00311         }
    00312     }
    00313
    00314     END_EXCEPTION_HANDLER
    00315
    00316     UserAssert(areaMost >= 0);
    00317     if (areaMost > 0)
    00318         return pMonitorResult;
    00319
    00320
    00321     switch (dwFlags) {
    00322     case MONITOR_DEFAULTTONULL:
    00323         return NULL;
    00324
    00325     case MONITOR_DEFAULTTOPRIMARY:
    00326         return GetPrimaryMonitor();
    00327
    00328     case MONITOR_DEFAULTTONEAREST:
    00329         {
    00330             int dx, dy;
    00331
    00332 #define MONITORFROMRECTALGORITHM(SUMSQUARESMAX, SUMSQUARESTYPE, POINTMULTIPLY)      \
    00333             SUMSQUARESTYPE  sumsquare;                                              \
    00334             SUMSQUARESTYPE  leastsumsquare;                                         \
    00335             leastsumsquare = SUMSQUARESMAX;                                         \
    00336             for (   pMonitor = REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorFirst); \
    00337                     pMonitor;                                                       \
    00338                     pMonitor = REBASESHAREDPTR(pMonitor->pMonitorNext)) {           \
    00339                                                                                     \
    00340                 if (!(pMonitor->dwMONFlags & MONF_VISIBLE))                         \
    00341                     continue;                                                       \
    00342                                                                                     \
    00343                 /*                                                                  \
    00344                  * Determine distance from monitor along x axis.                    \
    00345                  */                                                                 \
    00346                 if (lprc->right <= pMonitor->rcMonitor.left) {                      \
    00347                     /*                                                              \
    00348                      * Add 1 because rectangles do not include the rightmost edge.  \
    00349                      */                                                             \
    00350                     dx = pMonitor->rcMonitor.left - lprc->right + 1;                \
    00351                 } else if (lprc->left < pMonitor->rcMonitor.right) {                \
    00352                     dx = 0;                                                         \
    00353                 } else {                                                            \
    00354                     /*                                                              \
    00355                      * Add 1 because rectangles do not include the rightmost edge.  \
    00356                      */                                                             \
    00357                     dx = lprc->left - (pMonitor->rcMonitor.right - 1);              \
    00358                 }                                                                   \
    00359                                                                                     \
    00360                 /*                                                                  \
    00361                  * Skip this monitor if dx is greater than dx^2 + dy^2.             \
    00362                  * We do this check to avoid multiplication operations.             \
    00363                  */                                                                 \
    00364                 if ((SUMSQUARESTYPE) dx >= leastsumsquare)                          \
    00365                     continue;                                                       \
    00366                                                                                     \
    00367                 /*                                                                  \
    00368                  * Determine distance from monitor along y axis.                    \
    00369                  */                                                                 \
    00370                 if (lprc->bottom <= pMonitor->rcMonitor.top) {                      \
    00371                     /*                                                              \
    00372                      * Add 1 because rectangles do not include the bottommost edge. \
    00373                      */                                                             \
    00374                     dy = pMonitor->rcMonitor.top - lprc->bottom + 1;                \
    00375                 } else if (lprc->top < pMonitor->rcMonitor.bottom) {                \
    00376                     UserAssert(dx != 0 && "This rectangle intersects a monitor, so we shouldn't be here."); \
    00377                     dy = 0;                                                         \
    00378                 } else {                                                            \
    00379                     /*                                                              \
    00380                      * Add 1 because rectangles do not include the bottommost edge. \
    00381                      */                                                             \
    00382                     dy = lprc->top - pMonitor->rcMonitor.bottom + 1;                \
    00383                 }                                                                   \
    00384                                                                                     \
    00385                 /*                                                                  \
    00386                  * Calculate dx^2. Skip this monitor if dx is greater               \
    00387                  * than dx^2 + dy^2. We do this check to avoid                      \
    00388                  * multiplication operations.                                       \
    00389                  */                                                                 \
    00390                 sumsquare = POINTMULTIPLY(dx, dx);                                  \
    00391                 if (sumsquare >= leastsumsquare)                                    \
    00392                     continue;                                                       \
    00393                                                                                     \
    00394                 /*                                                                  \
    00395                  * Skip this monitor if dx^2 + y is greater than dx^2 + dy^2.       \
    00396                  * We do this check to avoid multiplication operations.             \
    00397                  */                                                                 \
    00398                 if (sumsquare + (SUMSQUARESTYPE) dy >= leastsumsquare)              \
                        continue;                                                       \

PMONITOR _MonitorFromWindow | ( | PWND | pwnd,
|  | DWORD | dwFlags
| ) |

Definition at line 426 of file mmrtl.c.

References BEGIN_EXCEPTION_HANDLER, END_EXCEPTION_HANDLER, Int32x32To32, MONITORFROMRECTALGORITHM, and UINT.

Referenced by FixBogusSWP(), GetDialogMonitor(), IsSmallerThanScreen(), MonitorFromWindow(), SelectWindowRgn(), ValidatePositionableWindow(), xxxCBShowListBoxWindow(), xxxCheckFullScreen(), xxxCreateWindowEx(), xxxFreeWindow(), xxxInitSendValidateMinMaxInfo(), xxxMenuWindowProc(), xxxMNPositionHierarchy(), and xxxSetTrayWindow().

    00428                    {
    00429
    00430                 BEGIN_EXCEPTION_HANDLER
    00431                 MONITORFROMRECTALGORITHM(UINT_MAX, UINT, Int32x32To32)
    00432                 END_EXCEPTION_HANDLER
    00433
    00434             }
    00435
    00436             UserAssert(pMonitorResult != (PMONITOR) -1);
    00437             return pMonitorResult;
    00438         }
    00439
    00440     default:
    00441         UserAssertMsg0(0, "Logic error in _MonitorFromWindow, shouldn't have gotten here.");
    00442         break;
    00443     }
    00444
    00445     UserAssertMsg0(0, "Logic error in _MonitorFromWindow, shouldn't have gotten here.");
    00446     return NULL;
    00447 }
    00448
    00449
    00450
    00451 /***************************************************************************\
    00452 * _MonitorFromWindow
    00453 *
    00454 * Calculate the monitor that a window is in or is nearest to. We use
    00455 * the center of the window to determine its location. If the window
    00456 * is minimized, use its normal position.
    00457 *
    00458 * Arguments:
    00459 *     pwnd    - The window.
    00460 *     dwFlags - One of:
    00461 *         MONITOR_DEFAULTTONULL - If the window doesn't intersect a monitor,
    00462 *             return NULL.
    00463 *
    00464 *         MONITOR_DEFAULTTOPRIMARY - If the window doesn't intersect a monitor,
    00465 *             return the primary monitor.
    00466 *
    00467 *         MONITOR_DEFAULTTONEAREST - Return the monitor nearest the window.
    00468 *
    00469 * History:
    00470 * 22-Sep-1996 adams     Created.
    00471 * 29-Mar-1997 adams     Moved to rtl.
    00472 \***************************************************************************/
    00473
    00474 PMONITOR
    00475 _MonitorFromWindow(PWND pwnd, DWORD dwFlags)
    00476 {
    00477     PWND            pwndParent;
    00478
    00479     UserAssert(dwFlags == MONITOR_DEFAULTTONULL ||
    00480                dwFlags == MONITOR_DEFAULTTOPRIMARY ||
    00481                dwFlags == MONITOR_DEFAULTTONEAREST);
    00482
    00483     if (GetDispInfo()->cMonitors == 1 && dwFlags != MONITOR_DEFAULTTONULL) {
    00484         return GetPrimaryMonitor();
    00485     }
    00486
    00487     if (!pwnd)
    00488         goto NoWindow;
    00489
    00490     /*
    00491      * Handle minimized windows.
    00492      */
    00493     if (TestWF(pwnd, WFMINIMIZED))
    00494     {
    00495 #ifdef _USERK_
    00496         CHECKPOINT *    pcp;