|
|
1.1 ! root 1: /*--------------------------------------------------------*\ ! 2: SHAPES.C - displays rotating, variable size 3D shapes ! 3: \*--------------------------------------------------------*/ ! 4: ! 5: #include <stddef.h> ! 6: #include <stdlib.h> ! 7: #include <os2.h> ! 8: #include "shapes.h" ! 9: #include "sstruct.h" ! 10: ! 11: #define WM_END_CHILD (WM_USER + 0) ! 12: ! 13: VOID CreateParent (); ! 14: VOID CreateChild (); ! 15: ! 16: INT iNextValidWindow (INT); ! 17: INT iQueryChild (HWND); ! 18: INT iNextFreeChild (); ! 19: ! 20: MRESULT EXPENTRY ParentWndProc (HWND, USHORT, MPARAM, MPARAM); ! 21: MRESULT EXPENTRY ChildWndProc (HWND, USHORT, MPARAM, MPARAM); ! 22: ! 23: extern VOID ChangeScale (PSV); ! 24: extern VOID ChangeShapePosition (PSV); ! 25: extern VOID DrawAndFill (PSV); ! 26: ! 27: extern SHAPE rgshape []; /* table of shape definitions */ ! 28: extern INT shapeMax; /* max number of different shapes */ ! 29: ! 30: INT ishapeParent = 0; /* current shape in parent window */ ! 31: ! 32: /* ! 33: "rgpsv" is a table of pointers to shape variables. For each open ! 34: window there is one instance of these variables. (see SHAPEVARS structure) ! 35: */ ! 36: ! 37: PSV rgpsv [MAX_WINDOWS]; ! 38: ! 39: INT iMaxChild = 0; /* max child index */ ! 40: INT iChildCreate; /* index of child being created */ ! 41: ! 42: BOOL fCloseParent = FALSE; /* true when parent window is closed */ ! 43: ! 44: extern INT yPelAdjust = 1024; /* adjustment for varying pixel shape */ ! 45: ! 46: LONG cxScreen, cyScreen; /* size of full screen */ ! 47: ! 48: HAB hab; ! 49: HWND hwndMenu; ! 50: CHAR szClassNameParent[] = "Shapes"; ! 51: CHAR szClassNameChild[] = "Child"; ! 52: ! 53: ! 54: /* ! 55: * Main: ! 56: * - main loop which receives/sends messages for the parent and child ! 57: * windows ! 58: * - when no messages are waiting in the queue, the next shape is redrawn ! 59: */ ! 60: ! 61: main() ! 62: { ! 63: HMQ hmq; ! 64: QMSG qmsg; ! 65: BOOL fNotDone = TRUE; ! 66: INT iWindow = 0; ! 67: ! 68: hab = WinInitialize (NULL); ! 69: hmq = WinCreateMsgQueue (hab, 0); ! 70: ! 71: WinRegisterClass (hab, szClassNameParent, ParentWndProc, ! 72: CS_SIZEREDRAW, ! 73: 0 ); ! 74: ! 75: WinRegisterClass (hab, szClassNameChild, ChildWndProc, ! 76: CS_SIZEREDRAW, ! 77: 0 ); ! 78: ! 79: CreateParent (); ! 80: ! 81: /* receive/send messages until parent window is closed */ ! 82: ! 83: while (fNotDone) ! 84: { ! 85: if (WinPeekMsg (hab, &qmsg, NULL, 0, 0, PM_REMOVE) ) ! 86: ! 87: if (qmsg.msg == WM_QUIT && fCloseParent) ! 88: fNotDone = FALSE; ! 89: else ! 90: WinDispatchMsg (hab, &qmsg); ! 91: else ! 92: { ! 93: /* get next window and redraw its shape */ ! 94: ! 95: iWindow = iNextValidWindow (iWindow); ! 96: if (!rgpsv [iWindow]->fShaded) ! 97: ChangeShapePosition (rgpsv [iWindow]); ! 98: } ! 99: } ! 100: ! 101: /* destroy remaining open windows */ ! 102: ! 103: iWindow = 0; ! 104: do ! 105: { ! 106: iWindow = iNextValidWindow (iWindow); ! 107: GpiDestroyPS (rgpsv [iWindow]->hpsClient); ! 108: WinDestroyWindow (rgpsv [iWindow]->hwndFrame); ! 109: } ! 110: while (iWindow != 0); ! 111: ! 112: WinDestroyMsgQueue (hmq); ! 113: WinTerminate (hab); ! 114: ! 115: return 0; ! 116: } ! 117: ! 118: ! 119: /* ! 120: * CreateParent: ! 121: * - allocate storage for shape variables ! 122: * - create the parent window ! 123: */ ! 124: ! 125: VOID CreateParent() ! 126: { ! 127: PSV psv; ! 128: SHAPE *pshape; ! 129: ULONG CtlData; ! 130: ! 131: psv = (PSV) malloc (sizeof (SHAPEVARS)); ! 132: rgpsv [0] = psv; ! 133: pshape = &rgshape [ishapeParent]; ! 134: ! 135: psv->iShape = ishapeParent; ! 136: psv->rgptOld = (POINTL *) malloc ( MAX_POINTS * sizeof (POINTL) ); ! 137: psv->rgptNew = (POINTL *) malloc ( MAX_POINTS * sizeof (POINTL) ); ! 138: psv->fShaded = FALSE; ! 139: psv->fErased = TRUE; ! 140: psv->fClipping = (pshape->pobject->rgface != NULL); ! 141: psv->fVarySize = FALSE; ! 142: psv->fPerspective = TRUE; ! 143: psv->pt2LightAng.x = 0; ! 144: psv->pt2LightAng.y = 0; ! 145: psv->pt3Angle = pshape->pinit->pt3Angle; ! 146: psv->pt3AngVel = pshape->pinit->pt3AngVel; ! 147: psv->pt3SizeAng = pshape->pinit->pt3SizeAng; ! 148: ! 149: CtlData = FCF_TITLEBAR ! 150: | FCF_SIZEBORDER | FCF_MINMAX ! 151: | FCF_SYSMENU | FCF_MENU; ! 152: psv->hwndFrame = WinCreateStdWindow( ! 153: HWND_DESKTOP, ! 154: WS_VISIBLE | FS_ICON | FS_ACCELTABLE, ! 155: &CtlData, ! 156: szClassNameParent, ! 157: szClassNameParent, ! 158: 0L, ! 159: NULL, ! 160: ID_RESOURCE, ! 161: &psv->hwndClient ); ! 162: ! 163: hwndMenu = WinWindowFromID (psv->hwndFrame, FID_MENU); ! 164: } ! 165: ! 166: ! 167: /* ! 168: * CreateChild: ! 169: * - allocate storage for shape variables ! 170: * - initialize variables using the parents variables ! 171: * - create a child window ! 172: */ ! 173: ! 174: VOID CreateChild( ! 175: INT iNewChild ) ! 176: { ! 177: PSV psv; ! 178: SHAPE *pshape; ! 179: ULONG CtlData; ! 180: ! 181: psv = (PSV) malloc (sizeof (SHAPEVARS)); ! 182: rgpsv [iNewChild] = psv; ! 183: pshape = &rgshape [ishapeParent]; ! 184: ! 185: psv->iShape = ishapeParent; ! 186: psv->rgptOld = (POINTL *) malloc ( ! 187: pshape->pobject->cPoints * sizeof (POINTL) ); ! 188: psv->rgptNew = (POINTL *) malloc ( ! 189: pshape->pobject->cPoints * sizeof (POINTL) ); ! 190: psv->fShaded = rgpsv[0]->fShaded; ! 191: psv->fErased = TRUE; ! 192: psv->fClipping = rgpsv[0]->fClipping; ! 193: psv->fVarySize = rgpsv[0]->fVarySize; ! 194: psv->fPerspective = rgpsv[0]->fPerspective; ! 195: psv->pt2LightAng = rgpsv[0]->pt2LightAng; ! 196: psv->pt3Angle = rgpsv[0]->pt3Angle; ! 197: psv->pt3AngVel = rgpsv[0]->pt3AngVel; ! 198: psv->pt3SizeAng = rgpsv[0]->pt3SizeAng; ! 199: ! 200: iChildCreate = iNewChild; ! 201: CtlData = FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX | FCF_SYSMENU; ! 202: psv->hwndFrame = WinCreateStdWindow( ! 203: HWND_DESKTOP, ! 204: WS_VISIBLE, ! 205: &CtlData, ! 206: szClassNameChild, ! 207: pshape->szName, ! 208: 0L, ! 209: NULL, ! 210: 0, ! 211: &psv->hwndClient ); ! 212: } ! 213: ! 214: ! 215: /* ! 216: * iNextValidWindow: ! 217: * - get the window index which is greater than a given index ! 218: * - if no indexes are greater then return the index for ! 219: * the parent (first) window ! 220: */ ! 221: ! 222: INT iNextValidWindow ( ! 223: INT iWindow ) ! 224: { ! 225: INT i; ! 226: ! 227: for (i = iWindow + 1; i <= iMaxChild; i++) ! 228: if (rgpsv [i] != NULL) ! 229: return i; ! 230: return 0; ! 231: } ! 232: ! 233: ! 234: /* ! 235: * iQueryChild: ! 236: * - get the window index associated with a window handle ! 237: * - return 0 if window handle not found ! 238: */ ! 239: ! 240: INT iQueryChild ( ! 241: HWND hwnd ) ! 242: { ! 243: INT i; ! 244: ! 245: for (i = 1; i <= iMaxChild; i++) ! 246: if (rgpsv [i] != NULL && rgpsv [i]->hwndClient == hwnd) ! 247: return i; ! 248: return 0; ! 249: } ! 250: ! 251: ! 252: /* ! 253: * iNextFreeChild: ! 254: * - get a window index which is free (not currently used) ! 255: * - return 0 if no indexes are free ! 256: */ ! 257: ! 258: INT iNextFreeChild () ! 259: { ! 260: INT i; ! 261: ! 262: for (i = 1; i < MAX_WINDOWS; i++) ! 263: if (rgpsv [i] == NULL) ! 264: return i; ! 265: return 0; ! 266: } ! 267: ! 268: ! 269: /* ! 270: * ArrangeWindows: ! 271: * - change position and size of windows so that they fill the screen ! 272: */ ! 273: ! 274: void ArrangeWindows () ! 275: { ! 276: static SWP rgswp [MAX_WINDOWS]; ! 277: INT cWnd = 0; ! 278: INT iWindow = 0; ! 279: static INT rgcWndsWide [MAX_WINDOWS] = ! 280: { 1,2,2,2,3,3,3,3 }; ! 281: static INT rgcWndsHigh [3 * MAX_WINDOWS] = ! 282: { 1,0,0, 1,1,0, 2,1,0, 2,2,0, 2,1,2, 2,2,2, 2,3,2, 3,2,3 }; ! 283: INT i; ! 284: INT xWndPos, yWndPos; ! 285: INT iWide, iHigh; ! 286: ! 287: /* initialize each SWP entry - one entry per window */ ! 288: ! 289: do ! 290: { ! 291: iWindow = iNextValidWindow (iWindow); ! 292: rgswp [cWnd].fs = SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_ACTIVATE; ! 293: rgswp [cWnd].hwndInsertBehind = HWND_TOP; ! 294: rgswp [cWnd].hwnd = rgpsv [iWindow]->hwndFrame; ! 295: cWnd++; ! 296: } ! 297: while (iWindow != 0); ! 298: ! 299: /* calculate each window size and position */ ! 300: ! 301: iWide = cWnd - 1; ! 302: iHigh = (cWnd - 1) * 3; ! 303: xWndPos = 0; ! 304: yWndPos = rgcWndsHigh [iHigh] - 1; ! 305: ! 306: for (i = 0; i < cWnd; i++) ! 307: { ! 308: rgswp [i].cx = (INT) (cxScreen / rgcWndsWide [iWide]); ! 309: rgswp [i].cy = (INT) (cyScreen / rgcWndsHigh [iHigh + xWndPos]); ! 310: rgswp [i].x = rgswp [i].cx * xWndPos; ! 311: rgswp [i].y = rgswp [i].cy * yWndPos; ! 312: ! 313: if (yWndPos-- == 0) ! 314: { ! 315: xWndPos++; ! 316: yWndPos = rgcWndsHigh [iHigh + xWndPos] - 1; ! 317: } ! 318: } ! 319: ! 320: /* reposition all windows */ ! 321: ! 322: WinSetMultWindowPos (hab, rgswp, cWnd); ! 323: } ! 324: ! 325: ! 326: /* ! 327: * AboutDlgProc: ! 328: * - simple 'About' dialog box ! 329: */ ! 330: ! 331: MRESULT EXPENTRY AboutDlgProc( ! 332: HWND hwnd, ! 333: USHORT msg, ! 334: MPARAM mp1, ! 335: MPARAM mp2 ) ! 336: { ! 337: switch (msg) ! 338: { ! 339: case WM_COMMAND: ! 340: switch (SHORT1FROMMP (mp1) ) ! 341: { ! 342: case DID_OK: ! 343: case DID_CANCEL: ! 344: WinDismissDlg (hwnd, TRUE); ! 345: break; ! 346: ! 347: default: ! 348: break; ! 349: } ! 350: break; ! 351: ! 352: default: ! 353: return WinDefDlgProc (hwnd, msg, mp1, mp2); ! 354: } ! 355: return FALSE; ! 356: } ! 357: ! 358: ! 359: /* ! 360: * LightSourceDlgProc: ! 361: * - allows the user to change the angle of the light source ! 362: */ ! 363: ! 364: MRESULT EXPENTRY LightSourceDlgProc( ! 365: HWND hwnd, ! 366: USHORT msg, ! 367: MPARAM mp1, ! 368: MPARAM mp2 ) ! 369: { ! 370: PSV psv; ! 371: INT iNewPosition; ! 372: INT cAddToPos; ! 373: ! 374: switch (msg) ! 375: { ! 376: case WM_INITDLG: ! 377: psv = rgpsv [0]; ! 378: ! 379: /* Set angle ranges from 0 to 180 */ ! 380: ! 381: WinSendDlgItemMsg (hwnd, IDD_LIGHTANG_X, SBM_SETSCROLLBAR, ! 382: MPFROMP (psv->pt2LightAng.x + 90), ! 383: MPFROM2SHORT (0, 180) ); ! 384: WinSendDlgItemMsg (hwnd, IDD_LIGHTANG_Y, SBM_SETSCROLLBAR, ! 385: MPFROMP (psv->pt2LightAng.y + 90), ! 386: MPFROM2SHORT (0, 180) ); ! 387: break; ! 388: ! 389: case WM_HSCROLL: ! 390: switch (SHORT2FROMMP (mp2) ) ! 391: { ! 392: case SB_LINELEFT: ! 393: cAddToPos = -5; ! 394: break; ! 395: case SB_LINERIGHT: ! 396: cAddToPos = 5; ! 397: break; ! 398: case SB_PAGELEFT: ! 399: cAddToPos = -30; ! 400: break; ! 401: case SB_PAGERIGHT: ! 402: cAddToPos = 30; ! 403: break; ! 404: default: ! 405: cAddToPos = 0; ! 406: break; ! 407: } ! 408: if (SHORT2FROMMP (mp2) == SB_SLIDERPOSITION) ! 409: iNewPosition = SHORT1FROMMP (mp2); ! 410: else ! 411: iNewPosition = ! 412: (INT) WinSendDlgItemMsg (hwnd, SHORT1FROMMP (mp1), ! 413: SBM_QUERYPOS, 0L, 0L) ! 414: + cAddToPos; ! 415: ! 416: /* Update slider position */ ! 417: ! 418: WinSendDlgItemMsg (hwnd, SHORT1FROMMP (mp1), SBM_SETPOS, ! 419: MPFROMP (iNewPosition), NULL); ! 420: break; ! 421: ! 422: case WM_COMMAND: ! 423: switch (SHORT1FROMMP (mp1) ) ! 424: { ! 425: case DID_OK: ! 426: psv = rgpsv [0]; ! 427: ! 428: /* Accept new angles (range -90 to 90) */ ! 429: ! 430: psv->pt2LightAng.x = (INT) WinSendDlgItemMsg (hwnd, ! 431: IDD_LIGHTANG_X, SBM_QUERYPOS, 0L, 0L); ! 432: psv->pt2LightAng.x -= 90; ! 433: ! 434: psv->pt2LightAng.y = (INT) WinSendDlgItemMsg (hwnd, ! 435: IDD_LIGHTANG_Y, SBM_QUERYPOS, 0L, 0L); ! 436: psv->pt2LightAng.y -= 90; ! 437: ! 438: WinDismissDlg (hwnd, TRUE); ! 439: break; ! 440: ! 441: case DID_CANCEL: ! 442: WinDismissDlg (hwnd, FALSE); ! 443: break; ! 444: ! 445: default: ! 446: break; ! 447: } ! 448: break; ! 449: ! 450: default: ! 451: return WinDefDlgProc (hwnd, msg, mp1, mp2); ! 452: } ! 453: return FALSE; ! 454: } ! 455: ! 456: ! 457: /* ! 458: * RotationDlgProc: ! 459: * - allows the user to change the angle and angular velocity of ! 460: * a shape in the parent window ! 461: */ ! 462: ! 463: MRESULT EXPENTRY RotationDlgProc( ! 464: HWND hwnd, ! 465: USHORT msg, ! 466: MPARAM mp1, ! 467: MPARAM mp2 ) ! 468: { ! 469: PSV psv; ! 470: INT iNewPosition; ! 471: INT cAddToPos; ! 472: INT cLineSize, cPageSize; ! 473: ! 474: switch (msg) ! 475: { ! 476: case WM_INITDLG: ! 477: psv = rgpsv [0]; ! 478: ! 479: /* Set angle ranges from 0 to 359 */ ! 480: ! 481: WinSendDlgItemMsg (hwnd, IDD_ANGLE_X, SBM_SETSCROLLBAR, ! 482: MPFROMP (psv->pt3Angle.x), ! 483: MPFROM2SHORT (0, 359) ); ! 484: WinSendDlgItemMsg (hwnd, IDD_ANGLE_Y, SBM_SETSCROLLBAR, ! 485: MPFROMP (psv->pt3Angle.y), ! 486: MPFROM2SHORT (0, 359) ); ! 487: WinSendDlgItemMsg (hwnd, IDD_ANGLE_Z, SBM_SETSCROLLBAR, ! 488: MPFROMP (psv->pt3Angle.z), ! 489: MPFROM2SHORT (0, 359) ); ! 490: ! 491: /* Set angular velocity ranges from 0 to 30 */ ! 492: ! 493: WinSendDlgItemMsg (hwnd, IDD_ANGVEL_X, SBM_SETSCROLLBAR, ! 494: MPFROMP (psv->pt3AngVel.x), ! 495: MPFROM2SHORT (0, 30) ); ! 496: WinSendDlgItemMsg (hwnd, IDD_ANGVEL_Y, SBM_SETSCROLLBAR, ! 497: MPFROMP (psv->pt3AngVel.y), ! 498: MPFROM2SHORT (0, 30) ); ! 499: WinSendDlgItemMsg (hwnd, IDD_ANGVEL_Z, SBM_SETSCROLLBAR, ! 500: MPFROMP (psv->pt3AngVel.z), ! 501: MPFROM2SHORT (0, 30) ); ! 502: break; ! 503: ! 504: case WM_HSCROLL: ! 505: switch (SHORT1FROMMP (mp1) ) ! 506: { ! 507: case IDD_ANGLE_X: ! 508: case IDD_ANGLE_Y: ! 509: case IDD_ANGLE_Z: ! 510: cLineSize = 1; ! 511: cPageSize = 30; ! 512: break; ! 513: case IDD_ANGVEL_X: ! 514: case IDD_ANGVEL_Y: ! 515: case IDD_ANGVEL_Z: ! 516: cLineSize = 1; ! 517: cPageSize = 6; ! 518: break; ! 519: } ! 520: ! 521: switch (SHORT2FROMMP (mp2) ) ! 522: { ! 523: case SB_LINELEFT: ! 524: cAddToPos = -cLineSize; ! 525: break; ! 526: case SB_LINERIGHT: ! 527: cAddToPos = cLineSize; ! 528: break; ! 529: case SB_PAGELEFT: ! 530: cAddToPos = -cPageSize; ! 531: break; ! 532: case SB_PAGERIGHT: ! 533: cAddToPos = cPageSize; ! 534: break; ! 535: default: ! 536: cAddToPos = 0; ! 537: break; ! 538: } ! 539: if (SHORT2FROMMP (mp2) == SB_SLIDERPOSITION) ! 540: iNewPosition = SHORT1FROMMP (mp2); ! 541: else ! 542: iNewPosition = ! 543: (INT) WinSendDlgItemMsg (hwnd, SHORT1FROMMP (mp1), ! 544: SBM_QUERYPOS, 0L, 0L) ! 545: + cAddToPos; ! 546: ! 547: /* Update slider position */ ! 548: ! 549: WinSendDlgItemMsg (hwnd, SHORT1FROMMP (mp1), SBM_SETPOS, ! 550: MPFROMP (iNewPosition), NULL); ! 551: break; ! 552: ! 553: case WM_COMMAND: ! 554: switch (SHORT1FROMMP (mp1) ) ! 555: { ! 556: case DID_OK: ! 557: psv = rgpsv [0]; ! 558: ! 559: /* Accept new angles */ ! 560: ! 561: psv->pt3Angle.x = (INT) WinSendDlgItemMsg (hwnd, ! 562: IDD_ANGLE_X, SBM_QUERYPOS, 0L, 0L); ! 563: psv->pt3Angle.y = (INT) WinSendDlgItemMsg (hwnd, ! 564: IDD_ANGLE_Y, SBM_QUERYPOS, 0L, 0L); ! 565: psv->pt3Angle.z = (INT) WinSendDlgItemMsg (hwnd, ! 566: IDD_ANGLE_Z, SBM_QUERYPOS, 0L, 0L); ! 567: ! 568: /* Accept new angular velocities */ ! 569: ! 570: psv->pt3AngVel.x = (INT) WinSendDlgItemMsg (hwnd, ! 571: IDD_ANGVEL_X, SBM_QUERYPOS, 0L, 0L); ! 572: psv->pt3AngVel.y = (INT) WinSendDlgItemMsg (hwnd, ! 573: IDD_ANGVEL_Y, SBM_QUERYPOS, 0L, 0L); ! 574: psv->pt3AngVel.z = (INT) WinSendDlgItemMsg (hwnd, ! 575: IDD_ANGVEL_Z, SBM_QUERYPOS, 0L, 0L); ! 576: ! 577: WinDismissDlg (hwnd, TRUE); ! 578: break; ! 579: ! 580: case DID_CANCEL: ! 581: WinDismissDlg (hwnd, FALSE); ! 582: break; ! 583: ! 584: default: ! 585: break; ! 586: } ! 587: break; ! 588: ! 589: default: ! 590: return WinDefDlgProc (hwnd, msg, mp1, mp2); ! 591: } ! 592: return FALSE; ! 593: } ! 594: ! 595: ! 596: /* ! 597: * ListDlgProc: ! 598: * - allows the user to switch to a new shape in the parent window ! 599: */ ! 600: ! 601: MRESULT EXPENTRY ListDlgProc( ! 602: HWND hwnd, ! 603: USHORT msg, ! 604: MPARAM mp1, ! 605: MPARAM mp2 ) ! 606: { ! 607: PSV psv; ! 608: INT iShape; ! 609: INT iItem; ! 610: SHAPE *pshape; ! 611: ! 612: switch (msg) ! 613: { ! 614: case WM_INITDLG: ! 615: WinSendDlgItemMsg (hwnd, IDD_NEWSHAPE, LM_DELETEALL, NULL, NULL); ! 616: ! 617: /* Fill list box with shape names */ ! 618: ! 619: for (iShape = 0; iShape < shapeMax; iShape++) ! 620: { ! 621: iItem = (USHORT) WinSendDlgItemMsg (hwnd, IDD_NEWSHAPE, ! 622: LM_INSERTITEM, ! 623: MPFROM2SHORT (LIT_SORTASCENDING, 0), ! 624: MPFROMP (rgshape [iShape].szName)); ! 625: WinSendDlgItemMsg (hwnd, IDD_NEWSHAPE, LM_SETITEMHANDLE, ! 626: MPFROMP (iItem), ! 627: MPFROMP (iShape)); ! 628: } ! 629: break ; ! 630: ! 631: case WM_COMMAND: ! 632: switch (SHORT1FROMMP (mp1) ) ! 633: { ! 634: case DID_OK: ! 635: iShape = (USHORT) WinSendDlgItemMsg (hwnd, IDD_NEWSHAPE, ! 636: LM_QUERYSELECTION, 0L, 0L); ! 637: ! 638: if (iShape >= 0 && iShape <= shapeMax) ! 639: { ! 640: /* set parent window to display chosen shape */ ! 641: ! 642: ishapeParent = (USHORT) WinSendDlgItemMsg (hwnd, ! 643: IDD_NEWSHAPE, ! 644: LM_QUERYITEMHANDLE, ! 645: MPFROMP (iShape), NULL); ! 646: psv = rgpsv [0]; ! 647: pshape = &rgshape [ishapeParent]; ! 648: psv->iShape = ishapeParent; ! 649: psv->fShaded = FALSE; ! 650: psv->fClipping = (pshape->pobject->rgface != NULL); ! 651: psv->fVarySize = FALSE; ! 652: psv->fPerspective = TRUE; ! 653: psv->pt2LightAng.x = 0; ! 654: psv->pt2LightAng.y = 0; ! 655: psv->pt3Angle = pshape->pinit->pt3Angle; ! 656: psv->pt3AngVel = pshape->pinit->pt3AngVel; ! 657: psv->pt3SizeAng = pshape->pinit->pt3SizeAng; ! 658: ! 659: /* set scale of shape for size of parent window */ ! 660: ! 661: ChangeScale (psv); ! 662: WinDismissDlg (hwnd, TRUE); ! 663: } ! 664: else ! 665: WinDismissDlg (hwnd, FALSE); ! 666: break; ! 667: ! 668: case DID_CANCEL: ! 669: WinDismissDlg (hwnd, FALSE); ! 670: break; ! 671: ! 672: default: ! 673: break; ! 674: } ! 675: break; ! 676: ! 677: default: ! 678: return WinDefDlgProc (hwnd, msg, mp1, mp2); ! 679: } ! 680: return FALSE; ! 681: } ! 682: ! 683: ! 684: /* ! 685: * ParentWndProc: ! 686: * - process menu requests ! 687: * - start and terminate child windows ! 688: * - handle painting and size changes ! 689: */ ! 690: ! 691: MRESULT EXPENTRY ParentWndProc( ! 692: HWND hwnd, ! 693: USHORT msg, ! 694: MPARAM mp1, ! 695: MPARAM mp2 ) ! 696: { ! 697: HPS hps; ! 698: HDC hdc; ! 699: PSV psv = rgpsv [0]; ! 700: SIZEL sizel; ! 701: LONG xPelsPerMeter, yPelsPerMeter; ! 702: INT iChild; ! 703: static BOOL fChildDisabled = FALSE; ! 704: SHAPE *pshape; ! 705: BOOL enClipping, enVarySize, enLightSource, enShaded; ! 706: /* enable flags for menu items */ ! 707: ! 708: switch (msg) ! 709: { ! 710: case WM_CREATE: ! 711: hdc = WinOpenWindowDC (hwnd); ! 712: ! 713: DevQueryCaps (hdc, CAPS_WIDTH, 1L, &cxScreen); ! 714: DevQueryCaps (hdc, CAPS_HEIGHT, 1L, &cyScreen); ! 715: ! 716: DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &xPelsPerMeter); ! 717: DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION, 1L, &yPelsPerMeter); ! 718: yPelAdjust = (INT) ((yPelsPerMeter << 10) / xPelsPerMeter); ! 719: ! 720: sizel.cx = sizel.cy = 0; ! 721: psv->hpsClient = GpiCreatePS (hab, hdc, &sizel, ! 722: PU_PELS | GPIT_MICRO | GPIA_ASSOC ); ! 723: ! 724: GpiSetBackMix (psv->hpsClient, BM_OVERPAINT); ! 725: GpiSetMix (psv->hpsClient, FM_OVERPAINT); ! 726: GpiSetBackColor (psv->hpsClient, CLR_WHITE); ! 727: break; ! 728: ! 729: case WM_INITMENU: ! 730: switch (SHORT1FROMMP (mp1)) ! 731: { ! 732: case IDM_OPTIONS: ! 733: pshape = &rgshape [ishapeParent]; ! 734: ! 735: /* disable/enable menu items */ ! 736: ! 737: enShaded = pshape->pobject->rgface != NULL; ! 738: enClipping = enShaded ! 739: && (pshape->pobject->rgline != NULL) ! 740: && !psv->fShaded; ! 741: enLightSource = psv->fShaded; ! 742: enVarySize = !psv->fShaded; ! 743: ! 744: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 745: MPFROM2SHORT (IDM_CLIPPING, TRUE), ! 746: MPFROM2SHORT (MIA_DISABLED, enClipping ? ! 747: 0 : MIA_DISABLED) ); ! 748: ! 749: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 750: MPFROM2SHORT (IDM_VARYSIZE, TRUE), ! 751: MPFROM2SHORT (MIA_DISABLED, enVarySize ? ! 752: 0 : MIA_DISABLED) ); ! 753: ! 754: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 755: MPFROM2SHORT (IDM_LIGHTSOURCE, TRUE), ! 756: MPFROM2SHORT (MIA_DISABLED, enLightSource ? ! 757: 0 : MIA_DISABLED) ); ! 758: ! 759: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 760: MPFROM2SHORT (IDM_SHADED, TRUE), ! 761: MPFROM2SHORT (MIA_DISABLED, enShaded ? ! 762: 0 : MIA_DISABLED) ); ! 763: ! 764: /* display check marks */ ! 765: ! 766: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 767: MPFROM2SHORT (IDM_SHADED, TRUE), ! 768: MPFROM2SHORT (MIA_CHECKED, ! 769: psv->fShaded ? MIA_CHECKED : 0) ); ! 770: ! 771: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 772: MPFROM2SHORT (IDM_CLIPPING, TRUE), ! 773: MPFROM2SHORT (MIA_CHECKED, ! 774: psv->fClipping ? MIA_CHECKED : 0) ); ! 775: ! 776: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 777: MPFROM2SHORT (IDM_VARYSIZE, TRUE), ! 778: MPFROM2SHORT (MIA_CHECKED, ! 779: psv->fVarySize ? MIA_CHECKED : 0) ); ! 780: ! 781: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 782: MPFROM2SHORT (IDM_PERSPECTIVE, TRUE), ! 783: MPFROM2SHORT (MIA_CHECKED, ! 784: psv->fPerspective ? MIA_CHECKED : 0) ); ! 785: break; ! 786: ! 787: default: ! 788: break; ! 789: } ! 790: break; ! 791: ! 792: case WM_COMMAND: ! 793: switch (SHORT1FROMMP (mp1)) ! 794: { ! 795: case IDM_LIST: ! 796: /* display list dialog box */ ! 797: ! 798: WinDlgBox (HWND_DESKTOP, hwnd, ListDlgProc, ! 799: NULL, IDD_LIST, NULL); ! 800: break; ! 801: ! 802: case IDM_ROTATION: ! 803: /* display rotation dialog box */ ! 804: ! 805: WinDlgBox (HWND_DESKTOP, hwnd, RotationDlgProc, ! 806: NULL, IDD_ROTATION, NULL); ! 807: break; ! 808: ! 809: case IDM_LIGHTSOURCE: ! 810: /* display light source dialog box */ ! 811: ! 812: WinDlgBox (HWND_DESKTOP, hwnd, LightSourceDlgProc, ! 813: NULL, IDD_LIGHTSOURCE, NULL); ! 814: break; ! 815: ! 816: case IDM_SHADED: ! 817: /* toggle shaded */ ! 818: ! 819: psv->fShaded = !psv->fShaded; ! 820: break; ! 821: ! 822: case IDM_CLIPPING: ! 823: /* toggle clipping */ ! 824: ! 825: psv->fClipping = !psv->fClipping; ! 826: break; ! 827: ! 828: case IDM_VARYSIZE: ! 829: /* toggle vary size */ ! 830: ! 831: psv->fVarySize = !psv->fVarySize; ! 832: break; ! 833: ! 834: case IDM_PERSPECTIVE: ! 835: /* toggle perspective */ ! 836: ! 837: psv->fPerspective = !psv->fPerspective; ! 838: break; ! 839: ! 840: case IDM_ABOUT: ! 841: /* display about dialog box */ ! 842: ! 843: WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc, ! 844: NULL, IDD_ABOUT, NULL); ! 845: break; ! 846: ! 847: case IDM_CHILD: ! 848: /* create child window when space exists */ ! 849: ! 850: iChild = iNextFreeChild (); ! 851: if (iChild != 0) ! 852: { ! 853: if (iChild > iMaxChild) ! 854: iMaxChild = iChild; ! 855: CreateChild (iChild); ! 856: } ! 857: ! 858: if (iNextFreeChild () == 0) ! 859: { ! 860: fChildDisabled = TRUE; ! 861: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 862: MPFROM2SHORT (IDM_CHILD, TRUE), ! 863: MPFROM2SHORT (MIA_DISABLED, MIA_DISABLED) ); ! 864: } ! 865: break; ! 866: ! 867: case IDM_ARRANGE: ! 868: /* arrange the windows to fill the screen */ ! 869: ! 870: ArrangeWindows (); ! 871: break; ! 872: } ! 873: /* window is now invalid */ ! 874: ! 875: WinInvalidateRect (hwnd, NULL, FALSE); ! 876: break; ! 877: ! 878: case WM_END_CHILD: ! 879: /* destroy child window and associated variables */ ! 880: ! 881: iChild = SHORT1FROMMP (mp1); ! 882: psv = rgpsv [iChild]; ! 883: ! 884: if (iChild == iMaxChild) ! 885: iMaxChild--; ! 886: rgpsv [iChild] = NULL; ! 887: ! 888: GpiDestroyPS (psv->hpsClient); ! 889: WinDestroyWindow (psv->hwndFrame); ! 890: free (psv); ! 891: ! 892: if (fChildDisabled) ! 893: { ! 894: fChildDisabled = FALSE; ! 895: WinSendMsg(hwndMenu, MM_SETITEMATTR, ! 896: MPFROM2SHORT (IDM_CHILD, TRUE), ! 897: MPFROM2SHORT (MIA_DISABLED, 0) ); ! 898: } ! 899: break; ! 900: ! 901: case WM_SIZE: ! 902: /* change the centre and scale of shape for new window size */ ! 903: ! 904: psv->ptCentre.x = SHORT1FROMMP (mp2) / 2; ! 905: psv->ptCentre.y = SHORT2FROMMP (mp2) / 2; ! 906: ! 907: ChangeScale (psv); ! 908: break; ! 909: ! 910: case WM_PAINT: ! 911: hps = WinBeginPaint (psv->hwndClient, NULL, NULL); ! 912: GpiErase (hps); ! 913: if (psv->fShaded) ! 914: DrawAndFill (psv); ! 915: WinEndPaint (hps); ! 916: ! 917: psv->fErased = TRUE; ! 918: break; ! 919: ! 920: case WM_CLOSE: ! 921: /* set flag so that main loop is terminated */ ! 922: ! 923: fCloseParent = TRUE; ! 924: return WinDefWindowProc (hwnd, msg, mp1, mp2); ! 925: ! 926: default: ! 927: return WinDefWindowProc (hwnd, msg, mp1, mp2); ! 928: } ! 929: return FALSE; ! 930: } ! 931: ! 932: ! 933: /* ! 934: * ChildWndProc: ! 935: * - generic child procedure (used for all child windows) ! 936: * - send message to parent upon termination ! 937: * - handle painting and size changes ! 938: */ ! 939: ! 940: MRESULT EXPENTRY ChildWndProc( ! 941: HWND hwnd, ! 942: USHORT msg, ! 943: MPARAM mp1, ! 944: MPARAM mp2 ) ! 945: { ! 946: HPS hps; ! 947: HDC hdc; ! 948: PSV psv; ! 949: SIZEL sizel; ! 950: INT iChild; ! 951: ! 952: switch (msg) ! 953: { ! 954: case WM_CREATE: ! 955: psv = rgpsv [iChildCreate]; ! 956: ! 957: hdc = WinOpenWindowDC (hwnd); ! 958: ! 959: sizel.cx = sizel.cy = 0; ! 960: psv->hpsClient = GpiCreatePS (hab, hdc, &sizel, ! 961: PU_PELS | GPIT_MICRO | GPIA_ASSOC ); ! 962: ! 963: GpiSetBackMix (psv->hpsClient, BM_OVERPAINT); ! 964: GpiSetMix (psv->hpsClient, FM_OVERPAINT); ! 965: GpiSetBackColor (psv->hpsClient, CLR_WHITE); ! 966: break; ! 967: ! 968: case WM_SIZE: ! 969: /* change the centre and scale of shape for new window size */ ! 970: ! 971: iChild = iQueryChild (hwnd); ! 972: psv = rgpsv [iChild]; ! 973: ! 974: psv->ptCentre.x = SHORT1FROMMP (mp2) / 2; ! 975: psv->ptCentre.y = SHORT2FROMMP (mp2) / 2; ! 976: ! 977: ChangeScale (psv); ! 978: break; ! 979: ! 980: case WM_PAINT: ! 981: iChild = iQueryChild (hwnd); ! 982: psv = rgpsv [iChild]; ! 983: ! 984: hps = WinBeginPaint (psv->hwndClient, NULL, NULL); ! 985: GpiErase (hps); ! 986: if (psv->fShaded) ! 987: DrawAndFill (psv); ! 988: WinEndPaint (hps); ! 989: ! 990: psv->fErased = TRUE; ! 991: break; ! 992: ! 993: case WM_CLOSE: ! 994: iChild = iQueryChild (hwnd); ! 995: ! 996: /* send termination message to parent */ ! 997: ! 998: WinPostMsg (rgpsv [0]->hwndClient, WM_END_CHILD, ! 999: MPFROMSHORT (iChild), 0L); ! 1000: break; ! 1001: ! 1002: default: ! 1003: return WinDefWindowProc (hwnd, msg, mp1, mp2); ! 1004: } ! 1005: return FALSE; ! 1006: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.