Annotation of os232sdk/toolkt20/c/samples/edpline/edpline.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.