|
|
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.