Annotation of mstools/samples/sdktools/fontedit/fontchar.c, revision 1.1.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.