Annotation of pmsdk/samples/mdi/mdisplit.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************\
                      2: * split.c - Code for window splitting
                      3: *
                      4: * Created by Microsoft Corporation, 1989
                      5: \***************************************************************************/
                      6: 
                      7: #define INCL_WINSYS
                      8: #define INCL_WINCOMMON
                      9: #define INCL_WINMESSAGEMGR
                     10: #define INCL_WINPOINTERS
                     11: #define INCL_WINMENUS
                     12: #define INCL_WININPUT
                     13: #define INCL_WINHEAP
                     14: #define INCL_WINSCROLLBARS
                     15: #define INCL_WINFRAMEMGR
                     16: #define INCL_WINWINDOWMGR
                     17: #define INCL_WINRECTANGLES
                     18: #define INCL_GPIBITMAPS
                     19: #define INCL_GPIPRIMITIVES
                     20: 
                     21: #include <os2.h>
                     22: #include "app.h"
                     23: #include "appdata.h"
                     24: #include "mdi.h"
                     25: #include "mdidata.h"
                     26: 
                     27: VOID InvertRect(HPS, PRECTL);
                     28: VOID TrackSplitbars(HWND, USHORT, SHORT, SHORT);
                     29: VOID FillSplitbarInteriors(USHORT, HWND, HWND);
                     30: HWND QueryBotLeftClient(HWND hwndFrame, NPDOC npdoc);
                     31: VOID DrawTrackRects(HPS, PRECTL, SHORT, SHORT, USHORT);
                     32: VOID MoveTrackRects(HPS, PRECTL, USHORT, SHORT, SHORT, SHORT, SHORT);
                     33: VOID CalcTrackRect(PRECTL, PRECTL, SHORT, USHORT);
                     34: VOID SetSplitbarPos(HWND, PRECTL, SHORT, SHORT, USHORT);
                     35: HWND QueryBotLeftClient(HWND hwndFrame, NPDOC npdoc);
                     36: 
                     37: MRESULT CALLBACK SplitbarWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
                     38: {
                     39:     HPS hps;
                     40:     POINTL ptl;
                     41:     RECTL rclPaint;
                     42:     HWND hwndClient, hwndFrame, hwndOrigin;
                     43:     BOOL fControl;
                     44:     register NPDOC npdoc;
                     45: 
                     46:     switch (msg) {
                     47: 
                     48:     case WM_PAINT:
                     49:         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
                     50:         hwndClient = WinWindowFromID(hwndFrame, FID_CLIENT);
                     51: 
                     52:         npdoc = NPDOCFROMCLIENT(hwndClient);
                     53: 
                     54:         hps = WinBeginPaint(hwnd, NULL, NULL);
                     55: 
                     56:         WinQueryWindowRect(hwnd, &rclPaint);
                     57: 
                     58:         if (WinQueryWindowUShort(hwnd, QWS_ID) == ID_VERTSPLITBAR) {
                     59:             if (npdoc->fs & DF_SPLITVERT) {
                     60:                 WinDrawBorder(hps, &rclPaint, 1, 0, SYSCLR_WINDOWFRAME,
                     61:                             SYSCLR_WINDOW, DB_STANDARD);
                     62:                 /*
                     63:                  * Make the interiors of the splitbars
                     64:                  * visually correct.
                     65:                  */
                     66:                 FillSplitbarInteriors(npdoc->fs, hwnd,
                     67:                         WinWindowFromID(hwndFrame, ID_HORZSPLITBAR));
                     68:             } else {
                     69:                 WinFillRect(hps, &rclPaint, SYSCLR_WINDOWFRAME);
                     70:             }
                     71:         } else {
                     72:             if (npdoc->fs & DF_SPLITHORZ) {
                     73:                 WinDrawBorder(hps, &rclPaint, 0, 1, SYSCLR_WINDOWFRAME,
                     74:                         SYSCLR_WINDOW, DB_STANDARD | DB_INTERIOR);
                     75:             } else {
                     76:                 WinFillRect(hps, &rclPaint, SYSCLR_WINDOWFRAME);
                     77:             }
                     78:         }
                     79: 
                     80:         WinEndPaint(hps);
                     81:         break;
                     82: 
                     83:     case WM_MOUSEMOVE:
                     84:         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
                     85:         hwndClient = WinWindowFromID(hwndFrame, FID_CLIENT);
                     86: 
                     87:         npdoc = NPDOCFROMCLIENT(hwndClient);
                     88: 
                     89:         ptl.x = SHORT1FROMMP(mp1);
                     90:         ptl.y = SHORT2FROMMP(mp1);
                     91: 
                     92:         hwndOrigin = QueryBotLeftClient(hwndFrame, npdoc);
                     93:         WinMapWindowPoints(hwnd, hwndOrigin, (PPOINTL)&ptl, 1);
                     94: 
                     95:         if (WinQueryWindowUShort(hwnd, QWS_ID) == ID_VERTSPLITBAR) {
                     96: 
                     97:             if ((npdoc->fs & DF_SPLITHORZ) &&
                     98:                     ((SHORT)ptl.y > (npdoc->cyHorzSplitPos - (cyHorzSplitbar))) &&
                     99:                     ((SHORT)ptl.y <= (npdoc->cyHorzSplitPos + (cyHorzSplitbar * 2)))) {
                    100:                 WinSetPointer(HWND_DESKTOP, hptrHVSplit);
                    101:             } else {
                    102:                 WinSetPointer(HWND_DESKTOP, hptrVertSplit);
                    103:             }
                    104:         } else {
                    105:             if ((npdoc->fs & DF_SPLITVERT) &&
                    106:                     ((SHORT)ptl.x > (npdoc->cxVertSplitPos - (cxVertSplitbar))) &&
                    107:                     ((SHORT)ptl.x <= (npdoc->cxVertSplitPos + (cxVertSplitbar * 2)))) {
                    108:                 WinSetPointer(HWND_DESKTOP, hptrHVSplit);
                    109:             } else {
                    110:                 WinSetPointer(HWND_DESKTOP, hptrHorzSplit);
                    111:             }
                    112:         }
                    113:         break;
                    114: 
                    115:     case WM_BUTTON1DOWN:
                    116:     case WM_BUTTON1DBLCLK:
                    117:         /*
                    118:          * Get the control key state here so the user doesn't
                    119:          * have to hold it down the whole time to get the
                    120:          * desired effect.
                    121:          */
                    122:         fControl = (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000);
                    123: 
                    124:         hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
                    125:         hwndClient = WinWindowFromID(hwndFrame, FID_CLIENT);
                    126: 
                    127:         /*
                    128:          * Update the entire window before we start
                    129:          * tracking with the splitter bars.
                    130:          */
                    131:         WinUpdateWindow(hwndFrame);
                    132: 
                    133:         npdoc = NPDOCFROMCLIENT(hwndClient);
                    134: 
                    135:         ptl.x = SHORT1FROMMP(mp1);
                    136:         ptl.y = SHORT2FROMMP(mp1);
                    137: 
                    138:         hwndOrigin = QueryBotLeftClient(hwndFrame, npdoc);
                    139:         WinMapWindowPoints(hwnd, hwndOrigin, (PPOINTL)&ptl, 1);
                    140: 
                    141:         if (WinQueryWindowUShort(hwnd, QWS_ID) == ID_VERTSPLITBAR) {
                    142:             if ((npdoc->fs & DF_SPLITHORZ) &&
                    143:                     ((SHORT)ptl.y > (npdoc->cyHorzSplitPos - (cyHorzSplitbar))) &&
                    144:                     ((SHORT)ptl.y <= (npdoc->cyHorzSplitPos + (cyHorzSplitbar * 2)))) {
                    145:                 TrackSplitbars(hwndClient, SPS_VERT | SPS_HORZ, (SHORT)ptl.x,
                    146:                         (SHORT)ptl.y);
                    147:             } else {
                    148:                 TrackSplitbars(hwndClient, SPS_VERT, (SHORT)ptl.x,
                    149:                         (SHORT)ptl.y);
                    150:             }
                    151:         } else {
                    152:             if ((npdoc->fs & DF_SPLITVERT) &&
                    153:                     ((SHORT)ptl.x > (npdoc->cxVertSplitPos - (cxVertSplitbar))) &&
                    154:                     ((SHORT)ptl.x <= (npdoc->cxVertSplitPos + (cxVertSplitbar * 2)))) {
                    155:                 TrackSplitbars(hwndClient, SPS_VERT | SPS_HORZ, (SHORT)ptl.x,
                    156:                         (SHORT)ptl.y);
                    157:             } else {
                    158:                 TrackSplitbars(hwndClient, SPS_HORZ, (SHORT)ptl.x,
                    159:                         (SHORT)ptl.y);
                    160:             }
                    161:         }
                    162: 
                    163:         /*
                    164:          * If the control key is down, we leave
                    165:          * the focus where it is.
                    166:          */
                    167:         if (fControl == FALSE)
                    168:             WinSetFocus(HWND_DESKTOP, hwndClient);
                    169: 
                    170:         break;
                    171: 
                    172:     case WM_MOVE:
                    173:     case WM_SIZE:
                    174:         WinInvalidateRect(hwnd, NULL, FALSE);
                    175:         break;
                    176: 
                    177:     default:
                    178:         return(WinDefWindowProc(hwnd, msg, mp1, mp2));
                    179:         break;
                    180:     }
                    181: 
                    182:     return (0L);
                    183: }
                    184: 
                    185: 
                    186: VOID FillSplitbarInteriors(USHORT fs, HWND hwndVert, HWND hwndHorz)
                    187: {
                    188:     HPS hps;
                    189:     RECTL rclVertSplitbar, rclHorzSplitbar;
                    190: 
                    191:     if (fs & DF_SPLITVERT) {
                    192:         hps = WinGetPS(hwndVert);
                    193:         WinQueryWindowRect(hwndVert, &rclVertSplitbar);
                    194:         WinInflateRect(NULL, &rclVertSplitbar, -cxBorder, 0);
                    195:         WinFillRect(hps, &rclVertSplitbar, SYSCLR_WINDOW);
                    196:         WinReleasePS(hps);
                    197:     }
                    198: 
                    199:     if (fs & DF_SPLITHORZ) {
                    200:         hps = WinGetPS(hwndHorz);
                    201:         WinQueryWindowRect(hwndHorz, &rclHorzSplitbar);
                    202:         WinInflateRect(NULL, &rclHorzSplitbar, 0, -cyBorder);
                    203:         WinFillRect(hps, &rclHorzSplitbar, SYSCLR_WINDOW);
                    204:         WinReleasePS(hps);
                    205:     }
                    206: }
                    207: 
                    208: 
                    209: BOOL CreateSplitbarWindows(HWND hwndFrame, NPDOC npdoc)
                    210: {
                    211:     USHORT fsStyle;
                    212:     register NPVIEW npview, npviewNew;
                    213:     HWND hwndNewClient;
                    214: 
                    215:     fsStyle = npdoc->fsStyle;
                    216:     npview = npdoc->npviewFirst;
                    217: 
                    218:     if (fsStyle & DS_VERTSPLITBAR) {
                    219:         if (WinCreateWindow(hwndFrame, WC_SCROLLBAR, "",
                    220:                 SBS_HORZ, 0, 0, 0, 0, hwndFrame,
                    221:                 WinWindowFromID(hwndFrame, FID_HORZSCROLL),
                    222:                 ID_HORZSCROLL2, NULL, NULL) == NULL)
                    223:             return (FALSE);
                    224: 
                    225:         if (WinCreateWindow(hwndFrame, szSplitbarClass, "",
                    226:                 (ULONG)SPS_VERT, 0, 0, 0, 0, hwndFrame,
                    227:                 WinWindowFromID(hwndFrame, FID_MINMAX),
                    228:                 ID_VERTSPLITBAR, NULL, NULL) == NULL)
                    229:             return (FALSE);
                    230: 
                    231:         hwndNewClient = WinCreateWindow(hwndFrame, szDocClass, "",
                    232:                 0L, 0, 0, 0, 0, hwndFrame,
                    233:                 WinWindowFromID(hwndFrame, FID_CLIENT),
                    234:                 ID_CLIENT2, NULL, NULL);
                    235:         if (hwndNewClient == NULL)
                    236:             return (FALSE);
                    237: 
                    238:         /*
                    239:          * Link ID_CLIENT2 into npdoc's view list.
                    240:          */
                    241:         npviewNew = NPVIEWFROMCLIENT(hwndNewClient);
                    242:         npview->npviewNext = npviewNew;
                    243:         npview = npviewNew;
                    244:     }
                    245: 
                    246:     if (fsStyle & DS_HORZSPLITBAR) {
                    247:         if (WinCreateWindow(hwndFrame, WC_SCROLLBAR, "",
                    248:                 SBS_VERT, 0, 0, 0, 0, hwndFrame,
                    249:                 WinWindowFromID(hwndFrame, FID_VERTSCROLL),
                    250:                 ID_VERTSCROLL2, NULL, NULL) == NULL)
                    251:             return (FALSE);
                    252: 
                    253:         if (WinCreateWindow(hwndFrame, szSplitbarClass, "",
                    254:                 (ULONG)SPS_HORZ, 0, 0, 0, 0, hwndFrame,
                    255:                 WinWindowFromID(hwndFrame, FID_MINMAX),
                    256:                 ID_HORZSPLITBAR, NULL, NULL) == NULL)
                    257:             return (FALSE);
                    258: 
                    259:         /*
                    260:          * If we're split vertically as well, then we want to
                    261:          * insert ID_CLIENT3 behind ID_CLIENT2 and create
                    262:          * ID_CLIENT4 behind CLIENT3, otherwise we just create
                    263:          * ID_CLIENT3 behind FID_CLIENT.
                    264:          */
                    265:         if (fsStyle & DS_VERTSPLITBAR) {
                    266:             hwndNewClient = WinCreateWindow(hwndFrame, szDocClass, "",
                    267:                     0L, 0, 0, 0, 0, hwndFrame,
                    268:                     WinWindowFromID(hwndFrame, ID_CLIENT2),
                    269:                     ID_CLIENT3, NULL, NULL);
                    270:             if (hwndNewClient == NULL)
                    271:                 return (FALSE);
                    272: 
                    273:             /*
                    274:              * Link ID_CLIENT3 into npdoc's view list.
                    275:              */
                    276:             npviewNew = NPVIEWFROMCLIENT(hwndNewClient);
                    277:             npview->npviewNext = npviewNew;
                    278:             npview = npviewNew;
                    279: 
                    280:             hwndNewClient = WinCreateWindow(hwndFrame, szDocClass, "",
                    281:                     0L, 0, 0, 0, 0, hwndFrame,
                    282:                     WinWindowFromID(hwndFrame, ID_CLIENT3),
                    283:                     ID_CLIENT4, NULL, NULL);
                    284:             if (hwndNewClient == NULL)
                    285:                 return (FALSE);
                    286: 
                    287:             /*
                    288:              * Link ID_CLIENT4 into npdoc's view list.
                    289:              */
                    290:             npviewNew = NPVIEWFROMCLIENT(hwndNewClient);
                    291:             npview->npviewNext = npviewNew;
                    292:             npview = npviewNew;
                    293: 
                    294:         } else {
                    295:             hwndNewClient = WinCreateWindow(hwndFrame, szDocClass, "",
                    296:                     0L, 0, 0, 0, 0, hwndFrame,
                    297:                     WinWindowFromID(hwndFrame, FID_CLIENT),
                    298:                     ID_CLIENT3, NULL, NULL);
                    299:             if (hwndNewClient == NULL)
                    300:                 return (FALSE);
                    301: 
                    302:             /*
                    303:              * Link ID_CLIENT3 into npdoc's view list.
                    304:              */
                    305:             npviewNew = NPVIEWFROMCLIENT(hwndNewClient);
                    306:             npview->npviewNext = npviewNew;
                    307:             npview = npviewNew;
                    308:         }
                    309:     }
                    310: 
                    311:     return (TRUE);
                    312: }
                    313: 
                    314: 
                    315: HWND QueryBotLeftClient(HWND hwndFrame, NPDOC npdoc)
                    316: {
                    317:     if (npdoc->fs & DF_SPLITHORZ) {
                    318:         /*
                    319:          * If there isn't enough room to split
                    320:          * then only the main client will be
                    321:          * visible so we'll use it.
                    322:          */
                    323:         if (WinIsWindowVisible(WinWindowFromID(hwndFrame, ID_HORZSPLITBAR)))
                    324:             return (WinWindowFromID(hwndFrame, ID_CLIENT3));
                    325:         else
                    326:             return (WinWindowFromID(hwndFrame, FID_CLIENT));
                    327: 
                    328:     } else {
                    329:         return (WinWindowFromID(hwndFrame, FID_CLIENT));
                    330:     }
                    331: }
                    332: 
                    333: 
                    334: 
                    335: VOID TrackSplitbars(HWND hwndClient, register USHORT fsTrack, SHORT xMouse,
                    336:         SHORT yMouse)
                    337: {
                    338:     SHORT x, y;
                    339:     SHORT xNew, yNew;
                    340:     HPS hps;
                    341:     RECTL rclClient, rclClientScreen;
                    342:     QMSG qmsg;
                    343:     AREABUNDLE abnd;
                    344:     HWND hwndFrame, hwndOrigin;
                    345:     register NPDOC npdoc;
                    346:     POINTL ptlPointer;
                    347: 
                    348:     hwndFrame = WinQueryWindow(hwndClient, QW_PARENT, FALSE);
                    349: 
                    350:     WinLockWindowUpdate(HWND_DESKTOP, hwndFrame);
                    351: 
                    352:     /*
                    353:      * If we're split horizontally then we want the
                    354:      * origin to be a ID_CLIENT3's origin, otherwise
                    355:      * we want FID_CLIENT's origin.
                    356:      */
                    357:     npdoc = NPDOCFROMCLIENT(hwndClient);
                    358:     hwndOrigin = QueryBotLeftClient(hwndFrame, npdoc);
                    359: 
                    360:     /*
                    361:      * We use WinCalcFrameRect() to get the client rectangle
                    362:      * rather than WinQueryWindowRect() because the window
                    363:      * might already be split, so hwndClient's rectangle wouldn't
                    364:      * necessarily include the area we want.
                    365:      */
                    366:     WinQueryWindowRect(hwndFrame, &rclClient);
                    367: 
                    368:     /*
                    369:      * Map rectangle to screen coordinates because
                    370:      * WinCalcFrameRect() will byte-align the client.
                    371:      */
                    372:     WinMapWindowPoints(hwndFrame, HWND_DESKTOP, (PPOINTL)&rclClient, 2);
                    373:     WinCalcFrameRect(hwndFrame, &rclClient, TRUE);
                    374: 
                    375:     WinCopyRect(NULL, &rclClientScreen, &rclClient);
                    376:     WinMapWindowPoints(HWND_DESKTOP, hwndOrigin, (PPOINTL)&rclClient, 2);
                    377: 
                    378:     WinSetCapture(HWND_DESKTOP, hwndOrigin);
                    379: 
                    380:     /*
                    381:      * We get a PSF_PARENTCLIP PS so we can draw the
                    382:      * splitbars through the other client windows,
                    383:      * but still get the PS origin we want.
                    384:      */
                    385:     hps = WinGetClipPS(hwndOrigin, NULL,
                    386:             PSF_PARENTCLIP | PSF_LOCKWINDOWUPDATE);
                    387: 
                    388:     abnd.usSymbol = PATSYM_HALFTONE;
                    389:     abnd.lColor = CLR_TRUE;
                    390:     abnd.lBackColor = CLR_FALSE;
                    391:     GpiSetAttrs(hps, PRIM_AREA, ABB_SYMBOL | ABB_COLOR | ABB_BACK_COLOR, 0L,
                    392:             (PBUNDLE)&abnd);
                    393: 
                    394:     if (fsTrack & SPS_HORZ) {
                    395:         if (npdoc->fs & DF_SPLITHORZ) {
                    396:             y = npdoc->cyHorzSplitPos + (cyHorzSplitbar / 2);
                    397:         } else if (npdoc->fs & DF_HSPLITOVERFLOW) {
                    398:             y = 0;
                    399:             /*
                    400:              * Clear the overflow flag since the
                    401:              * user can't track to an overflown
                    402:              * position.
                    403:              */
                    404:             npdoc->fs &= ~DF_HSPLITOVERFLOW;
                    405:         } else {
                    406:             y = (SHORT)rclClient.yTop - (cyHorzSplitbar / 2);
                    407:         }
                    408:     }
                    409: 
                    410:     if (fsTrack & SPS_VERT) {
                    411:         if (npdoc->fs & DF_SPLITVERT) {
                    412:             x = npdoc->cxVertSplitPos + (cxVertSplitbar / 2);
                    413:         } else if (npdoc->fs & DF_VSPLITOVERFLOW) {
                    414:             x = (SHORT)rclClient.xRight - cxVertSplitbar;
                    415:             /*
                    416:              * Clear the overflow flag since the
                    417:              * user can't track to an overflown
                    418:              * position.
                    419:              */
                    420:             npdoc->fs &= ~DF_VSPLITOVERFLOW;
                    421:         } else {
                    422:             x = (cxVertSplitbar / 2);
                    423:         }
                    424:     }
                    425: 
                    426:     /*
                    427:      * If xMouse is -1, then we want to set the pointer
                    428:      * position to the position of the splitbars.
                    429:      */
                    430:     if (xMouse == -1) {
                    431:         xMouse = x;
                    432:         yMouse = y;
                    433:         ptlPointer.x = x;
                    434:         ptlPointer.y = y;
                    435:         WinMapWindowPoints(hwndOrigin, HWND_DESKTOP, (PPOINTL)&ptlPointer, 1);
                    436:         WinSetPointerPos(HWND_DESKTOP, (SHORT)ptlPointer.x, (SHORT)ptlPointer.y);
                    437:     }
                    438: 
                    439:     DrawTrackRects(hps, &rclClient, x, y, fsTrack);
                    440: 
                    441:     while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, NULL, NULL)) {
                    442:         switch (qmsg.msg) {
                    443: 
                    444:         case WM_BUTTON1UP:
                    445:             DrawTrackRects(hps, &rclClient, x, y, fsTrack);
                    446:             WinLockWindowUpdate(HWND_DESKTOP, NULL);
                    447:             SetSplitbarPos(hwndClient, &rclClient, x, y, fsTrack);
                    448:             goto exit_no_unlock;
                    449: 
                    450:         case WM_CHAR:
                    451:             if ((((USHORT)qmsg.mp1 &
                    452:                     (KC_KEYUP | KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP))
                    453:                     == 0) && ((USHORT)qmsg.mp1 & KC_VIRTUALKEY)) {
                    454: 
                    455:                 WinQueryPointerPos(HWND_DESKTOP, (PPOINTL)&ptlPointer);
                    456:                 switch (SHORT2FROMMP(qmsg.mp2)) {
                    457: 
                    458:                 case VK_UP:
                    459:                     ptlPointer.y += (cyHorzSplitbar * 2);
                    460:                     break;
                    461: 
                    462:                 case VK_DOWN:
                    463:                     ptlPointer.y -= (cyHorzSplitbar * 2);
                    464:                     break;
                    465: 
                    466:                 case VK_RIGHT:
                    467:                     ptlPointer.x += (cxVertSplitbar * 2);
                    468:                     break;
                    469: 
                    470:                 case VK_LEFT:
                    471:                     ptlPointer.x -= (cxVertSplitbar * 2);
                    472:                     break;
                    473: 
                    474:                 case VK_ENTER:
                    475:                 case VK_NEWLINE:
                    476:                     DrawTrackRects(hps, &rclClient, x, y, SPS_HORZ | SPS_VERT);
                    477:                     WinLockWindowUpdate(HWND_DESKTOP, NULL);
                    478:                     SetSplitbarPos(hwndClient, &rclClient, x, y,
                    479:                             SPS_HORZ | SPS_VERT);
                    480:                     goto exit_no_unlock;
                    481: 
                    482:                 case VK_ESC:
                    483:                     DrawTrackRects(hps, &rclClient, x, y, SPS_HORZ | SPS_VERT);
                    484:                     goto exit;
                    485:                 }
                    486:                 if ((SHORT)ptlPointer.x < (SHORT)rclClientScreen.xLeft)
                    487:                     ptlPointer.x = rclClientScreen.xLeft;
                    488:                 else if ((SHORT)ptlPointer.x > (SHORT)rclClientScreen.xRight)
                    489:                     ptlPointer.x = rclClientScreen.xRight;
                    490: 
                    491:                 if ((SHORT)ptlPointer.y < (SHORT)rclClientScreen.yBottom)
                    492:                     ptlPointer.y = rclClientScreen.yBottom;
                    493:                 else if ((SHORT)ptlPointer.y > (SHORT)rclClientScreen.yTop)
                    494:                     ptlPointer.y = rclClientScreen.yTop;
                    495: 
                    496:                 WinSetPointerPos(HWND_DESKTOP, (SHORT)ptlPointer.x,
                    497:                         (SHORT)ptlPointer.y);
                    498:             }
                    499:             break;
                    500: 
                    501:         case WM_MOUSEMOVE:
                    502:             xNew = x + (SHORT1FROMMP(qmsg.mp1) - xMouse);
                    503:             xMouse = SHORT1FROMMP(qmsg.mp1);
                    504:             yNew = y + (SHORT2FROMMP(qmsg.mp1) - yMouse);
                    505:             yMouse = SHORT2FROMMP(qmsg.mp1);
                    506: 
                    507:             MoveTrackRects(hps, &rclClient, fsTrack, x, y, xNew, yNew);
                    508:             x = xNew;
                    509:             y = yNew;
                    510:             break;
                    511: 
                    512:         default:
                    513:             WinDispatchMsg(NULL, (PQMSG)&qmsg);
                    514:             break;
                    515:         }
                    516:     }
                    517: 
                    518: exit:
                    519:     WinLockWindowUpdate(HWND_DESKTOP, NULL);
                    520: exit_no_unlock:
                    521:     WinReleasePS(hps);
                    522:     WinSetCapture(HWND_DESKTOP, NULL);
                    523: }
                    524: 
                    525: 
                    526: VOID SetSplitbarPos(HWND hwndClient, PRECTL prclClient, SHORT x, SHORT y,
                    527:         USHORT fsTrack)
                    528: {
                    529:     register NPDOC npdoc;
                    530:     register NPVIEW npview1, npview2, npview3, npview4;
                    531:     HWND hwndFrame;
                    532:     RECTL rclTrack;
                    533: 
                    534:     npview1 = (NPVIEW)WinQueryWindowUShort(hwndClient, QWS_USER);
                    535:     npdoc = npview1->npdoc;
                    536:     hwndFrame = WinQueryWindow(hwndClient, QW_PARENT, FALSE);
                    537: 
                    538:     if (npdoc->fsStyle & DS_VERTSPLITBAR) {
                    539:         npview2 = (NPVIEW)WinQueryWindowUShort(
                    540:                 WinWindowFromID(hwndFrame, ID_CLIENT2), QWS_USER);
                    541:     }
                    542: 
                    543:     if (npdoc->fsStyle & DS_HORZSPLITBAR) {
                    544:         npview3 = (NPVIEW)WinQueryWindowUShort(
                    545:                 WinWindowFromID(hwndFrame, ID_CLIENT3), QWS_USER);
                    546:     }
                    547: 
                    548:     if (npdoc->fsStyle & (DS_HORZSPLITBAR | DS_VERTSPLITBAR)) {
                    549:         npview4 = (NPVIEW)WinQueryWindowUShort(
                    550:                 WinWindowFromID(hwndFrame, ID_CLIENT4), QWS_USER);
                    551:     }
                    552: 
                    553:     if (fsTrack & SPS_VERT) {
                    554:         CalcTrackRect(prclClient, &rclTrack, x, SPS_VERT);
                    555:         npdoc->cxVertSplitPos = (SHORT)rclTrack.xLeft;
                    556:         if ((npdoc->cxVertSplitPos < cxVertSplitbar) ||
                    557:                 (npdoc->cxVertSplitPos >
                    558:                 ((SHORT)prclClient->xRight - (cxVertSplitbar * 2)))) {
                    559:             npdoc->fs &= ~DF_SPLITVERT;
                    560:         } else {
                    561:             npdoc->fs |= DF_SPLITVERT;
                    562: 
                    563:             /*
                    564:              * Setup ID_CLIENT2 with the same yOrigin
                    565:              * as FID_CLIENT.
                    566:              */
                    567:             npview2->yOrigin = npview1->yOrigin;
                    568: 
                    569:             /*
                    570:              * If we were horizontally split already, then
                    571:              * set ID_CLIENT4 to the same yOrigin
                    572:              * as ID_CLIENT3.
                    573:              */
                    574:             if (npdoc->fs & DF_SPLITHORZ)
                    575:                 npview4->yOrigin = npview3->yOrigin;
                    576:         }
                    577:     }
                    578: 
                    579:     if (fsTrack & SPS_HORZ) {
                    580:         CalcTrackRect(prclClient, &rclTrack, y, SPS_HORZ);
                    581:         npdoc->cyHorzSplitPos = (SHORT)rclTrack.yBottom;
                    582:         if ((npdoc->cyHorzSplitPos >
                    583:                 ((SHORT)prclClient->yTop - (cyHorzSplitbar * 2))) ||
                    584:                 (npdoc->cyHorzSplitPos < cyHorzSplitbar)) {
                    585:             npdoc->fs &= ~DF_SPLITHORZ;
                    586:         } else {
                    587:             npdoc->fs |= DF_SPLITHORZ;
                    588: 
                    589:             /*
                    590:              * Setup ID_CLIENT3 with the same xOrigin
                    591:              * as FID_CLIENT.
                    592:              */
                    593:             npview3->xOrigin = npview1->xOrigin;
                    594: 
                    595:             /*
                    596:              * If we were vertically split already, then
                    597:              * set ID_CLIENT4 to the same xOrigin
                    598:              * as ID_CLIENT2.
                    599:              */
                    600:             if (npdoc->fs & DF_SPLITHORZ)
                    601:                 npview4->xOrigin = npview2->xOrigin;
                    602:         }
                    603:     }
                    604: 
                    605:     WinSendMsg(hwndFrame, WM_UPDATEFRAME, 0L, 0L);
                    606: }
                    607: 
                    608: 
                    609: VOID CalcTrackRect(PRECTL prclClient, PRECTL prcl, SHORT coord, USHORT fsTrack)
                    610: {
                    611:     if (fsTrack & SPS_VERT) {
                    612:         WinSetRect(NULL, prcl, coord - (cxVertSplitbar / 2), 0,
                    613:                 coord + (cxVertSplitbar - (cxVertSplitbar / 2)),
                    614:                 (SHORT)prclClient->yTop);
                    615: 
                    616:         if ((SHORT)prcl->xLeft < 0)
                    617:             WinOffsetRect(NULL, prcl, (SHORT)-(prcl->xLeft), 0);
                    618:         else if ((SHORT)prcl->xRight > (SHORT)prclClient->xRight)
                    619:             WinOffsetRect(NULL, prcl,
                    620:                     -((SHORT)prcl->xRight - (SHORT)prclClient->xRight), 0);
                    621:     } else if (fsTrack & SPS_HORZ) {
                    622:         WinSetRect(NULL, prcl, 0, coord - (cyHorzSplitbar / 2),
                    623:                 (SHORT)prclClient->xRight,
                    624:                 coord + (cyHorzSplitbar - (cyHorzSplitbar / 2)));
                    625: 
                    626:         if ((SHORT)prcl->yBottom < 0)
                    627:             WinOffsetRect(NULL, prcl, 0, (SHORT)-(prcl->yBottom));
                    628:         else if ((SHORT)prcl->yTop > (SHORT)prclClient->yTop)
                    629:             WinOffsetRect(NULL, prcl,
                    630:                     0, -((SHORT)prcl->yTop - (SHORT)prclClient->yTop));
                    631:     }
                    632: }
                    633: 
                    634: 
                    635: VOID DrawTrackRects(HPS hps, PRECTL prclClient, SHORT x, SHORT y,
                    636:         USHORT fsTrack)
                    637: {
                    638:     RECTL rclFill;
                    639: 
                    640:     VOID CalcTrackRect(PRECTL, PRECTL, SHORT, USHORT);
                    641: 
                    642:     if (fsTrack & SPS_VERT) {
                    643:         CalcTrackRect(prclClient, (PRECTL)&rclFill, x, SPS_VERT);
                    644: 
                    645:         InvertRect(hps, (PRECTL)&rclFill);
                    646:     }
                    647: 
                    648:     if (fsTrack & SPS_HORZ) {
                    649:         CalcTrackRect(prclClient, (PRECTL)&rclFill, y, SPS_HORZ);
                    650: 
                    651:         InvertRect(hps, (PRECTL)&rclFill);
                    652:     }
                    653: }
                    654: 
                    655: 
                    656: VOID MoveTrackRects(HPS hps, PRECTL prclClient, USHORT fsTrack, SHORT xOld,
                    657:         SHORT yOld, SHORT xNew, SHORT yNew)
                    658: {
                    659:     RECTL rclOld, rclNew, rclScratch;
                    660:     VOID CalcTrackRect(PRECTL, PRECTL, SHORT, USHORT);
                    661: 
                    662:     if (fsTrack & SPS_VERT) {
                    663:         CalcTrackRect(prclClient, (PRECTL)&rclOld, xOld, SPS_VERT);
                    664:         CalcTrackRect(prclClient, (PRECTL)&rclNew, xNew, SPS_VERT);
                    665: 
                    666:         if (WinSubtractRect(NULL, &rclScratch, &rclOld, &rclNew))
                    667:             InvertRect(hps, (PRECTL)&rclScratch);
                    668:         if (WinSubtractRect(NULL, &rclScratch, &rclNew, &rclOld))
                    669:             InvertRect(hps, (PRECTL)&rclScratch);
                    670:     }
                    671: 
                    672:     if (fsTrack & SPS_HORZ) {
                    673:         CalcTrackRect(prclClient, (PRECTL)&rclOld, yOld, SPS_HORZ);
                    674:         CalcTrackRect(prclClient, (PRECTL)&rclNew, yNew, SPS_HORZ);
                    675: 
                    676:         if (WinSubtractRect(NULL, &rclScratch, &rclOld, &rclNew))
                    677:             InvertRect(hps, (PRECTL)&rclScratch);
                    678:         if (WinSubtractRect(NULL, &rclScratch, &rclNew, &rclOld))
                    679:             InvertRect(hps, (PRECTL)&rclScratch);
                    680:     }
                    681: }
                    682: 
                    683: 
                    684: VOID InvertRect(HPS hps, PRECTL prcl)
                    685: {
                    686:     RECTL rclParm[2];
                    687: 
                    688:     WinCopyRect(NULL, (PRECTL)&rclParm[0], (PRECTL)prcl);
                    689:     rclParm[1].xLeft = 0;
                    690:     rclParm[1].yBottom = 0;
                    691:     GpiBitBlt(hps, (HPS)NULL, 3L, (PPOINTL)rclParm, ROP_PATINVERT, 0L);
                    692: }
                    693: 
                    694: 
                    695: VOID FindSwp(PSWP aswp, register USHORT cswp, USHORT id, PSWP FAR *ppswp)
                    696: {
                    697:     register i;
                    698: 
                    699:     for (i = 0; i < cswp; i++) {
                    700:         if (WinQueryWindowUShort(aswp[i].hwnd, QWS_ID) == id) {
                    701:             *ppswp = &aswp[i];
                    702:             return;
                    703:         }
                    704:     }
                    705: }
                    706: 
                    707: 
                    708: /*
                    709:  * Set the SWP structure to the passed in parameters.
                    710:  *
                    711:  * This routine is dependent on the order of elements
                    712:  * in the SWP structure.
                    713:  */
                    714: VOID SetSwpPos(PSWP pswp, HWND hwnd, HWND hwndInsertBehind, SHORT x, SHORT y,
                    715:         SHORT cx, SHORT cy, USHORT fs)
                    716: {
                    717:     /*
                    718:        *pswp = *((PSWP)&fs);
                    719:     */
                    720:     pswp->hwnd                 =       hwnd;
                    721:     pswp->hwndInsertBehind     =       hwndInsertBehind;
                    722:     pswp->x                    =       x;
                    723:     pswp->y                    =       y;
                    724:     pswp->cx                   =       cx;
                    725:     pswp->cy                   =       cy;
                    726:     pswp->fs                   =       fs;
                    727: }
                    728: 
                    729: 
                    730: VOID HideSwp(PSWP pswp, HWND hwnd, USHORT *piswp)
                    731: {
                    732:     if (WinIsWindowVisible(hwnd)) {
                    733:         SetSwpPos(pswp, hwnd, NULL, 0, 0, 0, 0, SWP_HIDE);
                    734:         (*piswp)++;
                    735:     }
                    736: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.