Annotation of mstools/samples/sdktools/fontedit/fontchar.c, revision 1.1

1.1     ! root        1: #include "windows.h"
        !             2: #include <windowsx.h>
        !             3: #include "fontedit.h"
        !             4: #include "fcntl.h"
        !             5: #include <stdio.h>
        !             6: 
        !             7: /****************************************************************************/
        !             8: /*              Shared Variables                                            */
        !             9: /****************************************************************************/
        !            10: 
        !            11: POINT SnapPointToGrid(POINT Pt);
        !            12: LONG  APIENTRY FontEditWndProc(HWND, WORD, WPARAM, LONG);
        !            13: BOOL  APIENTRY AboutDlg(
        !            14:        HWND   hDlg,
        !            15:        WORD   message,
        !            16:        WPARAM wParam,
        !            17:        LPARAM lParam
        !            18:        );
        !            19: BOOL   NewFile;                         /* flag indicating that NEW menu
        !            20:                                            item was selected */
        !            21: extern DLGPROC lpHeaderProc;            /* Pointer to Dialog Box Procedure */
        !            22: extern DLGPROC lpReSizeProc;            /* Pointer to Dialog Box Procedure */
        !            23: extern DLGPROC lpWidthProc;             /* Pointer to Dialog Box Procedure */
        !            24: 
        !            25: extern FontHeaderType font;             /* Structure of Font File Header */
        !            26: extern CHAR matBox [wBoxLim] [kBoxLim]; /* array to hold Box */
        !            27: extern HCURSOR hCross;                  /* handle to "+" shaped cursor(displayed
        !            28:                                            when in ROW or COLUMN menus */
        !            29: extern BOOL fReadOnly;
        !            30: extern HANDLE hInst;                    /* Module Handle */
        !            31: extern HBRUSH hbrBackGround;
        !            32: extern HWND hFont;
        !            33: extern HWND hBox;
        !            34: extern RECT rectWin;                    /* Client Rectangle */
        !            35: extern BOOL fLoaded;                    /* Set if a file loaded */
        !            36: extern BOOL fChanged;                   /* Anything has changed */
        !            37: extern BOOL fEdited;                    /* This character changed */
        !            38: extern DWORD kBox;                       /* height of character */
        !            39: extern DWORD wBox;                       /* Width of character */
        !            40: extern DWORD kStuff;                     /* Width of Show Header */
        !            41: extern INT  swH;                        /* Position in Show Window 0-100 */
        !            42: extern BYTE iChar;                      /* Character being edited */
        !            43: extern BYTE jChar;                      /* Last Char. of edit block */
        !            44: extern CHAR szNewFile[];                /* Name of New File */
        !            45: extern CHAR szFontFile[];               /* Name of Font File */
        !            46: extern CHAR szFontFileFull[];               /* Name of Font File */
        !            47: extern CHAR szFileNameTemp[];
        !            48: extern CHAR *szFileNameSave;
        !            49: extern INT cSysHeight;
        !            50: 
        !            51: extern CHAR *vrgsz[];                    /* total number of strings */
        !            52: extern OFSTRUCT ofstrFile;
        !            53: extern CHAR szExt[];                    /* default extension */
        !            54: extern CHAR szAppName[];
        !            55: extern CHAR szSCC[];
        !            56: extern HCURSOR hOldCursor;              /* handle to old arrow shaped cursor */
        !            57: /****************************************************************************/
        !            58: /*                      Local Variables                                     */
        !            59: /****************************************************************************/
        !            60: 
        !            61: HBRUSH hbrWhite;
        !            62: HBRUSH hbrBlack;
        !            63: HBRUSH hbrGray;
        !            64: HBRUSH hbrDkGray;
        !            65: HBRUSH hNullBrush;
        !            66: HPEN hWhitePen;
        !            67: DWORD colors[3] = {WHITENESS, BLACKNESS, PATCOPY};
        !            68: 
        !            69: 
        !            70: CHAR matBackup [wBoxLim] [kBoxLim];     /* Backup for UNDO */
        !            71: DWORD wBoxBackup;
        !            72: 
        !            73: LONG scale = 7;                        /* height/width of squares in box */
        !            74: WORD cursor = 0;               /* Add/Del cursor */
        !            75: 
        !            76: BOOL fAll = TRUE;              /* Redraw all if TRUE */
        !            77: POINT ptBox = {10, 5};         /* where edit box is */
        !            78: 
        !            79: RECT   rectRubber;             /* Rubber banding rectangle */
        !            80: HDC    hDst;                   /* Rubber banding dc */
        !            81: 
        !            82: POINT ptA;                     /* Start of draw/rectangle */
        !            83: POINT ptB;                     /* End of rectangle */
        !            84: POINT ptC;                     /* Current square */
        !            85: CHAR colorA;                   /* Color at/under point A */
        !            86: DWORD newWidth;                        /* Width set in WIDER option */
        !            87: BOOL FillingRect = FALSE;
        !            88: BOOL fRubberBanding = FALSE;   /* flag indicating if rubberbanding in
        !            89:                                    progress for row/column add/delete */
        !            90: BOOL fStartRubberBand = FALSE;  /* flag indicating that rubberbanding
        !            91:                                    can start */
        !            92: BOOL fCaptured = FALSE;                /* set if mouse is caputred */
        !            93: BOOL fJustZapped = FALSE;      /* Set on row/col add/delete */
        !            94: RECT FontRect;                 /* rectangle bounding font pattern */
        !            95: 
        !            96: /****************************************************************************/
        !            97: /*                      Local Functions                                     */
        !            98: /****************************************************************************/
        !            99: 
        !           100: VOID ClearFill(DWORD col, DWORD row, WORD mode);
        !           101: VOID FontEditCommand(HWND hBox, WORD id);
        !           102: VOID BoxRestore(VOID);
        !           103: VOID CharRectDimensions(LPRECT Rect);
        !           104: VOID BoxPaint(VOID);
        !           105: VOID DrawBox(HDC, DWORD, DWORD, DWORD, DWORD, INT, DWORD);
        !           106: VOID PASCAL DrawRubberBand(HDC hDst, LPRECT lpRect, DWORD rop);
        !           107: VOID FontEditPaint(HWND hBox, HDC hDC);
        !           108: BOOL CheckSave(VOID);
        !           109: VOID DupCol(DWORD col, DWORD row);
        !           110: VOID DupRow(DWORD col, DWORD row);
        !           111: VOID ZapCol(DWORD col, DWORD row);
        !           112: VOID ZapRow(DWORD col, DWORD row);
        !           113: VOID AddDel(DWORD col, DWORD row, WORD mode);
        !           114: VOID MouseInBox(HWND hBox, WORD message, POINT ptMouse);
        !           115: VOID BoxBackup(VOID);
        !           116: VOID ReadRect(VOID);
        !           117: 
        !           118: /*****************************************************************************/
        !           119: VOID
        !           120: BoxPaint(
        !           121:        VOID
        !           122:        )      /* Our call to FontEditPaint */
        !           123: {
        !           124:        HDC hDC;
        !           125: 
        !           126:        hDC = GetDC(hBox);
        !           127:        FontEditPaint(hBox,  hDC);
        !           128:        ReleaseDC(hBox, hDC);
        !           129:        if (fRubberBanding)
        !           130:                DrawRubberBand(hDst, &rectRubber, R2_XORPEN);
        !           131: }
        !           132: 
        !           133: 
        !           134: /******************************************************************************
        !           135:  * FontEditPaint(hBox, hDC)
        !           136:  *
        !           137:  * purpose: calculates coordinates for text in main window and repaints edit
        !           138:  *          box,small character boxes and text
        !           139:  *
        !           140:  * params:  HWND hBox : handle to main window
        !           141:  *          HDC hDC   I handle to display context
        !           142:  * returns: none
        !           143:  *
        !           144:  * side effects:  alters matBox (global 2-d array with ready pixel info. on
        !           145:  *                currently displayed box)
        !           146:  *****************************************************************************/
        !           147: VOID
        !           148: FontEditPaint(
        !           149:        HWND hBox,
        !           150:        HDC hDC
        !           151:        )
        !           152: {
        !           153:        CHAR szTemp[20];
        !           154:        DWORD len, yText, xText;
        !           155: 
        !           156:        if (!fLoaded)               /* Must load font first */
        !           157:                return;
        !           158: 
        !           159:        /* Here the application paints its window. */
        !           160:        if (fAll) {               /* Draw box setting */
        !           161:                GetClientRect(hBox, (LPRECT)&rectWin);
        !           162:                scale = (rectWin.bottom-rectWin.top-kStuff-20) / (kBox+1);
        !           163:                scale = min(scale, (min(320, rectWin.right - rectWin.left) - 
        !           164:                                90) / ((int)wBox + 1));
        !           165:                scale = max(scale, 4);
        !           166:                xText = ptBox.x + scale * wBox + 16;
        !           167: 
        !           168:                SelectObject(hDC, hbrDkGray);
        !           169:                Rectangle(hDC,
        !           170:                    ptBox.x - 2,
        !           171:                    ptBox.y - 2,
        !           172:                    ptBox.x + 3 + wBox * scale,
        !           173:                    ptBox.y + 5 + kBox * scale);
        !           174:                SelectObject(hDC, hbrGray);
        !           175: 
        !           176:                Rectangle(hDC,          /* Surround for font displays */
        !           177:                    xText,
        !           178:                    ptBox.y - 2,
        !           179:                    xText + wBox + 8,
        !           180:                    ptBox.y + 3 + kBox * 2 + font.ExtLeading);
        !           181: 
        !           182:                /* Now put up the text */
        !           183:                yText = 14 + 2 * kBox + font.ExtLeading;
        !           184:                len = (DWORD) sprintf(szTemp, vszCHAR, iChar);
        !           185:                TextOut(hDC, xText, yText, (LPSTR)szTemp, len);
        !           186:                len = (DWORD) sprintf(szTemp, vszWIDTH, wBox);
        !           187:                TextOut(hDC, xText, yText + cSysHeight, (LPSTR)szTemp, len);
        !           188:                len = (DWORD) sprintf(szTemp, vszHEIGHT, kBox);
        !           189:                TextOut(hDC, xText, yText + cSysHeight + cSysHeight, 
        !           190:                        (LPSTR)szTemp, len);
        !           191:        }
        !           192: 
        !           193:        /* Draw Character Box */
        !           194:        DrawBox(hDC, ptBox.x, ptBox.y, wBox, kBox, scale, 1);
        !           195: 
        !           196:        /* Draw small character */
        !           197:        xText = ptBox.x + scale * wBox + 16;
        !           198:        DrawBox(hDC,
        !           199:            xText + 4,
        !           200:            ptBox.y,
        !           201:            wBox,
        !           202:            kBox,
        !           203:            1, 0);
        !           204: 
        !           205:        /* Draw another small character to show leading */
        !           206:        DrawBox(hDC,
        !           207:            xText + 4,
        !           208:            ptBox.y + kBox + font.ExtLeading,
        !           209:            wBox,
        !           210:            kBox,
        !           211:            1, 0);
        !           212:        fAll = TRUE;
        !           213: }
        !           214: 
        !           215: 
        !           216: /******************************************************************************
        !           217:  * DrawBox(hDC, xChar, yChar, wChar, kChar, scale, htSep)
        !           218:  *
        !           219:  * purpose: draws the edit box for the character being edited and colors the
        !           220:  *          grid squares according to the pixels set for the character.
        !           221:  *
        !           222:  * params:  HDC hDC         : handle to display context
        !           223:  *          DWORD xChar      : x-location of char box.
        !           224:  *          DWORD yChar      : y-location of char box
        !           225:  *          DWORD wChar      : width of char box
        !           226:  *          DWORD kChar      : height of char
        !           227:  *          INT   wScale     : Scale of the squares.
        !           228:  *          DWORD htSep      : height of square separators
        !           229:  *
        !           230:  * returns: none
        !           231:  *
        !           232:  * side effects:  alters matBox (global 2-d array with ready pixel info. on
        !           233:  *                currently displayed box)
        !           234:  *****************************************************************************/
        !           235: VOID
        !           236: DrawBox(
        !           237:        HDC hDC,
        !           238:        DWORD xChar,                             /* x-location of char. */
        !           239:        DWORD yChar,                             /* y-location of char. */
        !           240:        DWORD wChar,                             /* width of char. */
        !           241:        DWORD kChar,                             /* height of char */
        !           242:        INT   wScale,                            /* scale of the squares. */
        !           243:        DWORD htSep                              /* hgt of square separators */
        !           244:        )
        !           245: /* draw a character of separate squares of height 'scale' with sep. 'htSep' */
        !           246: {
        !           247:        DWORD i, j, sep;
        !           248: 
        !           249:        if (fAll) {               /* redraw them all */
        !           250:            for (j = 0; j < kChar; j++) {
        !           251:                sep = (j >= font.Ascent) ? htSep : 0;
        !           252:                for (i = 0; i < wChar; i++) {
        !           253:                    if (wScale == 1)
        !           254:                        SetPixel(hDC, xChar + i, yChar + j,
        !           255:                                matBox[i][j] == TRUE ? BLACK : WHITE);
        !           256:                    else
        !           257:                        PatBlt(hDC,
        !           258:                                xChar + wScale * i,
        !           259:                                yChar + wScale * j + sep,
        !           260:                                wScale - htSep,
        !           261:                                wScale - htSep,
        !           262:                                colors[matBox[i][j] == TRUE ? 1 : 0]);
        !           263:                }
        !           264:            }
        !           265:        }
        !           266:        else {                  /* redraw one just flipped */
        !           267:            if (wScale == 1)
        !           268:                SetPixel(hDC,
        !           269:                        xChar + ptC.x,
        !           270:                        yChar + ptC.y,
        !           271:                        matBox[ptC.x][ptC.y] == TRUE ? BLACK : WHITE);
        !           272:            else {
        !           273:                sep = (((DWORD) ptC.y >= font.Ascent) ? htSep : 0L);
        !           274:                SelectObject(hDC, hbrGray);
        !           275:                PatBlt(hDC,
        !           276:                        xChar + wScale * ptC.x,
        !           277:                        yChar + wScale * ptC.y + sep,
        !           278:                        wScale - htSep,
        !           279:                        wScale - htSep,
        !           280:                        colors[matBox[ptC.x][ptC.y]]);
        !           281:            }
        !           282:        }
        !           283: 
        !           284: }
        !           285: 
        !           286: 
        !           287: /******************************************************************************
        !           288:  * FontEditCommand(hBox, id)
        !           289:  *
        !           290:  * purpose: interprets menu id and calls appropriate function to do the task
        !           291:  *
        !           292:  * params:  HWND hBox : handle to main window
        !           293:  *          WORD id   : menu command id
        !           294:  * returns: none
        !           295:  *
        !           296:  * side effects: plenty
        !           297:  *
        !           298:  *****************************************************************************/
        !           299: VOID
        !           300: FontEditCommand(
        !           301:        HWND hBox,
        !           302:        WORD id
        !           303:        )
        !           304: {
        !           305:        CHAR * szError;                 /* String for error messages */
        !           306:        LONG w; 
        !           307:        DWORD y, i, j;
        !           308:        BOOL fRepaint = FALSE;
        !           309:        HMENU hMenu;
        !           310:        DLGPROC lpprocAboutDlg;
        !           311:        MSG message;
        !           312: 
        !           313:        szError = "";               /* No Errors yet */
        !           314: 
        !           315:        switch (id) {
        !           316:            case FONT_EXIT:
        !           317:                if (!CheckSave())    /* See if any files need saving */
        !           318:                        break;
        !           319:                /* Window's being destroyed. */
        !           320:                if (fLoaded)         /* 4/8/87 Linsh added */
        !           321:                        DeleteGlobalBitmap(); /* Get rid of memory DC */
        !           322:                PostQuitMessage(0);  /* Cause application to be terminated */
        !           323:                break;
        !           324: 
        !           325:            case FONT_ABOUT:
        !           326:                lpprocAboutDlg = (DLGPROC)AboutDlg;
        !           327:                DialogBox (hInst, vszABOUT, hBox, lpprocAboutDlg);
        !           328:                FreeProcInstance (lpprocAboutDlg);
        !           329:                break;
        !           330: 
        !           331:            case FONT_LOAD:             /*  Check File Name  */
        !           332:            case FONT_NEW :
        !           333:                if (!CheckSave())       /*  See if current font needs saving */
        !           334:                        return;
        !           335:        /* to prevent scrambling of Show window chars, Bring back Show
        !           336:         ** window to parent window's client area before invoking the dialog */
        !           337: 
        !           338:                if (CommDlgOpen(hBox,&ofstrFile,szNewFile,szExt,szFontFile,id)
        !           339:                                == FALSE) {
        !           340: 
        !           341:                        InvalidateRect(hFont, (LPRECT)NULL, FALSE);
        !           342:                        UpdateWindow(hFont);
        !           343:                        return;
        !           344:                }
        !           345:                /* else drop thru */
        !           346: 
        !           347:            case FONT_START:    /*  Here if file name passed as argument */
        !           348:                InvalidateRect(hFont, (LPRECT)NULL, FALSE);
        !           349:                UpdateWindow(hFont);
        !           350: 
        !           351:                szError = FontLoad (szNewFile, &ofstrFile);
        !           352: 
        !           353:        /* Hack : needed to remove umwanted WM_MOUSEMOVE messages from the 
        !           354:          * queue.
        !           355:          * Apparently, Windows needs to reposition the mouse after a dialog
        !           356:          * is ended with a mouse double-click (releases mouse capture?) for
        !           357:          * which a couple of WM_MOUSEMOVEs may get sent to parent app.
        !           358:          * These mess with the edit box below the dialog if they happen to 
        !           359:          * overlap.
        !           360:          */
        !           361:                PeekMessage((LPMSG) &message, hBox, WM_MOUSEMOVE, WM_MOUSEMOVE,
        !           362:                    PM_REMOVE);
        !           363: 
        !           364:                if (fLoaded)    /* If loaded then do a few things */ {
        !           365:                    jChar = iChar = 65;                 /* Show an A */
        !           366:                    if ((BYTE)iChar > (BYTE)font.LastChar)
        !           367:                        jChar = iChar = font.FirstChar; /* .. if we can */
        !           368:                    swH = 15;                   /* Good bet to make A visible */
        !           369:                    fEdited = fChanged = FALSE;
        !           370:                    ResizeShow();               /* Set Box to proper size */
        !           371:                    ScrollFont();               /* Set thumb */
        !           372:                    CharToBox(iChar);
        !           373:                }
        !           374:                FontRename(szError);
        !           375:                SetFocus(hBox);
        !           376:                return;
        !           377: 
        !           378:            case FONT_SAVE:
        !           379:                if (!NewFile) {
        !           380:                    if (fLoaded && fChanged) {
        !           381:                        lstrcpy((LPSTR)szNewFile, (LPSTR)szFontFileFull);
        !           382:                        BoxToChar(iChar);           /* Just in case */
        !           383:                        szError = FontSave (szNewFile, &ofstrFile);
        !           384:                        FontRename(szError);        /* Rename or Print Error */
        !           385:                        return;
        !           386:                    }
        !           387:                    else
        !           388:                        return;
        !           389:                }
        !           390:        /* else file has been opened by selecting NEW... on menu.
        !           391:          * Fall thro' and bring up SaveAs dialog minus default
        !           392:          * filename in edit window */
        !           393: 
        !           394:            case FONT_SAVEAS:
        !           395:                BoxToChar(iChar);               /* Just in case */
        !           396: 
        !           397:                if (CommDlgSaveAs (hInst, hBox, &ofstrFile, szNewFile, szExt,
        !           398:                                szFontFile) == TRUE) {
        !           399: 
        !           400:                    szError = FontSave (szNewFile, &ofstrFile);
        !           401:                    FontRename (szError);          /* Rename or Print Error */
        !           402:                }
        !           403: 
        !           404:                /* to prevent scrambling of Show window chars,
        !           405:            repaint show window after dialog is brought down */
        !           406:                InvalidateRect (hFont, (LPRECT)NULL, TRUE);
        !           407:                UpdateWindow (hFont);
        !           408:                return;
        !           409: 
        !           410:            case FONT_HEADER:
        !           411:                /* to prevent scrambling of Show window chars,
        !           412:                 * repaint show window after dialog is invoked */
        !           413:                DialogBox(hInst, (LPSTR)vszDHeader, hBox, lpHeaderProc);
        !           414:                InvalidateRect(hFont, (LPRECT)NULL, TRUE);
        !           415:                UpdateWindow(hFont);
        !           416:                return;
        !           417: 
        !           418:            case FONT_RESIZE:
        !           419:                /* to prevent scrambling of Show window chars,
        !           420:                   repaint show window after dialog is brought down */
        !           421:                if (DialogBox(hInst, (LPSTR)vszDResize, hBox, lpReSizeProc)) {
        !           422:                    /* BoxToChar(iChar);*/ /* save current before resizing */
        !           423:                    ResizeShow();       /* New Font Display Size */
        !           424:                    CharToBox(iChar);               /* New Box display */
        !           425:                }
        !           426:                InvalidateRect(hFont, (LPRECT)NULL, TRUE);
        !           427:                UpdateWindow(hFont);
        !           428:                return;
        !           429: 
        !           430:            case FONT_COPY:                     /* Copy to Clipboard */
        !           431:                BoxToChar(iChar);               /* Just in case */
        !           432:                ToClipboard(iChar, wBox, kBox);
        !           433:                break;
        !           434: 
        !           435:            case FONT_PASTE:            /* Paste in Character form Clipboard */
        !           436:                BoxBackup();            /* In case we change our minds */
        !           437:                ptA.x = ptA.y = 0;
        !           438:                wBox = ClipboardToBox(ptA, wBox, kBox, TRUE);
        !           439:                fRepaint = TRUE;
        !           440:                break;
        !           441: 
        !           442:            case WIDER_LEFT:
        !           443:            case WIDER_RIGHT:
        !           444:            case WIDER_BOTH:
        !           445:            case NARROWER_LEFT:
        !           446:            case NARROWER_RIGHT:
        !           447:            case NARROWER_BOTH:
        !           448:            case WIDTH:
        !           449:                w = newWidth = wBox;
        !           450:                if (font.Family & 1)            /* Variable width or else */ {
        !           451:                    switch (id) {
        !           452:                        case WIDER_BOTH:
        !           453:                            w++;
        !           454:                        case WIDER_LEFT:
        !           455:                        case WIDER_RIGHT:
        !           456:                            w++;
        !           457:                            break;
        !           458:                        case NARROWER_BOTH:
        !           459:                            w--;
        !           460:                        case NARROWER_LEFT:
        !           461:                        case NARROWER_RIGHT:
        !           462:                            w--;
        !           463:                            break;
        !           464:                        case WIDTH:
        !           465:                            if (DialogBox(hInst,
        !           466:                                        (LPSTR)vszDWidth, hBox, lpWidthProc))
        !           467:                                w = newWidth;
        !           468:                            break;
        !           469:                    }
        !           470: 
        !           471:                    if (w < 0 || w >= wBoxLim) {
        !           472:                        MessageBox(hBox,
        !           473:                                (LPSTR)vszEdLimits0To64,
        !           474:                                (LPSTR)szAppName,
        !           475:                                MB_OK | MB_ICONASTERISK);
        !           476:                        break;                  /* Out of range! quit */
        !           477:                    }
        !           478:                    if (w > (LONG) font.MaxWidth) {
        !           479:                        if (IDOK == MessageBox(hBox,
        !           480:                                            (LPSTR)vszMaxWidthIncrease,
        !           481:                                            (LPSTR)szAppName,
        !           482:                                            MB_OKCANCEL | MB_ICONQUESTION))
        !           483:                            font.MaxWidth = (WORD)w;
        !           484:                        else
        !           485:                            break;
        !           486:                    }
        !           487:                    BoxBackup();                /* In case we change our minds */
        !           488:                    wBox = (WORD)w;             /* Reset width */
        !           489:                    fRepaint = TRUE;            /* Signal redraw */
        !           490:                    switch (id) {
        !           491:                    case WIDER_LEFT:
        !           492:                    case WIDER_BOTH:            /* Shift character one right */
        !           493:                        DupCol(0, kBoxLim - 1);
        !           494:                        for (y = 0; y < kBoxLim; y++)
        !           495:                            matBox[wBox -1][y] = FALSE; /* Clear right column */
        !           496:                        for (y = 0; y < kBoxLim; y++)
        !           497:                            matBox[0][y] = FALSE;       /* Clear left column */
        !           498:                        break;
        !           499:                    case NARROWER_LEFT:
        !           500:                    case NARROWER_BOTH: /* Shift character one left */
        !           501:                        if (wBox) {     /* .. unless width is already 0 */
        !           502:                            for (j = 0; j <= kBox - 1; j++)
        !           503:                                for (i = 0; i <= wBox - 1; i++)
        !           504:                                    matBox[i][j] = matBox[i + 1][j];
        !           505:                            break;
        !           506:                        }
        !           507:                    }
        !           508:                }
        !           509:                else {
        !           510:                    MessageBox(hBox,
        !           511:                            (LPSTR)vszCannotChangeWidth,
        !           512:                            (LPSTR)szAppName,
        !           513:                            MB_OK | MB_ICONASTERISK);
        !           514:                }
        !           515:                break;
        !           516: 
        !           517:            case ROW_ADD:
        !           518:            case ROW_DEL:
        !           519:            case COL_ADD:
        !           520:            case COL_DEL:
        !           521:                /* set cursor to "+" shaped cursor */
        !           522:                SetCapture (hBox); /* so that cursor doesn't get restored
        !           523:                                      before we are done */
        !           524:                hOldCursor = SetCursor (LoadCursor (NULL, IDC_CROSS));
        !           525:                fCaptured = TRUE;
        !           526:                cursor = id;
        !           527:                break;
        !           528: 
        !           529:            case BOX_CLEAR:
        !           530:            case BOX_FILL:
        !           531:            case BOX_INV:
        !           532:            case BOX_HATCH:
        !           533:            case BOX_LEFTRIGHT:
        !           534:            case BOX_TOPBOTTOM:
        !           535:            case BOX_COPY:
        !           536:            case BOX_PASTE:
        !           537:                /* Get one o' da funky cursors */
        !           538:                SetCapture(hBox);
        !           539:                hOldCursor = SetCursor(LoadCursor(hInst, MAKEINTRESOURCE(id)));
        !           540:                fStartRubberBand = TRUE;
        !           541:                CharRectDimensions((LPRECT)&FontRect);
        !           542:                cursor = id;
        !           543:                break;
        !           544: 
        !           545:            case BOX_REFRESH:           /* Go get old version of character */
        !           546:                BoxBackup();            /* In case we change our minds */
        !           547:                CharToBox(iChar);
        !           548:                hMenu = GetMenu(hBox);
        !           549:                EnableMenuItem(hMenu, BOX_UNDO, MF_ENABLED);    /* Can Unrefresh! */
        !           550:                break;
        !           551:            case BOX_UNDO:
        !           552:                BoxRestore();
        !           553:                hMenu = GetMenu(hBox);
        !           554:                EnableMenuItem(hMenu, BOX_REFRESH, MF_ENABLED);
        !           555:                fRepaint = TRUE;
        !           556:                break;
        !           557:        }
        !           558:        if (fRepaint) {
        !           559:                fEdited = fChanged = TRUE;
        !           560:                InvalidateRect(hBox, (LPRECT)NULL, TRUE);
        !           561:        }
        !           562: }
        !           563: 
        !           564: 
        !           565: VOID
        !           566: CharRectDimensions(
        !           567:        LPRECT Rect
        !           568:        )
        !           569: /* returns the dimensions of the edit box */
        !           570: {
        !           571:        Rect->top    =  ptBox.y;
        !           572:        Rect->bottom =  ptBox.y + (kBox) * (scale);
        !           573:        Rect->left   =  ptBox.x;
        !           574:        Rect->right  =  ptBox.x + (wBox) * (scale);
        !           575: }
        !           576: 
        !           577: 
        !           578: /******************************************************************************
        !           579:  * BOOL  APIENTRY WidthProc(hDial, message, wParam, lParam)
        !           580:  *
        !           581:  * purpose: dialog function for Width menu function
        !           582:  *
        !           583:  * params:  same as for all dialog fns.
        !           584:  *
        !           585:  * side effects: changes Box width variable
        !           586:  *
        !           587:  *****************************************************************************/
        !           588: BOOL  APIENTRY 
        !           589: WidthProc(
        !           590:        HWND   hDial,
        !           591:        WORD   message,
        !           592:        WPARAM wParam,
        !           593:        LPARAM lParam
        !           594:        )
        !           595: {
        !           596:        INT i;
        !           597:        BOOL fOk;
        !           598: 
        !           599:        UNREFERENCED_PARAMETER(lParam);
        !           600: 
        !           601:        switch (message) {
        !           602:        default:
        !           603:                return FALSE;
        !           604:        case WM_INITDIALOG:
        !           605:                SetDlgItemInt(hDial, BOX_WIDTH, newWidth, FALSE);
        !           606:                break;
        !           607: 
        !           608:        case WM_COMMAND:
        !           609:                switch (LOWORD(wParam)) {
        !           610:                case IDOK:
        !           611:                        fChanged = TRUE;
        !           612:                        i = GetDlgItemInt(hDial, BOX_WIDTH, (LPBOOL)&fOk, FALSE);
        !           613:                        if (fOk && i < wBoxLim)
        !           614:                                newWidth = i;
        !           615:                        else
        !           616:                                ErrorBox(hDial, vszWidthOutOfBounds);
        !           617: 
        !           618:                case IDCANCEL:
        !           619:                        EndDialog(hDial, LOWORD(wParam) != IDCANCEL);
        !           620:                        break;
        !           621: 
        !           622:                default:
        !           623:                        break;
        !           624:                }
        !           625:        }
        !           626:        return TRUE;
        !           627: }
        !           628: 
        !           629: 
        !           630: /******************************************************************************
        !           631:  * BOOL CheckSave()
        !           632:  *
        !           633:  * purpose: checks if font is dirty and prompts user to save font. If yes,
        !           634:  *          edit box is saved and file save function is called.
        !           635:  *
        !           636:  * params:  none
        !           637:  *
        !           638:  * returns: TRUE : font has been changed
        !           639:  *          FALSE: font untouched
        !           640:  *
        !           641:  * side effects: file dirty flag is reset.
        !           642:  *
        !           643:  *****************************************************************************/
        !           644: BOOL 
        !           645: CheckSave(
        !           646:        VOID
        !           647:        )
        !           648: {
        !           649:        CHAR * szError;                 /* String for error messages */
        !           650:        CHAR szMessage[MAX_STR_LEN+MAX_FNAME_LEN];
        !           651: 
        !           652:        /* Check if anything changed */
        !           653:        if (fLoaded && fChanged && (!fReadOnly)) {
        !           654:                lstrcpy((LPSTR)szNewFile, (LPSTR)szFontFileFull);
        !           655:                DlgMergeStrings(szSCC, szNewFile, szMessage);
        !           656:                switch (MessageBox(hFont,
        !           657:                    (LPSTR)szMessage,
        !           658:                    (LPSTR)szAppName,
        !           659:                    MB_YESNOCANCEL | MB_ICONQUESTION)) {
        !           660:                case IDYES:
        !           661:                        BoxToChar(iChar);            /* Just in case */
        !           662:                        szError = FontSave (szNewFile, &ofstrFile);
        !           663:                        FontRename(szError);            /* Rename or Print Error */
        !           664:                case IDNO:
        !           665:                        return TRUE;
        !           666:                case IDCANCEL:
        !           667:                        return FALSE;
        !           668:                }
        !           669:        }
        !           670:        return TRUE;
        !           671: }
        !           672: 
        !           673: 
        !           674: /******************************************************************************
        !           675:  * MouseInBox(hBox, message, ptMouse)
        !           676:  *
        !           677:  * purpose: do edit operation depending on currently active menu command
        !           678:  *
        !           679:  * params: HWND hBox       : handle to main window
        !           680:  *         WORD message    : Message retrieved by main window's window fn.
        !           681:  *         POINT ptMouse   : current mouse coordinates
        !           682:  * returns: none
        !           683:  *
        !           684:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           685:  *               currently displayed box). Also assigns values to ptA and ptB
        !           686:  *****************************************************************************/
        !           687: VOID
        !           688: MouseInBox(
        !           689:        HWND hBox,
        !           690:        WORD message,
        !           691:        POINT ptMouse
        !           692:        )
        !           693: {
        !           694:        POINT pt;
        !           695:        BOOL fRepaint = FALSE;
        !           696: 
        !           697:        pt = SnapPointToGrid(ptMouse);
        !           698: 
        !           699:        if (pt.x >= 0L && pt.y >= 0L &&
        !           700:            ((DWORD)pt.x) < wBox && ((DWORD)pt.y) < kBox) {
        !           701:                fEdited = fChanged = TRUE;
        !           702:                ptC.x = pt.x;
        !           703:                ptC.y = pt.y;                   /* Current square */
        !           704:                if (message == WM_LBUTTONDOWN)
        !           705:                        BoxBackup();            /* Set up for UNDO */
        !           706:                switch (cursor) {
        !           707:                case BOX_COPY:
        !           708:                case BOX_PASTE:
        !           709:                case BOX_CLEAR:
        !           710:                case BOX_FILL:
        !           711:                case BOX_INV:
        !           712:                case BOX_HATCH:
        !           713:                case BOX_LEFTRIGHT:
        !           714:                case BOX_TOPBOTTOM:
        !           715:                        ptA.x = pt.x;
        !           716:                        ptA.y = pt.y;           /* save anchor point */
        !           717:                                                /* save color under marker */
        !           718:                        colorA = matBox[pt.x][pt.y];
        !           719:                        fAll = FALSE;
        !           720: 
        !           721:                        fRepaint = TRUE;
        !           722:                        break;
        !           723:                default:
        !           724:                        AddDel(pt.x, pt.y, cursor);
        !           725:                        fRepaint = TRUE;
        !           726:                        cursor = FALSE;
        !           727:                        break;
        !           728:                case FALSE:
        !           729:                        switch (message) {
        !           730:                        case WM_LBUTTONDOWN:    /*invert */
        !           731:                                colorA = (matBox[pt.x][pt.y] ^= TRUE);
        !           732:                                break;
        !           733: 
        !           734:                        case WM_LBUTTONUP:
        !           735:                                break;
        !           736: 
        !           737:                        case WM_MOUSEMOVE:
        !           738:                                matBox[pt.x][pt.y] = colorA;    /* paint */
        !           739:                                break;
        !           740:                        }
        !           741:                        fRepaint = TRUE;
        !           742:                        fAll = FALSE;               /* Limited redraw */
        !           743:                        break;
        !           744:                }
        !           745:                if (fRepaint) {
        !           746:                        BoxPaint();
        !           747:                        return;
        !           748:                }
        !           749:        }
        !           750:        cursor = FALSE;
        !           751: }
        !           752: 
        !           753: 
        !           754: /******************************************************************************
        !           755:  * ReadRect(ptMouse)
        !           756:  *
        !           757:  * purpose:      defines the rectangular region in edit box to be filled by
        !           758:  *               fill menu command  by fixing top left (ptA) and bottom right
        !           759:  *               (ptB) coordinates of rect.
        !           760:  *
        !           761:  * params:
        !           762:  *
        !           763:  * assumes:    that rectRubber is normalized (eg, left < right, botton > top)
        !           764:  *
        !           765:  * returns:    none
        !           766:  *
        !           767:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           768:  *               currently displayed box). Also assigns values to ptA and ptB
        !           769:  *****************************************************************************/
        !           770: VOID
        !           771: ReadRect(
        !           772:        )
        !           773: {
        !           774: 
        !           775:        ptA.x = (rectRubber.left-(ptBox.x+1))   / scale;
        !           776:        ptA.y = (rectRubber.top-(ptBox.y+1))    / scale;
        !           777:        ptB.x = (rectRubber.right-(ptBox.x-2))  / scale - 1;
        !           778:        ptB.y = (rectRubber.bottom-(ptBox.y-2)) / scale - 1;
        !           779: 
        !           780:        if (((DWORD)ptB.x) > wBox - 1)
        !           781:            ptB.x = wBox - 1;
        !           782:        if (((DWORD)ptB.y) > kBox - 1)
        !           783:            ptB.y = kBox - 1;
        !           784: 
        !           785:        if (ptB.x >= 0 && ptB.y >= 0) {
        !           786:            ClearFill((DWORD)ptB.x, (DWORD)ptB.y, cursor);        
        !           787:            BoxPaint();
        !           788:        }
        !           789:        cursor = FALSE;
        !           790: }
        !           791: 
        !           792: 
        !           793: /******************************************************************************
        !           794:  * ClearFill(col, row, mode)
        !           795:  *
        !           796:  * purpose:  fill the specified rectangular region in edit box with fill type
        !           797:  *           indicated by mode.Top left corner of rect is global(ptA)
        !           798:  *
        !           799:  * params:   DWORD row : row (of bottom right corner of rect(ptB.x))
        !           800:  *           DWORD col : column (of bottom right corner of rect(ptB.y))
        !           801:  *           WORD mode: action to be performed
        !           802:  *
        !           803:  * returns:  none
        !           804:  *
        !           805:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           806:  *               currently displayed box)
        !           807:  *****************************************************************************/
        !           808: VOID
        !           809: ClearFill(
        !           810:        DWORD col, 
        !           811:        DWORD row, 
        !           812:        WORD mode
        !           813:        )
        !           814: {
        !           815:        DWORD i, x, y;
        !           816:        CHAR z;
        !           817: 
        !           818:        if (col < (DWORD)ptA.x) /* if points are reversed */ {
        !           819:                i = col;
        !           820:                col = ptA.x;
        !           821:                ptA.x = i;
        !           822:        }          /* flip them */
        !           823:        if (row < (DWORD) ptA.y) {
        !           824:                i = row;
        !           825:                row = ptA.y;
        !           826:                ptA.y = i;
        !           827:        }          /* flip them */
        !           828: 
        !           829:        if (mode == BOX_LEFTRIGHT) {
        !           830:                for (x = ptA.x; x <= (DWORD)((ptA.x + col) / 2); x++)
        !           831:                        for (y = ptA.y; y <= row; y++) {
        !           832:                                z = matBox[x][y];
        !           833:                                matBox[x][y] = matBox[ptA.x + col - x][y];
        !           834:                                matBox[ptA.x + col - x][y] = z;
        !           835:                        }
        !           836:                return;
        !           837:        }
        !           838: 
        !           839:        if (mode == BOX_TOPBOTTOM) {
        !           840:                for (y = ptA.y; y <= ((DWORD)(ptA.y + row) / 2); y++)
        !           841:                        for (x = ptA.x; x <= col; x++) {
        !           842:                                z = matBox[x][y];
        !           843:                                matBox[x][y] = matBox[x][ptA.y + row - y];
        !           844:                                matBox[x][ptA.y + row - y] = z;
        !           845:                        }
        !           846:                return;
        !           847:        }
        !           848: 
        !           849:        if (mode == BOX_COPY)
        !           850:                BoxToClipboard(ptA, col - ptA.x + 1, row - ptA.y + 1);
        !           851: 
        !           852:        if (mode == BOX_PASTE)
        !           853:                ClipboardToBox(ptA, col - ptA.x + 1, row - ptA.y + 1, FALSE);
        !           854: 
        !           855:        for (x = ptA.x; x <= col; x++)
        !           856:                for (y = ptA.y; y <= row; y++) {
        !           857:                        switch (mode) {
        !           858:                        case BOX_CLEAR:
        !           859:                        case BOX_FILL:
        !           860:                                matBox[x][y] = (CHAR)(mode == BOX_FILL);
        !           861:                                break;
        !           862:                        case BOX_INV:
        !           863:                                matBox[x][y] ^= (CHAR)TRUE;
        !           864:                                break;
        !           865:                        case BOX_HATCH:
        !           866:                                matBox[x][y] = (CHAR)((x+y)%2 ? TRUE : FALSE);
        !           867:                                break;
        !           868:                        }
        !           869:                }
        !           870: }
        !           871: 
        !           872: 
        !           873: /******************************************************************************
        !           874:  * AddDel(col, row, mode)
        !           875:  *
        !           876:  * purpose:  Add/Delete row/col as per mode
        !           877:  *
        !           878:  * params:   DWORD row : row
        !           879:  *           DWORD col : column
        !           880:  *           WORD mode: action to be performed
        !           881:  *
        !           882:  * returns:  none
        !           883:  *
        !           884:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           885:  *               currently displayed box)
        !           886:  *****************************************************************************/
        !           887: VOID
        !           888: AddDel(
        !           889:        DWORD col, 
        !           890:        DWORD row, 
        !           891:        WORD mode
        !           892:        )
        !           893: {
        !           894:        switch (mode) {
        !           895:        case ROW_ADD:
        !           896:                DupRow(wBox, row);
        !           897:                break;
        !           898: 
        !           899:        case ROW_DEL:
        !           900:                ZapRow(wBox, row);
        !           901:                break;
        !           902: 
        !           903:        case COL_ADD:
        !           904:                DupCol(col, kBox);
        !           905:                break;
        !           906: 
        !           907:        case COL_DEL:
        !           908:                ZapCol(col, kBox);
        !           909:                break;
        !           910:        }
        !           911:        /* restore arrow cursor */
        !           912:        SetCursor (hOldCursor);
        !           913:        ReleaseCapture();
        !           914:        fCaptured = FALSE;
        !           915:        fJustZapped = TRUE;
        !           916: }
        !           917: 
        !           918: 
        !           919: /******************************************************************************
        !           920:  * ZapCol(col, row)
        !           921:  *
        !           922:  * purpose: delete given column in edit box. Shift cols to right given col
        !           923:  *          right. Rightmost column gets duplicated.
        !           924:  *
        !           925:  * params : DWORD col : column
        !           926:  *          DWORD row : row
        !           927:  * returns: none
        !           928:  *
        !           929:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           930:  *               currently displayed box)
        !           931:  *****************************************************************************/
        !           932: VOID
        !           933: ZapCol(
        !           934:        DWORD col, 
        !           935:        DWORD row
        !           936:        )
        !           937: {
        !           938:        DWORD x, y;
        !           939:        for (y = 0; y <= row; y++)
        !           940:                for (x = col; x < wBox - 1; x++)
        !           941:                        matBox[x][y] = matBox[x + 1][y];
        !           942:        for (y = 0; y <= row; y++)
        !           943:                matBox[x][y] = matBox[x - 1][y];
        !           944: }
        !           945: 
        !           946: 
        !           947: /******************************************************************************
        !           948:  * ZapRow(col, row)
        !           949:  *
        !           950:  * purpose: delete given row in edit box. Shift rows below given row up. Lowest
        !           951:  *          row gets duplicated
        !           952:  *
        !           953:  * params:  DWORD col : column
        !           954:  *          DWORD row : row
        !           955:  * returns: none
        !           956:  *
        !           957:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           958:  *               currently displayed box)
        !           959:  *****************************************************************************/
        !           960: VOID
        !           961: ZapRow(
        !           962:        DWORD col, 
        !           963:        DWORD row
        !           964:        )
        !           965: {
        !           966:        DWORD x, y;
        !           967:        for (x = 0; x <= col; x++)
        !           968:                for (y = row; y < kBox - 1; y++)
        !           969:                        matBox[x][y] = matBox[x][y + 1];
        !           970:        for (x = 0; x <= col; x++)
        !           971:                matBox[x][y] = matBox[x][y - 1];
        !           972: }
        !           973: 
        !           974: 
        !           975: /******************************************************************************
        !           976:  * DupCol(col, row)
        !           977:  *
        !           978:  * purpose: duplicate given column in edit box. Shift cols to right of given
        !           979:  *          col right
        !           980:  *
        !           981:  * params:  DWORD col : column
        !           982:  *          DWORD row : row
        !           983:  * returns: none
        !           984:  *
        !           985:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !           986:  *               currently displayed box)
        !           987:  *****************************************************************************/
        !           988: VOID
        !           989: DupCol(
        !           990:        DWORD col, 
        !           991:        DWORD row
        !           992:        )
        !           993: {
        !           994:        DWORD x, y;
        !           995:        for (x = wBox - 1; x > col; x--)
        !           996:                for (y = 0; y <= row; y++)
        !           997:                        matBox[x][y] = matBox[x - 1][y];
        !           998: }
        !           999: 
        !          1000: 
        !          1001: /******************************************************************************
        !          1002:  * DupRow(col, row)
        !          1003:  *
        !          1004:  * purpose: duplicate given row in edit box. Shift rows below given row down.
        !          1005:  *
        !          1006:  * params:  DWORD col : column
        !          1007:  *          DWORD row : row
        !          1008:  * returns: none
        !          1009:  *
        !          1010:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !          1011:  *               currently displayed box)
        !          1012:  *****************************************************************************/
        !          1013: VOID
        !          1014: DupRow(
        !          1015:        DWORD col, 
        !          1016:        DWORD row
        !          1017:        )
        !          1018: {
        !          1019:        DWORD x, y;
        !          1020:        for (x = 0; x <= col; x++)
        !          1021:                for (y = kBox - 1; y > row; y--)
        !          1022:                        matBox[x][y] = matBox[x][y - 1];
        !          1023: }
        !          1024: 
        !          1025: 
        !          1026: /******************************************************************************
        !          1027:  * ClearBox(col, row, bb)
        !          1028:  *
        !          1029:  * purpose: reset all pixels in edit box (make box white)
        !          1030:  *
        !          1031:  * params : none
        !          1032:  *
        !          1033:  * returns: none
        !          1034:  *
        !          1035:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !          1036:  *               currently displayed box)
        !          1037:  *
        !          1038:  *****************************************************************************/
        !          1039: VOID
        !          1040: ClearBox(
        !          1041:        VOID
        !          1042:        )                  /* Clear edit box */
        !          1043: {
        !          1044:        DWORD x, y;
        !          1045:        for (x = 0; x < wBoxLim; x++)
        !          1046:                for (y = 0; y < kBoxLim; y++)
        !          1047:                        matBox[x][y] = FALSE;
        !          1048: }
        !          1049: 
        !          1050: 
        !          1051: /******************************************************************************
        !          1052:  * BoxBackup()
        !          1053:  *
        !          1054:  * purpose:   makes a backup of pix. info. of currently displayed edit box
        !          1055:  *
        !          1056:  * params:    none
        !          1057:  *
        !          1058:  * returns:   none
        !          1059:  *
        !          1060:  * side effects: alters matBackup (local 2-d array with backup pixel info.
        !          1061:  *               on edit box )
        !          1062:  *****************************************************************************/
        !          1063: VOID
        !          1064: BoxBackup(
        !          1065:        VOID
        !          1066:        )
        !          1067: {
        !          1068:        DWORD x, y;
        !          1069:        HMENU hMenu;
        !          1070: 
        !          1071:        hMenu = GetMenu(hBox);
        !          1072:        EnableMenuItem(hMenu, BOX_UNDO, MF_ENABLED);
        !          1073:        EnableMenuItem(hMenu, BOX_REFRESH, MF_ENABLED);
        !          1074:        for (x = 0; x < wBoxLim; x++)
        !          1075:                for (y = 0; y < kBoxLim; y++)
        !          1076:                        matBackup[x][y] = matBox[x][y];
        !          1077:        wBoxBackup = wBox;
        !          1078: }
        !          1079: 
        !          1080: 
        !          1081: /******************************************************************************
        !          1082:  * BoxRestore()
        !          1083:  *
        !          1084:  * purpose : Current edit box and backup box exchange places
        !          1085:  *
        !          1086:  * params  : none
        !          1087:  *
        !          1088:  * returns : none
        !          1089:  *
        !          1090:  * side effects: alters matBox (global 2-d array with ready pixel info. on
        !          1091:  *               currently displayed box
        !          1092:  *
        !          1093:  *****************************************************************************/
        !          1094: VOID
        !          1095: BoxRestore(
        !          1096:        VOID
        !          1097:        )            /* Box and Backup exchange places */
        !          1098: {
        !          1099:        DWORD x, y, temp;
        !          1100:        CHAR z;
        !          1101: 
        !          1102:        for (x = 0; x < wBoxLim; x++)
        !          1103:                for (y = 0; y < kBoxLim; y++) {
        !          1104:                        z = matBackup[x][y];
        !          1105:                        matBackup[x][y] = matBox[x][y];
        !          1106:                        matBox[x][y] = z;
        !          1107:                }
        !          1108:        temp = wBox;
        !          1109:        wBox = wBoxBackup;
        !          1110:        wBoxBackup = temp;
        !          1111: }
        !          1112: 
        !          1113: 
        !          1114: /******************************************************************************
        !          1115:  * POINT SnapPointToGrid (Pt)
        !          1116:  *
        !          1117:  * purpose : Intended only for the Fill menu command where rubberbanding rect.
        !          1118:  *           needs to be aligned on the grid lines. Snap the current mouse
        !          1119:  *           coordinates to nearest grid intersection.
        !          1120:  *
        !          1121:  * params  : POINT Pt : current point mouse is over
        !          1122:  *
        !          1123:  * returns : POINT    : number of nearest square
        !          1124:  *
        !          1125:  * side effects:      : current mouse coordinate(global variable) altered to
        !          1126:  *                      return value
        !          1127:  *
        !          1128:  *****************************************************************************/
        !          1129: POINT 
        !          1130: SnapPointToGrid(
        !          1131:        POINT   Pt
        !          1132:        )
        !          1133: {
        !          1134: 
        !          1135:        Pt.x = (Pt.x - ptBox.x) / scale;
        !          1136:        if (Pt.y > (scale * (font.Ascent - 1)))
        !          1137:                Pt.y = Pt.y - 2;        /* Allow for break in box */
        !          1138:        Pt.y = (Pt.y - ptBox.y) / scale;
        !          1139:        return (Pt);
        !          1140: }
        !          1141: 
        !          1142: 
        !          1143: /******************************************************************************
        !          1144:  * VOID PASCAL EndRubberBandingRect()
        !          1145:  *
        !          1146:  * purpose: Stops rubberbanding rect for Fill menu command and cleans up
        !          1147:  *
        !          1148:  * params : HANDLE hDst : handle to dest. DC
        !          1149:  *
        !          1150:  * side effects: none
        !          1151:  *
        !          1152:  *****************************************************************************/
        !          1153: VOID PASCAL 
        !          1154: EndRubberBandingRect(
        !          1155:        HDC hDst  /* handle to dest. DC */
        !          1156:        )
        !          1157: {
        !          1158:        fRubberBanding = FALSE;      /* reset "in-progress" flag */
        !          1159: 
        !          1160:        ReleaseDC(hBox, hDst);
        !          1161:        ReleaseCapture();
        !          1162:        SetCursor(hOldCursor);
        !          1163: }
        !          1164: 
        !          1165: 
        !          1166: /******************************************************************************
        !          1167:  * HDC PASCAL InitialiseRubberBandingRect(hBox)
        !          1168:  *
        !          1169:  * purpose: Sets up rubberbanding rect for Fill menu command.
        !          1170:  *
        !          1171:  * params : HANDLE hDst : handle to box DC
        !          1172:  *
        !          1173:  * returns :handle to destination display context
        !          1174:  *
        !          1175:  * side effects: alters few global flags for rubberbanding
        !          1176:  *
        !          1177:  *****************************************************************************/
        !          1178: HDC PASCAL 
        !          1179: InitialiseRubberBandingRect(
        !          1180:        HDC hBox  /* handle to  DC  of box */
        !          1181:        )
        !          1182: {
        !          1183:        HDC hDst;
        !          1184: 
        !          1185:        fRubberBanding = TRUE;       /* set "in-progress" flag */
        !          1186:        fStartRubberBand = FALSE;    /* reset "start-proceedings" flag */
        !          1187:        SetCapture(hBox);            /* send all msgs to current window */
        !          1188: 
        !          1189:        hDst = GetDC (hBox);
        !          1190: 
        !          1191:        /* select pen and fill mode for rectangle*/
        !          1192:        hWhitePen  = SelectObject(hDst, GetStockObject (WHITE_PEN));
        !          1193:        hNullBrush = SelectObject(hDst, GetStockObject (NULL_BRUSH));
        !          1194:        SetROP2(hDst, R2_XORPEN);
        !          1195: 
        !          1196:        return(hDst);
        !          1197: }
        !          1198: 
        !          1199: 
        !          1200: /******************************************************************************
        !          1201:  * VOID PASCAL DrawRubberBand()
        !          1202:  *
        !          1203:  * purpose: Draw rubberbanding rect for Fill menu command.
        !          1204:  *
        !          1205:  * params : HANDLE hDst : handle to dest. DC
        !          1206:  *
        !          1207:  * side effects: alters few global flags for rubberbanding
        !          1208:  *
        !          1209:  *****************************************************************************/
        !          1210: VOID PASCAL 
        !          1211: DrawRubberBand(
        !          1212:        HDC     hDst,                        /*  handle to dest. DC */
        !          1213:        LPRECT  lpRect,
        !          1214:        DWORD   rop
        !          1215:        )
        !          1216: {
        !          1217: #ifdef DBG
        !          1218:        char    buf[256];
        !          1219: #endif
        !          1220: 
        !          1221:        SetROP2(hDst, rop);
        !          1222:        Rectangle(hDst, lpRect->left,  lpRect->top,
        !          1223:                        lpRect->right, lpRect->bottom);
        !          1224: 
        !          1225: #ifdef DBG
        !          1226:        sprintf(buf, "left=%d, top=%d, right=%d, bottom=%d", 
        !          1227:                lpRect->left,  lpRect->top, lpRect->right, lpRect->bottom);
        !          1228:        
        !          1229:        TextOut(hDst, ptBox.x+scale*wBox+16,
        !          1230:                      14+2*kBox+font.ExtLeading+3*cSysHeight,
        !          1231:                      buf, strlen(buf));
        !          1232: #endif
        !          1233: }
        !          1234: 
        !          1235: 
        !          1236: /******************************************************************************
        !          1237:  * long  APIENTRY FontEditWndProc(hBox, message, wParam, lParam)
        !          1238:  *
        !          1239:  * purpose: Master controller for Fontedit's all-encompassing main window
        !          1240:  *
        !          1241:  * params : same as for all window functions
        !          1242:  *
        !          1243:  * side effects: countless
        !          1244:  *
        !          1245:  *****************************************************************************/
        !          1246: LONG  APIENTRY 
        !          1247: FontEditWndProc(
        !          1248:        HWND   hBox,
        !          1249:        WORD   message,
        !          1250:        WPARAM wParam,
        !          1251:        LPARAM lParam
        !          1252:        )
        !          1253: {
        !          1254:        PAINTSTRUCT     ps;
        !          1255:        HMENU   hMenu;
        !          1256:        WORD    mf;
        !          1257:        POINT   pt;
        !          1258:        RECT    BoxRect;
        !          1259: 
        !          1260:        switch (message) {
        !          1261:        case WM_CLOSE:
        !          1262:                if (!CheckSave())    /* See if any files need saving */
        !          1263:                        break;
        !          1264:                /* Window's being destroyed. */
        !          1265:                if (fLoaded)         /* 4/8/87 Linsh added */
        !          1266:                        DeleteGlobalBitmap(); /* Get rid of memory DC */
        !          1267:                DestroyWindow(hFont);
        !          1268:                DestroyWindow(hBox);
        !          1269:                break;
        !          1270: 
        !          1271:        case WM_DESTROY:
        !          1272:                PostQuitMessage(0);  /* Cause application to be terminated */
        !          1273:                break;
        !          1274: 
        !          1275:        case WM_QUERYENDSESSION:
        !          1276:                if (CheckSave())             /* See if any files need saving */
        !          1277:                        return TRUE;
        !          1278:                break;
        !          1279: 
        !          1280:        case WM_ENDSESSION:
        !          1281:                if (fLoaded)
        !          1282:                        DeleteGlobalBitmap();      /* Get rid of memory DC */
        !          1283:                break;
        !          1284: 
        !          1285:        case WM_SIZE:
        !          1286:                /* Window's size is changing.  lParam contains the width
        !          1287:         ** and height, in the low and high words, respectively.
        !          1288:         ** wParam contains SIZENORMAL for "normal" size changes,
        !          1289:         ** SIZEICONIC when the window is being made iconic, and
        !          1290:         ** SIZEFULLSCREEN when the window is being made full screen. */
        !          1291:                switch (wParam) {
        !          1292:                case SIZEFULLSCREEN:
        !          1293:                case SIZENORMAL:
        !          1294:                        ResizeShow();
        !          1295:                        if (kStuff != GetkStuff())      /* Did it change ? */
        !          1296:                                ResizeShow();           /* Yes resize again */
        !          1297:                        break;
        !          1298:                }
        !          1299:                break;
        !          1300: 
        !          1301:        case WM_MOVE: /* Tell popup to move with us. */
        !          1302:                if (!IsIconic(hBox))
        !          1303:                        ResizeShow();
        !          1304:                break;
        !          1305: 
        !          1306:        case WM_PAINT:
        !          1307:                /* Time for the window to draw itself. */
        !          1308:                BeginPaint(hBox, (LPPAINTSTRUCT)&ps);
        !          1309:                FontEditPaint(hBox,  ps.hdc);
        !          1310:                EndPaint(hBox, (LPPAINTSTRUCT)&ps);
        !          1311:                break;
        !          1312: 
        !          1313: 
        !          1314:        case WM_COMMAND:
        !          1315:                /* A menu item has been selected, or a control is notifying
        !          1316:                 * its parent.  wParam is the menu item value (for menus),
        !          1317:                 * or control ID (for controls).  For controls, the low word
        !          1318:                 * of lParam has the window handle of the control, and the hi
        !          1319:                 * word has the notification code.  For menus, lParam contains
        !          1320:                 * 0L. */
        !          1321:                FontEditCommand(hBox, LOWORD(wParam));
        !          1322:                break;
        !          1323: 
        !          1324:                /* Data interchange request. */
        !          1325:        case WM_CUT:
        !          1326:        case WM_COPY:
        !          1327:        case WM_PASTE:
        !          1328:        case WM_CLEAR:
        !          1329:        case WM_UNDO:
        !          1330:        case WM_RENDERFORMAT:
        !          1331:        case WM_RENDERALLFORMATS:
        !          1332:        case WM_DESTROYCLIPBOARD:
        !          1333:        case WM_DRAWCLIPBOARD:
        !          1334:                break;
        !          1335:        case WM_INITMENU:
        !          1336:                hMenu = GetMenu(hBox);  /* Gray menu if no clipboard bitmap */
        !          1337:                mf = (WORD)(IsClipboardFormatAvailable(CF_BITMAP) ? MF_ENABLED : 
        !          1338:                                MF_GRAYED);
        !          1339:                EnableMenuItem(hMenu, BOX_PASTE, mf);
        !          1340:                EnableMenuItem(hMenu, FONT_PASTE, mf);
        !          1341:                break;
        !          1342: 
        !          1343:        /* For each of following mouse window messages, wParam contains
        !          1344:        ** bits indicating whether or not various virtual keys are down,
        !          1345:        ** and lParam is a POINT containing the mouse coordinates.   The
        !          1346:        ** keydown bits of wParam are:  MK_LBUTTON (set if Left Button is
        !          1347:        ** down); MK_RBUTTON (set if Right Button is down); MK_SHIFT (set
        !          1348:        ** if Shift Key is down); MK_ALTERNATE (set if Alt Key is down);
        !          1349:        ** and MK_CONTROL (set if Control Key is down). */
        !          1350: 
        !          1351:        case WM_LBUTTONDOWN:
        !          1352:                ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
        !          1353: 
        !          1354:                if (fStartRubberBand) {
        !          1355:                        /* a green signal to rubberband a rectangle for the
        !          1356:                         * Fill menu command rectangle now has null dimensions.
        !          1357:                         * Snap the current mouse point to nearest grid
        !          1358:                         * intersection thus defining upper left corner of
        !          1359:                         * rectangle */
        !          1360: 
        !          1361:                        if (PtInRect((LPRECT)&FontRect, pt)) {
        !          1362:                                pt = SnapPointToGrid(pt);
        !          1363:                                rectRubber.top    =  pt.y   *scale+ptBox.y+1;
        !          1364:                                rectRubber.bottom = (pt.y+1)*scale+ptBox.y-2;
        !          1365:                                rectRubber.left   =  pt.x   *scale+ptBox.x+1;
        !          1366:                                rectRubber.right  = (pt.x+1)*scale+ptBox.x-2;
        !          1367: 
        !          1368:                                hDst = InitialiseRubberBandingRect(hBox);
        !          1369:                                DrawRubberBand(hDst, &rectRubber, R2_XORPEN);
        !          1370:                        }
        !          1371:                        else {
        !          1372:                                fStartRubberBand = fRubberBanding = FALSE;
        !          1373:                                ReleaseCapture();
        !          1374:                        }
        !          1375:                }
        !          1376:                /* do operation depending upon current active command,
        !          1377:                 * but not if we just added/deleted a row/column. */
        !          1378:                if (!fJustZapped) {
        !          1379:                        if (fStartRubberBand) {
        !          1380:                                pt.x *= scale;
        !          1381:                                pt.y *= scale;
        !          1382:                                MouseInBox(hBox, message, pt);
        !          1383:                        }
        !          1384:                        else {
        !          1385:                                ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
        !          1386:                                MouseInBox(hBox, message, pt);
        !          1387:                        }
        !          1388:                }
        !          1389: 
        !          1390:                break;
        !          1391: 
        !          1392:        case WM_LBUTTONUP:               /* Get other corner of rectangle */
        !          1393:                fJustZapped = FALSE;
        !          1394:                if (fRubberBanding) {
        !          1395:                        /* if rubberbanding for the Fill menu command,
        !          1396:                         * terminate proceedings and clean up */
        !          1397:                        DrawRubberBand(hDst, &rectRubber, R2_NOT);
        !          1398:                        EndRubberBandingRect(hDst);
        !          1399:                        if (cursor) {
        !          1400:                                ReadRect();
        !          1401:                        }
        !          1402:                }
        !          1403:                if (fCaptured ) {
        !          1404:                        /* if cursor is + shaped, restore it to default */
        !          1405:                        ReleaseCapture();
        !          1406:                        SetCursor (hOldCursor);
        !          1407:                }
        !          1408:                break;
        !          1409: 
        !          1410:        case WM_RBUTTONDOWN:
        !          1411:        case WM_RBUTTONUP:
        !          1412:                break;
        !          1413: 
        !          1414:        case WM_MOUSEMOVE:                      /* If mouse is down */
        !          1415: 
        !          1416:                ((pt).x = ((*((POINTS *)&(lParam)))).x, (pt).y = ((*((POINTS *)&(lParam)))).y);
        !          1417: 
        !          1418:                if ((fRubberBanding) && (wParam & MK_LBUTTON)) {
        !          1419:                        /* if any of Fill menu commands is active
        !          1420:                        ** (AND the mouse key depressed) draw a rubberband
        !          1421:                        ** a rectangle with the mouse movements */
        !          1422: 
        !          1423:                        /* get current square number */
        !          1424:                        pt = SnapPointToGrid(pt);
        !          1425: 
        !          1426:                        /* calculate grid for new square */
        !          1427:                        BoxRect.top    =  pt.y   *scale+ptBox.y+1;
        !          1428:                        BoxRect.bottom = (pt.y+1)*scale+ptBox.y-2;
        !          1429:                        BoxRect.left   =  pt.x   *scale+ptBox.x+1;
        !          1430:                        BoxRect.right  = (pt.x+1)*scale+ptBox.x-2;
        !          1431: 
        !          1432:                        /* erase old mark */
        !          1433:                        DrawRubberBand(hDst, &rectRubber, R2_NOT);
        !          1434: 
        !          1435:                        /* limit rubber band to box */
        !          1436:                        if (BoxRect.right > (LONG) (scale * wBox + ptBox.x))
        !          1437:                                BoxRect.right = scale * wBox + ptBox.x;
        !          1438:                        if (BoxRect.bottom > (LONG) (scale * kBox + ptBox.y))
        !          1439:                                BoxRect.bottom = scale * kBox + ptBox.y;
        !          1440:                        if (BoxRect.top < 0)
        !          1441:                                BoxRect.top = 1;
        !          1442:                        if (BoxRect.left < 0)
        !          1443:                                BoxRect.left = 1;
        !          1444: 
        !          1445:                        if (ptA.x == pt.x) {
        !          1446:                                rectRubber.right  = BoxRect.right;
        !          1447:                                rectRubber.left   = BoxRect.left;
        !          1448:                        }
        !          1449:                        if (ptA.y == pt.y) {
        !          1450:                                rectRubber.bottom = BoxRect.bottom;
        !          1451:                                rectRubber.top    = BoxRect.top;
        !          1452:                        }
        !          1453: 
        !          1454:                        /* almost an IntersectRect */
        !          1455:                        if (ptA.x >= pt.x)
        !          1456:                                rectRubber.left   = BoxRect.left;
        !          1457:                        else
        !          1458:                                rectRubber.right  = BoxRect.right;
        !          1459: 
        !          1460:                        if (ptA.y >= pt.y)
        !          1461:                                rectRubber.top    = BoxRect.top;
        !          1462:                        else
        !          1463:                                rectRubber.bottom = BoxRect.bottom;
        !          1464: 
        !          1465:                        /* Draw new mark */
        !          1466:                        DrawRubberBand(hDst, &rectRubber, R2_XORPEN);
        !          1467:                }
        !          1468:                else {
        !          1469:                        /* if not "Fill"ing(AND mouse key depressed,
        !          1470:                         * paint with the mouse movements */
        !          1471:                        if ((wParam & MK_LBUTTON) && cursor == FALSE && 
        !          1472:                            fJustZapped == FALSE)
        !          1473:                                MouseInBox(hBox, message, pt);
        !          1474:                }
        !          1475:                break;
        !          1476: 
        !          1477:        case WM_LBUTTONDBLCLK:
        !          1478:        case WM_RBUTTONDBLCLK:
        !          1479:                break;
        !          1480: 
        !          1481:        default:
        !          1482: 
        !          1483:                /* Everything else comes here.  This call MUST exist
        !          1484:         ** in your window proc.  */
        !          1485: 
        !          1486:                return(DefWindowProc(hBox, message, wParam, lParam));
        !          1487:                break;
        !          1488:        }
        !          1489: 
        !          1490:        /* A window proc should always return something */
        !          1491:        return(0L);
        !          1492: }
        !          1493: 
        !          1494: 
        !          1495: /***************************** Public  Function ****************************\
        !          1496: *
        !          1497: * BOOL  APIENTRY AboutDlg(hDlg, message, wParam, lParam)
        !          1498: * HWND     hDlg;
        !          1499: * WORD message;
        !          1500: * WPARAM wParam;
        !          1501: * LPARAM lParam;
        !          1502: *
        !          1503: *
        !          1504: * Effects: none.
        !          1505: *
        !          1506: \***************************************************************************/
        !          1507: BOOL  APIENTRY 
        !          1508: AboutDlg(
        !          1509:        HWND   hDlg,
        !          1510:        WORD   message,
        !          1511:        WPARAM wParam,
        !          1512:        LPARAM lParam
        !          1513:        )
        !          1514: {
        !          1515:        UNREFERENCED_PARAMETER(lParam);
        !          1516: 
        !          1517:        switch (message) {
        !          1518:        case WM_INITDIALOG:
        !          1519:                break;
        !          1520: 
        !          1521:        case WM_COMMAND:
        !          1522:                EndDialog(hDlg, LOWORD(wParam));
        !          1523:                /* idok or idcancel */
        !          1524:                break;
        !          1525: 
        !          1526:        default:
        !          1527:                return FALSE;
        !          1528:                break;
        !          1529:        }
        !          1530:        return(TRUE);
        !          1531: }

unix.superglobalmegacorp.com

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