|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.