|
|
1.1 ! root 1: /* ! 2: edpline.c -- polyline editor, for practice in mouse handling ! 3: Created by Microsoft Corporation, 1989 ! 4: */ ! 5: #define INCL_DOSMEMMGR ! 6: #define INCL_WINWINDOWMGR ! 7: #define INCL_WINMESSAGEMGR ! 8: #define INCL_WINSWITCHLIST ! 9: #define INCL_WINDIALOGS ! 10: #define INCL_GPIBITMAPS ! 11: #define INCL_GPIPRIMITIVES ! 12: #define INCL_WINMENUS ! 13: #define INCL_WININPUT ! 14: #define INCL_WINFRAMEMGR ! 15: #include <os2.h> ! 16: ! 17: #include <mt\stdio.h> ! 18: #include <mt\stdlib.h> ! 19: ! 20: #include "edpline.h" ! 21: ! 22: ! 23: ! 24: #define abs(x) (((x) > 0) ? (x) : -(x)) ! 25: #define PRIM_POLYLINE 0x0001 ! 26: #define PRIM_POLYFILLET 0x0002 ! 27: #define PRIM_POLYSPLINE 0x0004 ! 28: #define PRIM_POINTARC 0x0008 ! 29: ! 30: ! 31: /************************************************************************ ! 32: * ! 33: * Function declarations ! 34: * ! 35: ************************************************************************/ ! 36: ! 37: /* Private functions */ ! 38: ! 39: VOID cdecl main(VOID); ! 40: BOOL InitGlobals(VOID); ! 41: BOOL InitApp(VOID); ! 42: VOID Close(HWND); ! 43: VOID Command(HWND, USHORT); ! 44: VOID Paint(HPS, BOOL); ! 45: VOID MouseMove(HWND, MPARAM); ! 46: VOID ButtonUp(HWND, USHORT); ! 47: VOID ButtonDown(HWND, USHORT, MPARAM); ! 48: USHORT IsPtInList(PPOINTL); ! 49: USHORT AddPtToList(PPOINTL); ! 50: BOOL IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL); ! 51: VOID DrawPrimitive(HPS, USHORT); ! 52: VOID DrawPolyLine(HPS); ! 53: VOID DrawPolyFillet(HPS); ! 54: VOID DrawPolySpline(HPS); ! 55: VOID DrawPointArc(HPS); ! 56: VOID DrawControlPoints(HPS, LONG, PPOINTL); ! 57: VOID MyMessageBox(HWND, PSZ); ! 58: VOID SwapLong(PLONG, PLONG); ! 59: ! 60: /* Exported functions */ ! 61: ! 62: ULONG CALLBACK WndProc(HWND, USHORT, MPARAM, MPARAM); ! 63: MRESULT CALLBACK AboutDlgProc(HWND, USHORT, MPARAM, MPARAM); ! 64: ! 65: ! 66: ! 67: /************************************************************************ ! 68: * ! 69: * Global Variables ! 70: * ! 71: ************************************************************************/ ! 72: ! 73: typedef struct ! 74: { ! 75: HAB hab; ! 76: HMQ hMsgQ; ! 77: HWND hwndFrame; ! 78: HWND hwnd; ! 79: ! 80: ULONG flPrim; ! 81: BOOL fDisplayControlPoints; ! 82: LONG cptl; ! 83: PPOINTL pptl; ! 84: ! 85: USHORT usPtGrabbed; ! 86: BOOL fDragging; ! 87: ! 88: ULONG ulHitPrecision; ! 89: ! 90: } GLOBALDATA; ! 91: GLOBALDATA global; ! 92: ! 93: ! 94: ! 95: ! 96: /************************************************************************ ! 97: * ! 98: * main ! 99: * ! 100: * WinInitialize resizes our ring 2 stack, among other things, so ! 101: * we won't GP fault trying to do graphics. WinCreateMsgQueue defines ! 102: * us as a REAL PM app. (as well as the WINDOWAPI statement in the .DEF ! 103: * file...) Call a sub to register our window class and create a window. ! 104: * Loop over messages. Exit cleanly. ! 105: * ! 106: ************************************************************************/ ! 107: ! 108: VOID cdecl ! 109: main() ! 110: { ! 111: QMSG qMsg; ! 112: int iRet = 0; ! 113: ! 114: ! 115: global.hab = WinInitialize(NULL); ! 116: global.hMsgQ = WinCreateMsgQueue(global.hab, 0); ! 117: ! 118: if (InitApp()) ! 119: while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 )) ! 120: WinDispatchMsg( global.hab, (PQMSG)&qMsg ); ! 121: else ! 122: iRet = -1; ! 123: ! 124: WinDestroyWindow( global.hwndFrame ); ! 125: WinDestroyMsgQueue( global.hMsgQ ); ! 126: WinTerminate( global.hab ); ! 127: DosExit(EXIT_PROCESS, iRet); ! 128: } ! 129: ! 130: ! 131: ! 132: ! 133: /**************************************************************************** ! 134: * ! 135: * InitGlobals ! 136: * ! 137: * Initialize global variables. ! 138: * ! 139: ****************************************************************************/ ! 140: ! 141: BOOL ! 142: InitGlobals() ! 143: { ! 144: global.flPrim = PRIM_POLYLINE; ! 145: global.fDisplayControlPoints = TRUE; ! 146: ! 147: global.cptl = 0L; ! 148: global.pptl = NULL; ! 149: if (DosAllocSeg(CPTLMAX * sizeof(POINTL), ! 150: ((PUSHORT)&global.pptl)+1, 0)) ! 151: return FALSE; ! 152: ! 153: global.usPtGrabbed = -1; ! 154: global.fDragging = FALSE; ! 155: global.ulHitPrecision = 0L; ! 156: ! 157: return TRUE; ! 158: } ! 159: ! 160: ! 161: ! 162: ! 163: /**************************************************************************** ! 164: * ! 165: * InitApp ! 166: * ! 167: * Register application window class and creates standard window. ! 168: * ! 169: ****************************************************************************/ ! 170: ! 171: #define INIT_MENU_ITEM(val, var) \ ! 172: TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var)) ! 173: ! 174: BOOL ! 175: InitApp() ! 176: { ! 177: char szTitle[24]; ! 178: ULONG ctldata; ! 179: PID pid; ! 180: TID tid; ! 181: HSWITCH hsw; ! 182: static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE, ! 183: SWL_JUMPABLE, "Edit Polyline", 0 }; ! 184: ! 185: if (!InitGlobals()) ! 186: return FALSE; ! 187: ! 188: ! 189: /* Register Application Window Class */ ! 190: ! 191: WinLoadString( global.hab, NULL, IDS_TITLE, sizeof(szTitle), (PCH)szTitle ); ! 192: if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc, ! 193: CS_SIZEREDRAW, 0 )) ! 194: return FALSE; ! 195: ! 196: ! 197: ! 198: /* Create a window instance of class "PolyLine Editor" */ ! 199: ! 200: ctldata = FCF_STANDARD & ! 201: ~(ULONG)(FCF_ICON | FCF_ACCELTABLE | FCF_TASKLIST); ! 202: ! 203: if (global.hwndFrame = WinCreateStdWindow( ! 204: HWND_DESKTOP, /* specify desktop as parent window */ ! 205: WS_VISIBLE, /* window styles */ ! 206: &ctldata, /* frame creation flags */ ! 207: (PCH)szTitle, /* window class name */ ! 208: (PCH)szTitle, /* name appearing in window caption */ ! 209: 0L, /* */ ! 210: (HMODULE)NULL, /* use current executable module id */ ! 211: IDR_EDPLINE, /* menu id */ ! 212: (HWND FAR *)&global.hwnd /* window handle */ ! 213: )) ! 214: { ! 215: INIT_MENU_ITEM(IDM_CTLPOINTS, global.fDisplayControlPoints); ! 216: ! 217: if (global.flPrim & PRIM_POLYLINE) ! 218: CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYLINE); ! 219: if (global.flPrim & PRIM_POLYFILLET) ! 220: CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET); ! 221: if (global.flPrim & PRIM_POLYSPLINE) ! 222: CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE); ! 223: if (global.flPrim & PRIM_POINTARC) ! 224: CHECK_MENU_ITEM(global.hwndFrame, IDM_POINTARC); ! 225: ! 226: ! 227: /* Add ourselves to the switch list. */ ! 228: ! 229: WinQueryWindowProcess(global.hwndFrame, &pid, &tid); ! 230: swctl.hwnd = global.hwndFrame; ! 231: swctl.idProcess = pid; ! 232: hsw = WinAddSwitchEntry(&swctl); ! 233: ! 234: return TRUE; ! 235: } ! 236: return FALSE; ! 237: } ! 238: ! 239: ! 240: ! 241: ! 242: /************************************************************************ ! 243: * ! 244: * WndProc ! 245: * ! 246: * Process messages for the window class. ! 247: * ! 248: ************************************************************************/ ! 249: ! 250: ULONG CALLBACK ! 251: WndProc( hwnd, usMsg, mp1, mp2 ) ! 252: HWND hwnd; ! 253: USHORT usMsg; ! 254: MPARAM mp1; ! 255: MPARAM mp2; ! 256: { ! 257: HPS hps; ! 258: ! 259: ! 260: switch (usMsg) ! 261: { ! 262: case WM_CLOSE: ! 263: Close(hwnd); ! 264: break; ! 265: ! 266: case WM_COMMAND: ! 267: Command(hwnd, LOUSHORT(mp1)); ! 268: break; ! 269: ! 270: case WM_PAINT: ! 271: hps = WinBeginPaint(global.hwnd, NULL, NULL); ! 272: if (global.ulHitPrecision == 0L) ! 273: { ! 274: HDC hdc; ! 275: LONG cx; ! 276: ! 277: if (hdc = WinQueryWindowDC(global.hwnd)) { ! 278: DevQueryCaps(hdc, CAPS_MARKER_WIDTH, 1L, &cx); ! 279: global.ulHitPrecision = (cx >> 17) + 1L; ! 280: } else { ! 281: global.ulHitPrecision = 6L; ! 282: } ! 283: } ! 284: Paint(hps, TRUE); ! 285: WinEndPaint(hps); ! 286: break; ! 287: ! 288: case WM_BUTTON1DOWN: ! 289: case WM_BUTTON2DOWN: ! 290: ButtonDown(hwnd, usMsg, mp1); ! 291: break; ! 292: ! 293: case WM_BUTTON1UP: ! 294: case WM_BUTTON2UP: ! 295: ButtonUp(hwnd, usMsg); ! 296: break; ! 297: ! 298: case WM_MOUSEMOVE: ! 299: MouseMove(hwnd, mp1); ! 300: return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2)); ! 301: break; ! 302: ! 303: default: ! 304: return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2)); ! 305: break; ! 306: } ! 307: ! 308: return FALSE; ! 309: } ! 310: ! 311: ! 312: ! 313: ! 314: /************************************************************************ ! 315: * ! 316: * MouseMove ! 317: * ! 318: ************************************************************************/ ! 319: ! 320: VOID ! 321: MouseMove(hwnd, mp1) ! 322: HWND hwnd; ! 323: MPARAM mp1; ! 324: { ! 325: POINTL ptl; ! 326: HPS hps; ! 327: ! 328: if (hwnd == global.hwnd) ! 329: if (global.fDragging) ! 330: { ! 331: ptl.x = (LONG) LOUSHORT(mp1); ! 332: ptl.y = (LONG) HIUSHORT(mp1); ! 333: ! 334: if (global.usPtGrabbed != -1) ! 335: { ! 336: hps = WinGetPS(hwnd); ! 337: Paint(hps, FALSE); ! 338: ! 339: *(global.pptl+global.usPtGrabbed) = ptl; ! 340: ! 341: Paint(hps, FALSE); ! 342: WinReleasePS(hps); ! 343: } ! 344: } ! 345: } ! 346: ! 347: ! 348: ! 349: ! 350: /************************************************************************ ! 351: * ! 352: * ButtonUp ! 353: * ! 354: ************************************************************************/ ! 355: ! 356: VOID ! 357: ButtonUp(hwnd, usMsg) ! 358: HWND hwnd; ! 359: USHORT usMsg; ! 360: { ! 361: int i; ! 362: HPS hps; ! 363: ! 364: ! 365: if (hwnd == global.hwnd) ! 366: if (global.fDragging) ! 367: { ! 368: global.fDragging = FALSE; ! 369: if (global.usPtGrabbed != -1) ! 370: { ! 371: if (usMsg == WM_BUTTON2UP) ! 372: { ! 373: hps = WinGetPS(hwnd); ! 374: Paint(hps, FALSE); ! 375: ! 376: if ((i = global.usPtGrabbed) < (int) global.cptl-1) ! 377: while (i < (int) global.cptl-1) ! 378: { ! 379: global.pptl[i] = global.pptl[i+1]; ! 380: ++i; ! 381: } ! 382: ! 383: --global.cptl; ! 384: global.usPtGrabbed = -1; ! 385: ! 386: Paint(hps, FALSE); ! 387: WinReleasePS(hps); ! 388: } ! 389: else /* WM_BUTTON1UP */ ! 390: global.usPtGrabbed = -1; ! 391: } ! 392: } ! 393: } ! 394: ! 395: ! 396: ! 397: ! 398: /************************************************************************ ! 399: * ! 400: * ButtonDown ! 401: * ! 402: ************************************************************************/ ! 403: ! 404: VOID ! 405: ButtonDown(hwnd, usMsg, mp1) ! 406: HWND hwnd; ! 407: USHORT usMsg; ! 408: MPARAM mp1; ! 409: { ! 410: POINTL ptl; ! 411: HPS hps; ! 412: USHORT usNewPtGrabbed; ! 413: ! 414: ! 415: if (hwnd == global.hwnd) ! 416: if (!global.fDragging) ! 417: { ! 418: global.fDragging = TRUE; ! 419: ! 420: ptl.x = (LONG) LOUSHORT(mp1); ! 421: ptl.y = (LONG) HIUSHORT(mp1); ! 422: ! 423: if ((usNewPtGrabbed = IsPtInList(&ptl)) != -1) ! 424: global.usPtGrabbed = usNewPtGrabbed; ! 425: ! 426: if (usMsg == WM_BUTTON1DOWN) ! 427: { ! 428: hps = WinGetPS(hwnd); ! 429: Paint(hps, FALSE); ! 430: ! 431: if (usNewPtGrabbed == -1) ! 432: global.usPtGrabbed = AddPtToList(&ptl); ! 433: else ! 434: global.usPtGrabbed = usNewPtGrabbed; ! 435: ! 436: Paint(hps, FALSE); ! 437: WinReleasePS(hps); ! 438: ! 439: if (global.usPtGrabbed == -1) ! 440: MyMessageBox(global.hwnd, "Cannot add any more points."); ! 441: } ! 442: } ! 443: } ! 444: ! 445: ! 446: ! 447: ! 448: /************************************************************************ ! 449: * ! 450: * IsPtInList ! 451: * ! 452: ************************************************************************/ ! 453: ! 454: USHORT ! 455: IsPtInList(pptl) ! 456: PPOINTL pptl; ! 457: { ! 458: int i; ! 459: ! 460: ! 461: /* try to find pptl in the points we already have */ ! 462: for (i = 0; i < (int) global.cptl; ++i) ! 463: if (((abs(pptl->x - global.pptl[i].x)) ! 464: <= (LONG) global.ulHitPrecision) ! 465: && ((abs(pptl->y - global.pptl[i].y)) ! 466: <= (LONG) global.ulHitPrecision)) ! 467: return i; ! 468: ! 469: /* couldn't find it */ ! 470: return -1; ! 471: } ! 472: ! 473: ! 474: ! 475: ! 476: /************************************************************************ ! 477: * ! 478: * AddPtToList ! 479: * ! 480: ************************************************************************/ ! 481: ! 482: USHORT ! 483: AddPtToList(pptl) ! 484: PPOINTL pptl; ! 485: { ! 486: int i, j; ! 487: ! 488: if (global.cptl < CPTLMAX) ! 489: { ! 490: /* check for new points lying on a line segment */ ! 491: for (i = 0; i < (int) (global.cptl - 1L); ++i) ! 492: if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl)) ! 493: { ! 494: for (j = (int) global.cptl; j > i+1; --j) ! 495: global.pptl[j] = global.pptl[j - 1]; ! 496: global.pptl[i+1] = *pptl; ! 497: ++global.cptl; ! 498: return i+1; ! 499: } ! 500: ! 501: /* append the point */ ! 502: ! 503: i = (int) global.cptl; ! 504: global.pptl[i] = *pptl; ! 505: ++global.cptl; ! 506: return i; ! 507: } ! 508: ! 509: return -1; ! 510: } ! 511: ! 512: ! 513: ! 514: ! 515: /************************************************************************ ! 516: * ! 517: * IsPtCloseToLine ! 518: * ! 519: ************************************************************************/ ! 520: ! 521: BOOL ! 522: IsPtCloseToLine(pptl1, pptl2, pptlTest) ! 523: PPOINTL pptl1; ! 524: PPOINTL pptl2; ! 525: PPOINTL pptlTest; ! 526: { ! 527: POINTL ptlLL, ptlUR; ! 528: LONG dx, dy, yIntercept, result; ! 529: ! 530: ! 531: /* find the bounding box of the line segment */ ! 532: ! 533: ptlLL = *pptl1; /* assume line goes lower left to upper right */ ! 534: ptlUR = *pptl2; ! 535: if (pptl1->x > pptl2->x) ! 536: SwapLong(&ptlLL.x, &ptlUR.x); ! 537: if (pptl1->y > pptl2->y) ! 538: SwapLong(&ptlLL.y, &ptlUR.y); ! 539: ! 540: ! 541: /* adjust the bounding box if it's too narrow */ ! 542: ! 543: dx = pptl2->x - pptl1->x; ! 544: if (abs(dx) <= (LONG) (global.ulHitPrecision >> 1)) ! 545: { ! 546: ptlLL.x -= (LONG) (global.ulHitPrecision >> 1); ! 547: ptlUR.x += (LONG) (global.ulHitPrecision >> 1); ! 548: } ! 549: dy = pptl2->y - pptl1->y; ! 550: if (abs(dy) <= (LONG) (global.ulHitPrecision >> 1)) ! 551: { ! 552: ptlLL.y -= (LONG) (global.ulHitPrecision >> 1); ! 553: ptlUR.y += (LONG) (global.ulHitPrecision >> 1); ! 554: } ! 555: ! 556: ! 557: /* see if the test point is in the bounding box of the line segment */ ! 558: ! 559: if ((pptlTest->x >= ptlLL.x) && ! 560: (pptlTest->x <= ptlUR.x) && ! 561: (pptlTest->y >= ptlLL.y) && ! 562: (pptlTest->y <= ptlUR.y)) ! 563: { ! 564: /* test for special cases */ ! 565: ! 566: if (dx == 0) ! 567: { ! 568: if (abs(pptlTest->x - pptl1->x) <= (LONG) global.ulHitPrecision) ! 569: return TRUE; ! 570: else ! 571: return FALSE; ! 572: } ! 573: ! 574: if (dy == 0) ! 575: { ! 576: if (abs(pptlTest->y - pptl1->y) <= (LONG) global.ulHitPrecision) ! 577: return TRUE; ! 578: else ! 579: return FALSE; ! 580: } ! 581: ! 582: ! 583: /* test for general case */ ! 584: ! 585: yIntercept = pptl1->y - (pptl1->x * dy) / dx; ! 586: ! 587: result = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept; ! 588: if (abs(result) <= (LONG) global.ulHitPrecision) ! 589: return TRUE; ! 590: } ! 591: ! 592: return FALSE; ! 593: } ! 594: ! 595: ! 596: ! 597: ! 598: /************************************************************************ ! 599: * ! 600: * SwapLong ! 601: * ! 602: ************************************************************************/ ! 603: ! 604: VOID ! 605: SwapLong(pl1, pl2) ! 606: PLONG pl1, pl2; ! 607: { ! 608: LONG lTmp; ! 609: ! 610: lTmp = *pl1; ! 611: *pl1 = *pl2; ! 612: *pl2 = lTmp; ! 613: } ! 614: ! 615: ! 616: ! 617: ! 618: /************************************************************************ ! 619: * ! 620: * Close ! 621: * ! 622: ************************************************************************/ ! 623: ! 624: VOID ! 625: Close(hwnd) ! 626: HWND hwnd; ! 627: { ! 628: WinPostMsg(hwnd, WM_QUIT, 0L, 0L); ! 629: } ! 630: ! 631: ! 632: ! 633: ! 634: /************************************************************************ ! 635: * ! 636: * Command ! 637: * ! 638: * Dispatches menu commands to the proper handlers. ! 639: * ! 640: ************************************************************************/ ! 641: ! 642: #define UPDATE_MENU_BOOL(var, val) \ ! 643: { \ ! 644: TOGGLE_BOOL((var)); \ ! 645: TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var)); \ ! 646: } ! 647: ! 648: #define UPDATE_MENU_LIST(var, val) \ ! 649: { \ ! 650: UNCHECK_MENU_ITEM(global.hwndFrame, (var)); \ ! 651: (var) = (val); \ ! 652: CHECK_MENU_ITEM(global.hwndFrame, (var)); \ ! 653: } ! 654: ! 655: VOID ! 656: Command(hwnd, id) ! 657: HWND hwnd; ! 658: USHORT id; ! 659: { ! 660: HPS hps; ! 661: BOOL fRedraw = FALSE; ! 662: int rc; ! 663: ! 664: switch (id) ! 665: { ! 666: case IDM_ABOUT: ! 667: rc = WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, NULL, IDD_ABOUT, NULL); ! 668: fRedraw = FALSE; ! 669: break; ! 670: ! 671: case IDM_NOPRIM: ! 672: global.flPrim = 0L; ! 673: TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYLINE, 0); ! 674: TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET, 0); ! 675: TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE, 0); ! 676: fRedraw = TRUE; ! 677: break; ! 678: ! 679: case IDM_POLYLINE: ! 680: global.flPrim ^= PRIM_POLYLINE; ! 681: TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYLINE)); ! 682: fRedraw = TRUE; ! 683: break; ! 684: ! 685: case IDM_POLYFILLET: ! 686: global.flPrim ^= PRIM_POLYFILLET; ! 687: TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYFILLET)); ! 688: fRedraw = TRUE; ! 689: break; ! 690: ! 691: case IDM_POLYSPLINE: ! 692: global.flPrim ^= PRIM_POLYSPLINE; ! 693: TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYSPLINE)); ! 694: fRedraw = TRUE; ! 695: break; ! 696: ! 697: case IDM_POINTARC: ! 698: global.flPrim ^= PRIM_POINTARC; ! 699: TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POINTARC)); ! 700: fRedraw = TRUE; ! 701: break; ! 702: ! 703: case IDM_CTLPOINTS: ! 704: UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS); ! 705: fRedraw = TRUE; ! 706: break; ! 707: ! 708: case IDM_CLEARALL: ! 709: global.cptl = 0L; ! 710: fRedraw = TRUE; ! 711: break; ! 712: } ! 713: ! 714: if (fRedraw) ! 715: { ! 716: hps = WinGetPS(hwnd); ! 717: Paint(hps, TRUE); ! 718: WinReleasePS(hps); ! 719: } ! 720: } ! 721: ! 722: ! 723: ! 724: ! 725: /************************************************************************ ! 726: * ! 727: * Paint ! 728: * ! 729: ************************************************************************/ ! 730: ! 731: VOID ! 732: Paint(hps, fClearScreen) ! 733: HPS hps; ! 734: BOOL fClearScreen; ! 735: { ! 736: LINEBUNDLE lb; ! 737: RECTL rcl; ! 738: ! 739: ! 740: ! 741: if (fClearScreen) ! 742: { ! 743: /* clear the screen */ ! 744: WinQueryWindowRect(global.hwnd, &rcl); ! 745: GpiBitBlt(hps, NULL, 2L, (PPOINTL) &rcl, ROP_ONE, NULL); ! 746: } ! 747: ! 748: ! 749: if (global.cptl > 0L) ! 750: { ! 751: if (global.fDisplayControlPoints) ! 752: { ! 753: if (fClearScreen) ! 754: /* draw all the control points */ ! 755: DrawControlPoints(hps, global.cptl, global.pptl); ! 756: else if (global.usPtGrabbed != -1) ! 757: /* draw just the control point that moved */ ! 758: DrawControlPoints(hps, 1L, global.pptl+global.usPtGrabbed); ! 759: } ! 760: ! 761: /* set mix mode to xor */ ! 762: lb.usMixMode = FM_XOR; ! 763: GpiSetAttrs(hps, PRIM_LINE, LBB_MIX_MODE, 0L, &lb); ! 764: ! 765: /* draw the current primitives */ ! 766: ! 767: if (global.flPrim & PRIM_POLYLINE) ! 768: { ! 769: lb.lColor = CLR_BROWN; ! 770: GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb); ! 771: DrawPrimitive(hps, IDM_POLYLINE); ! 772: } ! 773: ! 774: if (global.flPrim & PRIM_POLYFILLET) ! 775: { ! 776: lb.lColor = CLR_DARKCYAN; ! 777: GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb); ! 778: DrawPrimitive(hps, IDM_POLYFILLET); ! 779: } ! 780: ! 781: if (global.flPrim & PRIM_POLYSPLINE) ! 782: { ! 783: lb.lColor = CLR_DARKPINK; ! 784: GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb); ! 785: DrawPrimitive(hps, IDM_POLYSPLINE); ! 786: } ! 787: ! 788: if (global.flPrim & PRIM_POINTARC) ! 789: { ! 790: lb.lColor = CLR_BACKGROUND; ! 791: GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb); ! 792: DrawPrimitive(hps, IDM_POINTARC); ! 793: } ! 794: } ! 795: } ! 796: ! 797: ! 798: ! 799: ! 800: /************************************************************************ ! 801: * ! 802: * DrawPrimitive ! 803: * ! 804: ************************************************************************/ ! 805: ! 806: VOID ! 807: DrawPrimitive(hps, usPrim) ! 808: HPS hps; ! 809: USHORT usPrim; ! 810: { ! 811: switch ( usPrim ) ! 812: { ! 813: case IDM_POLYLINE: ! 814: DrawPolyLine(hps); ! 815: break; ! 816: ! 817: case IDM_POLYFILLET: ! 818: DrawPolyFillet(hps); ! 819: break; ! 820: ! 821: case IDM_POLYSPLINE: ! 822: DrawPolySpline(hps); ! 823: break; ! 824: ! 825: case IDM_POINTARC: ! 826: DrawPointArc(hps); ! 827: break; ! 828: } ! 829: } ! 830: ! 831: ! 832: ! 833: ! 834: /************************************************************************ ! 835: * ! 836: * DrawPolyLine ! 837: * ! 838: ************************************************************************/ ! 839: ! 840: VOID ! 841: DrawPolyLine(hps) ! 842: HPS hps; ! 843: { ! 844: GpiSetCurrentPosition( hps, global.pptl ); ! 845: GpiPolyLine( hps, global.cptl-1L, global.pptl+1 ); ! 846: } ! 847: ! 848: ! 849: ! 850: ! 851: /************************************************************************ ! 852: * ! 853: * DrawPolyFillet ! 854: * ! 855: ************************************************************************/ ! 856: ! 857: VOID ! 858: DrawPolyFillet(hps) ! 859: HPS hps; ! 860: { ! 861: if (global.cptl > 2) ! 862: { ! 863: GpiSetCurrentPosition( hps, global.pptl ); ! 864: GpiPolyFillet( hps, global.cptl-1L, global.pptl+1 ); ! 865: } ! 866: } ! 867: ! 868: ! 869: ! 870: ! 871: /************************************************************************ ! 872: * ! 873: * DrawPolySpline ! 874: * ! 875: ************************************************************************/ ! 876: ! 877: VOID ! 878: DrawPolySpline(hps) ! 879: HPS hps; ! 880: { ! 881: USHORT cptSlack; /* # points in pptl not usable by PolySpline */ ! 882: ! 883: /* GpiPolySpline expects the number of points to be a ! 884: multiple of 3. If we have a non-multiple of three, ! 885: (excluding the first point, which we've used to set ! 886: the current position), only pass the largest multiple ! 887: of three, saving the rest for the next go-round. */ ! 888: ! 889: cptSlack = (int)((global.cptl-1L) % 3) + 1; ! 890: GpiSetCurrentPosition( hps, global.pptl ); ! 891: GpiPolySpline( hps, global.cptl-cptSlack, ! 892: global.pptl+1 ); ! 893: } ! 894: ! 895: ! 896: ! 897: ! 898: /************************************************************************ ! 899: * ! 900: * DrawPointArc ! 901: * ! 902: ************************************************************************/ ! 903: ! 904: VOID ! 905: DrawPointArc(hps) ! 906: HPS hps; ! 907: { ! 908: if (global.cptl >= 3L) ! 909: { ! 910: GpiSetCurrentPosition( hps, global.pptl ); ! 911: GpiPointArc( hps, global.pptl+1 ); ! 912: } ! 913: } ! 914: ! 915: ! 916: ! 917: ! 918: /************************************************************************ ! 919: * ! 920: * DrawControlPoints ! 921: * ! 922: ************************************************************************/ ! 923: ! 924: VOID ! 925: DrawControlPoints(hps, cptl, pptl) ! 926: HPS hps; ! 927: LONG cptl; ! 928: PPOINTL pptl; ! 929: { ! 930: MARKERBUNDLE mb; ! 931: ! 932: mb.lColor = CLR_TRUE; ! 933: mb.usMixMode = FM_XOR; ! 934: GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR | MBB_MIX_MODE, 0L, &mb); ! 935: ! 936: GpiPolyMarker(hps, cptl, pptl); ! 937: } ! 938: ! 939: ! 940: ! 941: ! 942: /************************************************************************ ! 943: * ! 944: * MyMessageBox ! 945: * ! 946: * Displays a message box with the given string. To simplify matters, ! 947: * the box will always have the same title ("PolyLine Editor"), will always ! 948: * have a single button ("Ok"), will always have an exclamation point ! 949: * icon, and will always be application modal. ! 950: * ! 951: ************************************************************************/ ! 952: ! 953: VOID ! 954: MyMessageBox(hWnd, sz) ! 955: HWND hWnd; ! 956: PSZ sz; ! 957: { ! 958: static char *szTitle = "PolyLine Editor"; ! 959: ! 960: WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, NULL, ! 961: MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL); ! 962: } ! 963: ! 964: MRESULT CALLBACK AboutDlgProc(hDlg, msg, mp1, mp2) ! 965: /* ! 966: About... dialog procedure ! 967: */ ! 968: HWND hDlg; ! 969: USHORT msg; ! 970: MPARAM mp1; ! 971: MPARAM mp2; ! 972: { ! 973: switch(msg) { ! 974: case WM_COMMAND: ! 975: switch(COMMANDMSG(&msg)->cmd) { ! 976: case DID_OK: WinDismissDlg(hDlg, TRUE); break; ! 977: default: break; ! 978: } ! 979: default: return WinDefDlgProc(hDlg, msg, mp1, mp2); ! 980: } ! 981: return FALSE; ! 982: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.