Annotation of os232sdk/toolkt20/c/samples/edpline/edpline.c, revision 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.