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