|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.