|
|
1.1 root 1: /*--------------------- file identification ------------------------*/
2:
3: /*
4: * within.c
5: *
6: * worlds within worlds
7: *
8: *
9: * Created by Microsoft Corp., 1988
10: */
11:
12:
13: /*---------------------- include files -----------------------------*/
14:
15: /* os2 pm stuff */
16: #define INCL_WIN
17: #include <os2.h>
18:
19: /* ansi c stuff */
20: #include <stdlib.h>
21: #include <stdio.h>
22: #include <string.h>
23:
24: /* within stuff */
25: #include "within.h"
26:
27:
28: /*------------------------------ main ------------------------------*/
29:
30: /* main program block */
31: SHORT cdecl main ()
32: {
33: /* local variables */
34: ULONG afInitFlags ;
35:
36: /* try to initialize */
37: if (initialize(& afInitFlags))
38:
39: /* initialized successfully, so run main message loop*/
40: messageLoop() ;
41:
42: /* clean up */
43: cleanUp(afInitFlags) ;
44:
45: /* so long */
46: return (0) ;
47: }
48:
49:
50: /*--------------------------- initialize ---------------------------*/
51:
52: /* initialization procedure */
53:
54: /* returns true if successful, false if not */
55:
56: /* sets bits in a longword to indicate
57: * success of various initialization activities
58: */
59:
60: BOOL initialize (ULONG * pafInitFlags)
61: {
62: /* local constants */
63: #define DEFAULT_QUEUE_SIZE 0
64:
65: /* init the result flags */
66: *pafInitFlags = 0L ;
67:
68: /* try to initialize this application thread's use of the PM */
69: if (habAnchorBlock = WinInitialize (0))
70: *pafInitFlags |= GOT_ANCHOR_BLOCK ;
71: else
72: return FALSE ;
73:
74: /* try to create a message queue */
75: if (hmqMessageQueue =
76: WinCreateMsgQueue(habAnchorBlock, DEFAULT_QUEUE_SIZE))
77: *pafInitFlags |= GOT_MESSAGE_QUEUE ;
78: else
79: return FALSE ;
80:
81: /* try to register our client window class */
82: if (WinRegisterClass ( habAnchorBlock,
83: szOurNameClient,
84: ChildClientWndProc,
85: 0L,
86: sizeof (winbytz) ))
87: *pafInitFlags |= GOT_CLIENT_CLASS ;
88: else
89: return FALSE ;
90:
91: /* try to create a top-level frame window */
92: if (createNewChildStdFrame(
93: & hwndTopFrame, & hwndTopClient, HWND_DESKTOP))
94: *pafInitFlags |= GOT_TOP_FRAME_WINDOW ;
95: else
96: return FALSE ;
97:
98: /* made it */
99: return TRUE ;
100:
101: /* kill local constants */
102: #undef DEFAULT_QUEUE_SIZE
103: }
104:
105:
106: /*---------------------createNewChildStdFrame ----------------------*/
107:
108: BOOL createNewChildStdFrame (PHWND phwndFrame, PHWND phwndClient,
109: HWND hwndParent)
110:
111: {
112: /* local variables */
113: ULONG bflWindowStyles ;
114: RECTL rclParentRect ;
115: SHORT sFrameWidth ;
116: SHORT sFrameHeight ;
117: SHORT sBLCx ;
118: SHORT sBLCy ;
119: USHORT usChildNumber ;
120: USHORT usGeneration ;
121: CHAR szOurTitle[80] ;
122: CHAR szPathString[256] ;
123:
124: /* prepare style bits for our window creation attempt */
125: bflWindowStyles = FCF_SYSMENU | FCF_TITLEBAR |
126: FCF_SIZEBORDER | FCF_MINMAX |
127: FCF_MENU ;
128:
129: /* special case on first window */
130: if (hwndParent != HWND_DESKTOP)
131: {
132: /* not the first window */
133:
134: /* get a child number for the child */
135: /* all windows except the first go here */
136: usChildNumber = WinQueryWindowUShort (hwndParent,
137: US_NUM_CHILDREN) ;
138:
139: /* get a generation for the child */
140: usGeneration = WinQueryWindowUShort (hwndParent,
141: US_GENERATION) + 1 ;
142: }
143: else
144: {
145: /* first window */
146:
147: /* get a child number for the child */
148: usChildNumber = 0 ;
149:
150: /* get a generation for the child */
151: usGeneration = 0 ;
152: }
153:
154: /* initialize the window's path string */
155: sprintf (szPathString, "%i", usChildNumber) ;
156:
157: if (hwndParent != HWND_DESKTOP)
158: /* figure the window's path string */
159: getPathString (hwndParent, szPathString) ;
160:
161:
162: /* adjust the window title to suit the generation and level */
163: sprintf (szOurTitle, "%s %s",
164: szOurNameTitle, szPathString) ;
165:
166: /* try to create a standard frame window */
167: if (! (*phwndFrame = WinCreateStdWindow (hwndParent,
168: FS_ICON, & bflWindowStyles,
169: szOurNameClient, szOurTitle,
170: WS_VISIBLE, NULL, RSRC_ID_within,
171: phwndClient)))
172: return FALSE ;
173:
174: /* for first window, record desktop window's handle */
175: if (hwndParent == HWND_DESKTOP)
176: hwndDeskTop = WinQueryWindow (*phwndFrame, QW_PARENT, FALSE) ;
177:
178: /* get the parent window's size */
179: WinQueryWindowRect (hwndParent, & rclParentRect) ;
180:
181: /* let's make our new window a simple
182: * fraction of that size, centered
183: */
184: sFrameWidth = (SHORT) ((rclParentRect.xRight -
185: rclParentRect.xLeft) * 19 / 20) ;
186: sFrameHeight = (SHORT) ((rclParentRect.yTop -
187: rclParentRect.yBottom) * 19 / 20) ;
188: sBLCx = (SHORT) (sFrameWidth / 40) ;
189: sBLCy = (SHORT) (sFrameHeight / 40) ;
190:
191: /* move, size, and show the window */
192: WinSetWindowPos (*phwndFrame,
193: HWND_TOP,
194: sBLCx, sBLCy,
195: sFrameWidth, sFrameHeight,
196: SWP_SIZE | SWP_MOVE |
197: SWP_SHOW | SWP_ACTIVATE) ;
198:
199: /* tell the parent a child's been born by upping its # of children */
200: if (hwndParent != HWND_DESKTOP)
201: WinSetWindowUShort(hwndParent, US_NUM_CHILDREN, usChildNumber + 1) ;
202:
203: /* set this window's child id */
204: WinSetWindowUShort(*phwndClient, US_CHILD_ID, usChildNumber) ;
205:
206: /* store a generation number in the window */
207: WinSetWindowUShort(*phwndClient, US_GENERATION, usGeneration) ;
208:
209: /* made it; return signalling success */
210: return TRUE ;
211:
212: }
213:
214:
215: /*------------------------- getPathString --------------------------*/
216:
217: VOID getPathString (HWND hwndGrandParent, CHAR * szPathString)
218: {
219: /* stop recursing when we hit the desktop */
220: if (hwndGrandParent == HWND_DESKTOP || hwndGrandParent == hwndDeskTop)
221: {
222: reverseString (szPathString) ;
223: return ;
224: }
225:
226: /* add child number of grandparent to path string */
227: sprintf(szPathString, "%s%s%i", szPathString,"-",
228: WinQueryWindowUShort (hwndGrandParent, US_CHILD_ID)) ;
229:
230: /* figure out grandparent's parent */
231: hwndGrandParent = WinQueryWindow (hwndGrandParent, QW_PARENT, FALSE) ;
232: hwndGrandParent = WinQueryWindow (hwndGrandParent, QW_PARENT, FALSE) ;
233:
234: /* recurse on grandparent's grandparent */
235: getPathString(hwndGrandParent, szPathString) ;
236: }
237:
238:
239: /*--------------------------- reverseString ------------------------*/
240:
241: /* reverses a string of characters in place */
242:
243: VOID reverseString (CHAR szSomeString[])
244: {
245: CHAR chHoldingCell ;
246: USHORT usIndexFromLeft ;
247: USHORT usIndexFromRight ;
248:
249: for (usIndexFromLeft = 0, usIndexFromRight = strlen (szSomeString) - 1 ;
250: usIndexFromLeft < usIndexFromRight;
251: usIndexFromLeft++, usIndexFromRight--)
252: {
253: chHoldingCell =szSomeString[usIndexFromLeft] ;
254: szSomeString[usIndexFromLeft] = szSomeString[usIndexFromRight] ;
255: szSomeString[usIndexFromRight] = chHoldingCell ;
256: }
257: }
258:
259: /*---------------------------- messageLoop -------------------------*/
260:
261: /* main message loop */
262:
263: VOID messageLoop ()
264: {
265: /* local variables */
266: QMSG qmsgTheMessage ;
267:
268: /* until it's time to quit, fetch a message ... */
269: /* we go until there's the top window's done */
270: while (WinGetMsg (habAnchorBlock, & qmsgTheMessage, NULL, 0, 0))
271: /* ... send the message off to get handled */
272: WinDispatchMsg (habAnchorBlock, &qmsgTheMessage) ;
273: }
274:
275: /*-------------------------- cleanUp -------------------------------*/
276:
277: /* carefully mop the floor from our muddy little feet */
278:
279: VOID cleanUp (ULONG afInitFlags)
280: {
281: /* if we were able to build a child frame window and it's
282: * still alive ... */
283: #ifdef fred
284: if (afInitFlags & GOT_CHILD_FRAME_WINDOW)
285: /* ... destroy it */
286: WinDestroyWindow (hChildFrame) ;
287: #endif
288:
289: /* if we were able to build a top-level frame window ... */
290: if (afInitFlags & GOT_TOP_FRAME_WINDOW)
291: /* ... destroy it */
292: WinDestroyWindow (hwndTopFrame) ;
293:
294: /* if we were able to get a message queue ... */
295: if (afInitFlags & GOT_MESSAGE_QUEUE)
296: /* ... destroy it */
297: WinDestroyMsgQueue (hmqMessageQueue) ;
298:
299: /* if we were able to get an anchor block ... */
300: if (afInitFlags & GOT_ANCHOR_BLOCK)
301: /* ... destroy it */
302: WinTerminate (habAnchorBlock) ;
303: }
304:
305:
306: /*-------------------------- ChildFrameWndProc -----------------------*/
307:
308: MRESULT APIENTRY ChildFrameWndProc(hwnd, msg, mp1, mp2)
309: HWND hwnd;
310: USHORT msg;
311: MPARAM mp1;
312: MPARAM mp2;
313: {
314: switch (msg) {
315:
316: case WM_SYSCOMMAND:
317: /* MDI: close window explicitly to avoid posting WM_QUIT */
318: if (SHORT1FROMMP(mp1) == SC_CLOSE) {
319: WinDestroyWindow(hwnd);
320: return TRUE;
321: }
322: break;
323:
324:
325: /* send to DefWindowProc instead of original frame procedure */
326: return WinDefWindowProc(hwnd, msg, mp1, mp2);
327: break;
328: }
329: return (*pfnwpRegFrameWndProc)(hwnd, msg, mp1, mp2);
330: }
331:
332:
333: /*------------------------- ChildClientWndProc --------------------------*/
334:
335: MRESULT EXPENTRY ChildClientWndProc( HWND hwnd, USHORT usMessage,
336: MPARAM mp1, MPARAM mp2 )
337: {
338: /* local variables */
339: HPS hpsPS ;
340: RECTL rclUpdateRect ;
341: USHORT usChildID ;
342: USHORT usGeneration ;
343: CHAR szPathString [80] ;
344: CHAR szLittleMessage [80] ;
345: HWND hwndGrandParent ;
346:
347: /* case out on the message, dudes and dudesses */
348: switch (usMessage)
349: {
350: case WM_COMMAND:
351: switch (LOUSHORT (mp1))
352: {
353: case WINDOW_NEW:
354: /* try to create a child standard frame window */
355: createNewChildStdFrame(
356: & hwndChildFrame[0], & hwndChildClient[0], hwnd) ;
357:
358: /* subclass the child frame window so we can
359: * intercept system menu quit messages
360: */
361: pfnwpRegFrameWndProc = WinSubclassWindow (
362: hwndChildFrame[0],
363: ChildFrameWndProc);
364:
365:
366: break ;
367:
368: default:
369: break ;
370: }
371: return FALSE ;
372:
373: case WM_PAINT:
374: /* try to start painting */
375: if (hpsPS = WinBeginPaint (hwnd, NULL, & rclUpdateRect))
376: {
377: /* got a PS */
378: /* get the generation number */
379: usGeneration = WinQueryWindowUShort (hwnd, US_GENERATION) ;
380:
381: /* get the child number */
382: usChildID = WinQueryWindowUShort (hwnd, US_CHILD_ID) ;
383:
384: /* initialize the window's path string */
385: sprintf (szPathString, "%i", usChildID) ;
386:
387: /* build the path */
388: if (usGeneration)
389: {
390: hwndGrandParent = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
391: hwndGrandParent = WinQueryWindow (hwndGrandParent, QW_PARENT, FALSE) ;
392:
393: /* figure the window's path string */
394: getPathString (hwndGrandParent, szPathString) ;
395: }
396: /* compose a little message */
397: sprintf (szLittleMessage, "%s %s ",
398: "window", szPathString) ;
399:
400: /* fill the invalid rectangle with a color */
401: WinFillRect (hpsPS, & rclUpdateRect,
402: CLR_BLACK) ;
403:
404: /* print a little message */
405: fillWindowWithMessage (
406: hpsPS, hwnd, & rclUpdateRect,
407: szLittleMessage,
408: apaclrChildColorArrays[usChildID],
409: asChildColorArraySizes[usChildID]) ;
410:
411: /* close down painting operation */
412: WinEndPaint (hpsPS) ;
413:
414: /* message taken care of */
415: return MESSAGE_HANDLED ;
416: }
417: }
418: /* go to default for unhandled messages and
419: * handled messages that want continued processing
420: */
421: return (WinDefWindowProc (hwnd, usMessage, mp1, mp2));
422: }
423:
424:
425: /*---------------------- fillWindowWithMessage ---------------------*/
426:
427: /* fills a window with a message */
428:
429: VOID fillWindowWithMessage (HPS hpsPS, HWND hwnd,
430: PRECTL prclInvalidRect,
431: CHAR szSomeMessage [],
432: ULONG aclrColors [],
433: SHORT sNumColors)
434: {
435: /* local variables */
436: RECTL rclWindowRect, rclTextRect, rclDrawRect ;
437: SHORT sWindowWidth, sWindowHeight ;
438: SHORT sTextWidth, sTextHeight ;
439: SHORT sRow, sColumn ;
440: SHORT sNumColumns ;
441: SHORT sColorIndex ;
442: SHORT sStartRow, sEndRow, sStartColumn, sEndColumn ;
443:
444: /* figure size of window */
445: WinQueryWindowRect (hwnd, & rclWindowRect) ;
446:
447: /* figure rectangle text will fit in */
448: WinDrawText (hpsPS, -1, szSomeMessage,
449: &rclTextRect, SYSCLR_WINDOWTEXT,
450: SYSCLR_WINDOW, DT_QUERYEXTENT | DT_LEFT | DT_TOP) ;
451:
452: /* figure out window's width and height */
453: sWindowWidth = (SHORT) rclWindowRect.xRight ;
454: sWindowHeight = (SHORT) rclWindowRect.yTop ;
455:
456: /* figure out text's width and height */
457: sTextWidth = (SHORT) (rclTextRect.xRight - rclTextRect.xLeft) ;
458: sTextHeight = (SHORT) (rclTextRect.yTop - rclTextRect.yBottom) ;
459:
460: /* figure out number of columns */
461: sNumColumns = (sWindowWidth / sTextWidth) + 1 ;
462:
463: /* figure out which rows and columns contain the update area */
464: /* figure out row for top of invalid rect */
465: sStartRow = (sWindowHeight - (SHORT) prclInvalidRect->yTop)
466: / sTextHeight ;
467:
468: /* figure out row for bottom of invalid rect */
469: sEndRow = (sWindowHeight - (SHORT) prclInvalidRect->yBottom)
470: / sTextHeight ;
471:
472: /* figure out column for left of invalid rect */
473: sStartColumn = (SHORT) prclInvalidRect->xLeft / sTextWidth ;
474:
475: /* figure out column for right of invalid rect */
476: sEndColumn = (SHORT) prclInvalidRect->xRight / sTextWidth ;
477:
478: /* draw those rows and columns */
479:
480: /* move text rect to initial row and column */
481: rclTextRect.xLeft = sStartColumn * sTextWidth ;
482: rclTextRect.xRight = rclTextRect.xLeft + sTextWidth ;
483: rclTextRect.yTop = rclWindowRect.yTop -
484: (sStartRow * sTextHeight) ;
485: rclTextRect.yBottom = rclTextRect.yTop - sTextHeight ;
486:
487: /* initialize the vertical parts of the drawing rectangle */
488: rclDrawRect.yTop = rclTextRect.yTop ;
489: rclDrawRect.yBottom = rclTextRect.yBottom ;
490:
491: /* for each row to be drawn ... */
492: for (sRow = sStartRow ;
493: sRow <= sEndRow ;
494: sRow ++)
495: {
496: /* adjust drawing rectangle for first column in a row */
497: rclDrawRect.xLeft = rclTextRect.xLeft ;
498: rclDrawRect.xRight = rclTextRect.xRight ;
499:
500: /* initialize a coloring index */
501: sColorIndex = (sRow * sNumColumns + sStartColumn)
502: % sNumColors ;
503:
504: /* for each column in the row ... */
505: for (sColumn = sStartColumn ;
506: sColumn <= sEndColumn ;
507: sColumn ++)
508: {
509: /* draw the column's text */
510: WinDrawText (hpsPS, -1, szSomeMessage,
511: &rclDrawRect, aclrColors [sColorIndex],
512: SYSCLR_WINDOW, DT_LEFT | DT_TOP) ;
513:
514: /* adjust color for next column */
515: if (++sColorIndex == sNumColors)
516: sColorIndex = 0 ;
517:
518: /* adjust drawing rectangle for next column */
519: rclDrawRect.xLeft += sTextWidth ;
520: rclDrawRect.xRight += sTextWidth ;
521: }
522:
523: /* adjust drawing rectangle for next row */
524: rclDrawRect.yTop -= (LONG) sTextHeight ;
525: rclDrawRect.yBottom -= (LONG) sTextHeight ;
526: }
527: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.