|
|
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.