|
|
1.1 root 1: /**************************************************************************\
2: * allfont.c -- module to display the result of enumerating all fonts.
3: * Includes the window procedure and an initialization routine.
4: *
1.1.1.2 ! root 5: * Steve Firebaugh
! 6: * Microsoft Developer Support
! 7: * Copyright (c) 1992 Microsoft Corporation
! 8: *
1.1 root 9: * There are actually two windows serviced by this module. One for the
10: * display fonts, one for the printer fonts.
11: *
12: *
13: * Data structure:
14: * Since we keep a modest amount of data for each possible font, and
15: * since the amount of this information is known only at run time,
16: * the main data structure used here is all allocated dynamically.
17: * parFonts points to an array of ARFONT structures. These structures
18: * store two int's and then three pointers to arrays of LOGFONT,
19: * TEXTMETRIC, and int's respectively.
20: *
21: * parFonts--> |--------------------| |--------------------|
22: * | nFonts (Family0) | | nFonts (Family1) |
23: * | cySpace | | cySpace | ...
24: * | hdc | | hdc |
25: * |--------------------| |--------------------|
26: * | lf | tm | Type | | lf | tm | Type |
27: * |--------------------| |--------------------|
28: * | | | | | |
29: * | | | | | |
30: * V V V V V V
31: * |----| |------| |----| |----| |------| |----|
32: * |LOG | |TEXT | |Type| |LOG | |TEXT | |Type|
33: * |FONT| |METRIC| | | |FONT| |METRIC| | |
34: * |0,0 | |0,0 | |0,0 | |1,0 | |1,0 | |1,0 |
35: * |----| |------| |----| |----| |------| |----|
36: * |LOG | |TEXT | |Type| |LOG | |TEXT | |Type|
37: * |FONT| |METRIC| | | |FONT| |METRIC| | |
38: * |0,1 | |0,1 | |0,1 | |1,1 | |1,1 | |1,1 |
39: * |----| |------| |----| |----| |------| |----|
40: *
41: * ... ... ... ... ... ...
42: *
43: * |----| |------| |----|
44: * |LOG | |TEXT | |Type|
45: * |FONT| |METRIC| | | |----| |------| |----|
46: * |0, | |0, | |0, | |LOG | |TEXT | |Type|
47: * |nFon| |nFonts| |nFon| |FONT| |METRIC| | |
48: * |----| |------| |----| |1, | |1, | |1, |
49: * |nFon| |nFonts| |nFon|
50: * |----| |------| |----|
51: *
52: *
53: * So, to get the FontType of the 4th font within the 2nd family use:
54: * parFonts[1].Type[3]
55: *
56: * There is one final ARFONT structure which has no linked lists atttached,
57: * but has a blank HDC as padding on the far right of the window.
58: *
59: * The pointer to the array of ARFONT structures is stored in the
60: * GWL_PARFONTS extra bytes for each window. The number of face names
61: * for each window is stored in the GWLU_NFACES extra bytes.
62: *
63: \**************************************************************************/
1.1.1.2 ! root 64: #define UNICODE
1.1 root 65:
66: #include <windows.h>
67: #include <string.h>
68: #include "ntfonts.h"
69:
70:
71: typedef struct tagArFonts{
72: int nFonts;
73: int cySpace;
74: HDC hdc;
75: LOGFONT *lf;
76: TEXTMETRIC *tm;
77: int *Type;
78: } ARFONTS, *PARFONTS;
79:
80:
81: #define ALLFONTBORDER 10
82: #define CXDEF 130
83: #define BMSIZE 14
84:
85:
86: #define GWLU_PARFONTS 0
87: #define GWLU_NFACES 4
88:
89: /* forward declare function prototypes. */
90: VOID DrawBitmapXY (HDC, HBITMAP, int, int);
91:
92: PARFONTS BuildFontList(HDC, LPINT);
93: VOID BuildBitmapStrips (HWND, LPRECT, PARFONTS, int);
94:
95: int APIENTRY MyEnumFaces(LPLOGFONT, LPTEXTMETRIC, DWORD, LPVOID);
96: int APIENTRY MyEnumCopy (LPLOGFONT, LPTEXTMETRIC, DWORD, LPVOID);
97: int APIENTRY MyEnumCount(LPLOGFONT, LPTEXTMETRIC, DWORD, LPINT);
98:
99:
100:
1.1.1.2 ! root 101: int initAllFont(HWND hwndParent)
1.1 root 102: {
103: WNDCLASS wc;
104: HDC hdc;
105:
106: wc.style = NULL;
107: wc.lpfnWndProc = (WNDPROC)AllFontsWndProc;
108: wc.cbClsExtra = 0;
109: wc.cbWndExtra = 8;
110: wc.hInstance = hInst;
111: wc.hIcon = NULL;
112: wc.hCursor = LoadCursor(NULL, IDC_CROSS);
113: wc.hbrBackground = GetStockObject(WHITE_BRUSH);
114: wc.lpszMenuName = NULL;
1.1.1.2 ! root 115: wc.lpszClassName = TEXT("AllFonts");
1.1 root 116:
117: if (!RegisterClass(&wc)) return (FALSE);
118:
119:
120: /* create a window to show all of the display fonts, and send it
121: * the proper WMU_CREATE message with an HDC for the display.
122: */
1.1.1.2 ! root 123: hwndDisplayFonts = CreateMDIWindow(
! 124: TEXT("AllFonts"),
! 125: TEXT("EnumFonts (display)"),
! 126: WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
! 127: WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_HSCROLL,
1.1 root 128: 0,0,
129: GetSystemMetrics (SM_CXFULLSCREEN),
1.1.1.2 ! root 130: GetSystemMetrics (SM_CYFULLSCREEN) - GetSystemMetrics (SM_CYMENU),
! 131: hwndParent, hInst, 0);
1.1 root 132:
1.1.1.2 ! root 133: ShowWindow (hwndDisplayFonts, SW_HIDE);
1.1 root 134: hdc = GetDC (hwndDisplayFonts);
135: SendMessage (hwndDisplayFonts, WMU_CREATE, (DWORD)hdc, 0);
136: ReleaseDC (hwndDisplayFonts, hdc);
1.1.1.2 ! root 137: ShowWindow (hwndDisplayFonts, SW_SHOWMINIMIZED);
1.1 root 138:
139: if (!hwndDisplayFonts) return (FALSE);
140:
141:
142: /* create a window to show all of the printer fonts, and send it
143: * the proper WMU_CREATE message with an HDC for the printer.
144: */
1.1.1.2 ! root 145:
! 146: hwndPrinterFonts = CreateMDIWindow(
! 147: TEXT("AllFonts"),
! 148: TEXT("EnumFonts (printer)"),
! 149: WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
! 150: WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_HSCROLL,
1.1 root 151: 0,0,
152: GetSystemMetrics (SM_CXFULLSCREEN),
1.1.1.2 ! root 153: GetSystemMetrics (SM_CYFULLSCREEN) - GetSystemMetrics (SM_CYMENU),
! 154: hwndParent, hInst, 0);
1.1 root 155:
1.1.1.2 ! root 156: ShowWindow (hwndPrinterFonts, SW_HIDE);
1.1 root 157: hdc = GetPrinterDC ();
1.1.1.2 ! root 158: if (hdc == NULL) {
! 159: SetWindowLong (hwndPrinterFonts, GWLU_PARFONTS, (LONG) NULL);
! 160: } else {
! 161: SendMessage (hwndPrinterFonts, WMU_CREATE, (DWORD)hdc, 0);
! 162: DeleteDC (hdc);
! 163: }
! 164: ShowWindow (hwndPrinterFonts, SW_SHOWMINIMIZED);
1.1 root 165:
166: if (!hwndPrinterFonts) return (FALSE);
167:
1.1.1.2 ! root 168:
1.1 root 169: return TRUE;
170: }
171:
172:
173:
174:
175:
176: /**************************************************************************\
177: * function: GetPrinterDC
178: *
179: * input parameters: none.
180: *
181: * Simply return an HDC for the default printer as specified in win.ini.
182: * Note that this HDC should be deleted later (DeleteDC).
1.1.1.2 ! root 183: *
! 184: *
! 185: // UNICODE NOTICE
! 186: // this function held as ANSI rather than UNICODE because
! 187: // I have yet to find a decent way to parse wide character
! 188: // strings analogous to using the strtok() function.
! 189: *
! 190: *
1.1 root 191: \**************************************************************************/
192: #define NCHAR MAX_PATH
193:
194: HDC GetPrinterDC ()
195: {
1.1.1.2 ! root 196: CHAR szPrinter[NCHAR];
! 197:
! 198: static CHAR szDevice[NCHAR]; // CreateDCA has problems
! 199: static CHAR szDriver[NCHAR]; // if these variables are in the
! 200: static CHAR szOutput[NCHAR]; // address space local to this function.
! 201: static DEVMODEA DevMode; // However, declaring them 'static' works.
1.1 root 202:
1.1.1.2 ! root 203: DWORD dwResult;
1.1 root 204:
1.1.1.2 ! root 205: dwResult = GetProfileStringA ("windows", "device", "", szPrinter, NCHAR) ;
! 206: if (dwResult == NULL) return NULL;
1.1 root 207:
208:
1.1.1.2 ! root 209: /* note, input strings are not unicode. */
1.1 root 210: strcpy (szDevice,strtok (szPrinter, "," ));
211: strcpy (szDriver,strtok (NULL, ", "));
212: strcpy (szOutput,strtok (NULL, ", "));
213:
1.1.1.2 ! root 214: return CreateDCA (szDriver, szDevice, szOutput, (LPDEVMODEA)&DevMode);
1.1 root 215: }
216:
217:
218:
219:
220: /**************************************************************************\
221: *
222: * function: AllFontsWndProc
223: *
224: * input parameters: normal window procedure parameters.
225: *
226: * global variables:
227: * hwndMain - Main window. place to return focus.
228: *
229: * Create array of structures which contain, among other things, bitmap
230: * strips containing the face names of fonts. These strips are later
231: * scrolled back and forth as well as selected with the mouse.
232: *
233: \**************************************************************************/
1.1.1.2 ! root 234: LRESULT CALLBACK AllFontsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1 root 235: {
236: RECT rectClient;
237: int i,j;
238: int thumbpos;
239: int nStrips;
240: PARFONTS parFonts;
241: int nFaces;
242:
1.1.1.2 ! root 243:
1.1 root 244: /* Get the pointer out of the userdata extra bytes. */
245: parFonts = (PARFONTS) GetWindowLong (hwnd, GWLU_PARFONTS);
246: nFaces = GetWindowLong (hwnd, GWLU_NFACES);
247:
1.1.1.2 ! root 248: if ((parFonts == NULL) && (message != WMU_CREATE))
! 249: return (DefMDIChildProc(hwnd, message, wParam, lParam));
1.1 root 250:
251: switch (message) {
252:
253:
254: /**********************************************************************\
255: * WMU_CREATE
256: *
257: * USER create message (sent after the window is created, before it
258: * is shown for the first time). Use this rather than WM_CREATE because
259: * we want to have control over the message parameters.
260: *
261: * wParam - HDC which we build the font list for.
262: *
263: * First build the 2d variable arrays of fonts (c.f. BuildFontList), then
264: * create the bitmap strips (stored in HDCs in ARFONT structures),
265: * Set the parFonts pointer into the extra bytes for use by other messages.
266: \**********************************************************************/
267: case WMU_CREATE: {
268: int rightPos;
269: HDC hdc;
270:
271: hdc = (HDC) wParam;
272:
273: GetClientRect (hwnd, &rectClient);
274: InflateRect (&rectClient, 0, -ALLFONTBORDER);
275:
276: parFonts = BuildFontList (hdc, &nFaces);
277:
278: BuildBitmapStrips (hwnd, &rectClient, parFonts, nFaces);
279:
280: SetWindowLong (hwnd, GWLU_PARFONTS, (LONG) parFonts);
281: SetWindowLong (hwnd, GWLU_NFACES, nFaces);
282:
283: /* Compute the number of bitmap strips visible in the window.
284: * set the scroll bar range,
285: * or make it invisible if there are not enough fonts to justify.
286: */
287: nStrips = (rectClient.right - rectClient.left) /CXDEF + 1;
288: if (nFaces > nStrips) {
289: rightPos = nFaces - nStrips + 1;
290: SetScrollRange (hwnd, SB_HORZ, 0, rightPos, FALSE);
291: } else {
292: SetScrollRange (hwnd, SB_HORZ, 0, 0, FALSE);
293: }
294:
295: } break;
296:
297:
298: /**********************************************************************\
299: * WM_DESTROY
300: *
301: * Free up the memory allocated at create time. Notice that parFonts
302: * is allocated in BuildFontList, as are its subarrays.
303: \**********************************************************************/
304: case WM_DESTROY:
305: for (i= 0; i<nFaces; i++) {
1.1.1.2 ! root 306: LocalFree ( LocalHandle ((LPVOID)parFonts[i].lf ));
! 307: LocalFree ( LocalHandle ((LPVOID)parFonts[i].tm ));
! 308: LocalFree ( LocalHandle ((LPVOID)parFonts[i].Type ));
1.1 root 309: DeleteDC (parFonts[i].hdc);
310: }
311: /* also get the final, blank one */
312: DeleteDC (parFonts[nFaces].hdc);
313:
1.1.1.2 ! root 314: LocalFree ( LocalHandle ((LPVOID)parFonts));
1.1 root 315: break;
316:
317:
318: /**********************************************************************\
319: * WM_HSCROLL
320: *
321: * Slide the contents of the window back and forth. Notice that the
322: * scroll bar thumb position is important for painting and hit testing.
323: \**********************************************************************/
324: case WM_HSCROLL:
325: /* compute number of strips for page scrolling. */
326: GetClientRect (hwnd, &rectClient);
327: nStrips = (rectClient.right - rectClient.left) /CXDEF + 1;
328:
329: switch (LOWORD(wParam)){
330: int OldPos, NewPos;
331:
332: case SB_LINEDOWN:
333: OldPos = GetScrollPos (hwnd, SB_HORZ);
334: SetScrollPos (hwnd, SB_HORZ, (OldPos+1), TRUE);
335: NewPos = GetScrollPos (hwnd, SB_HORZ);
336: ScrollWindow (hwnd, (OldPos-NewPos)*CXDEF, 0, NULL, NULL);
337: break;
338:
339: case SB_PAGEDOWN:
340: OldPos = GetScrollPos (hwnd, SB_HORZ);
341: SetScrollPos (hwnd, SB_HORZ, (OldPos+(nStrips-1)), TRUE);
342: NewPos = GetScrollPos (hwnd, SB_HORZ);
343: ScrollWindow (hwnd, (OldPos-NewPos)*CXDEF, 0, NULL, NULL);
344: break;
345:
346: case SB_LINEUP:
347: OldPos = GetScrollPos (hwnd, SB_HORZ);
348: SetScrollPos (hwnd, SB_HORZ, (OldPos-1), TRUE);
349: NewPos = GetScrollPos (hwnd, SB_HORZ);
350: ScrollWindow (hwnd, (OldPos-NewPos)*CXDEF, 0, NULL, NULL);
351: break;
352:
353: case SB_PAGEUP:
354: OldPos = GetScrollPos (hwnd, SB_HORZ);
355: SetScrollPos (hwnd, SB_HORZ, (OldPos-(nStrips-1)), TRUE);
356: NewPos = GetScrollPos (hwnd, SB_HORZ);
357: ScrollWindow (hwnd, (OldPos-NewPos)*CXDEF, 0, NULL, NULL);
358: break;
359:
360: case SB_THUMBPOSITION:
361: OldPos = GetScrollPos (hwnd, SB_HORZ);
362: NewPos = HIWORD (wParam);
363: SetScrollPos (hwnd, SB_HORZ, NewPos, TRUE);
364: ScrollWindow (hwnd, (OldPos-NewPos)*CXDEF, 0, NULL, NULL);
365: break;
366:
367: }
368: break;
369:
370:
371:
372: /**********************************************************************\
373: * WM_LBUTTONDOWN
374: *
375: * Hittest based on the mouse position. When finished, hide the window.
376: \**********************************************************************/
377: case WM_LBUTTONDOWN: {
378: POINT mousePt;
379:
380: mousePt.x = LOWORD(lParam);
381: mousePt.y = HIWORD(lParam);
382:
383: mousePt.x -= 0;
384: mousePt.y -= ALLFONTBORDER;
385:
386: i = mousePt.x / CXDEF;
387: i += GetScrollPos (hwnd, SB_HORZ);
388: if (i < 0) i = 0;
389: if (i >= nFaces) i = (nFaces-1);
390:
391: j = mousePt.y / parFonts[i].cySpace;
392: if (j < 0) j = 0;
393: if (j >= parFonts[i].nFonts) j = (parFonts[i].nFonts-1);
394:
1.1.1.2 ! root 395: ShowWindow(hwnd, SW_MINIMIZE);
1.1 root 396: UpdateWindow(hwndMain);
397: flyWinWin(hwndMain, hwnd, hwndDlgLF, 40);
398: SendMessage (hwndDlgLF, WMU_DEMOTOLF, 0,(LONG) &(parFonts[i].lf[j]));
399:
400: flyWinWin(hwndMain, hwnd, hwndDlgTM, 40);
401: SendMessage (hwndDlgTM, WMU_DEMOTOTM, 0,(LONG) &(parFonts[i].tm[j]));
402: SetFocus (hwndMain);
403:
404: }break;
405:
406:
407: /**********************************************************************\
408: * WM_RBUTTONDOWN, WM_CHAR
409: *
410: * Put the window away without changing the LOGFONT or TEXTMETRIC dlgs.
411: \**********************************************************************/
412: case WM_RBUTTONDOWN:
413: case WM_CHAR :
1.1.1.2 ! root 414: ShowWindow(hwnd, SW_MINIMIZE);
1.1 root 415: SetFocus (hwndMain);
416: break;
417:
418:
419: /**********************************************************************\
420: * WM_PAINT
421: *
422: * Using the HDCs stored in the parFonts array, blt enough strips of
423: * font family names to cover the window.
424: \**********************************************************************/
425: case WM_PAINT : {
426: PAINTSTRUCT ps;
427: HDC hdc;
428: int iStrip;
429:
1.1.1.2 ! root 430: if (parFonts == NULL) break;
! 431:
1.1 root 432: GetClientRect (hwnd, &rectClient);
433: hdc = BeginPaint(hwnd, &ps);
434:
435: thumbpos = GetScrollPos (hwnd, SB_HORZ);
436:
437: nStrips = (rectClient.right - rectClient.left) /CXDEF + 1;
438:
439: for (iStrip= 0; iStrip<nStrips; iStrip++)
440: BitBlt (hdc, iStrip*CXDEF,0,
441: CXDEF,
442: (rectClient.bottom - rectClient.top),
443: parFonts[iStrip+thumbpos].hdc, 0,0, SRCCOPY);
444:
445:
446: EndPaint (hwnd, &ps);
447: } break;
448:
449:
1.1.1.2 ! root 450: default: break;
! 451: } /* end switch */
! 452:
! 453: return (DefMDIChildProc(hwnd, message, wParam, lParam));
1.1 root 454: }
455:
456:
457:
458:
459: /**************************************************************************\
460: *
461: * function: DrawBitmapXY()
462: *
463: * input parameters: HDC, HBITMAP,
464: * X, Y - destination position. (get width and height from hbitmap)
465: *
466: * Draw the bitmap into the hdc. Source rectangle computed to include the
467: * whole bitmap.
468: *
469: * global variables: none.
470: *
471: \**************************************************************************/
472: VOID DrawBitmapXY (HDC hdc, HBITMAP hbm, int x, int y)
473: {
474: BOOL f;
475: HDC hdcBits;
476: BITMAP bm;
477:
478: hdcBits = CreateCompatibleDC(hdc);
479: GetObject (hbm, sizeof(BITMAP), &bm);
480: SelectObject(hdcBits,hbm);
481: f = BitBlt(hdc,x,y,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);
482: DeleteDC(hdcBits);
483: }
484:
485:
486:
487:
488:
489:
490:
491: /**************************************************************************\
492: * function: BuildBitmapStrips
493: *
494: * input parameters:
495: * hwnd - window this will all be painted on some day, needed for GetDC
496: * lprectClient - Pointer to client window rect, bitmap strips are this high
497: * parFonts - array with all the font information.
498: * nFaces - number of face names (array size of parFonts).
499: *
500: * Once the fonts have all been queried, create bitmaps and HDCs for them, and
501: * draw the different fonts into the different bitmap strips.
502: \**************************************************************************/
503: VOID BuildBitmapStrips (HWND hwnd, LPRECT lprectClient,
504: PARFONTS parFonts, int nFaces)
505: {
506: int i,j;
507: HFONT hNewFont;
508: HBITMAP hbm;
509: HBITMAP hbmtt, hbmdevice;
510: RECT rectClip, rectStrip;
511: HDC hdc;
512: int height;
513: int rightshift;
514:
515: /* load 2 bitmaps used to "tag" true type and printer fonts. */
1.1.1.2 ! root 516: hbmtt = LoadBitmap (hInst, TEXT("bmtt"));
! 517: hbmdevice = LoadBitmap (hInst, TEXT("bmdevice"));
1.1 root 518:
519: /* establish bounds of vertical strip that all fonts are drawn into. */
520: hdc = GetDC (hwnd);
521: rectStrip.left = rectStrip.top =0;
522: rectStrip.right = CXDEF;
523: rectStrip.bottom = (lprectClient->bottom - lprectClient->top);
524:
525:
526: /* step through all of the face names. For each one, compute the cySpace-
527: * i.e. number of pixels per entry. also create a memory DC that we can
528: * draw the font into. This DC provides the STRIP later blt'ed out at
529: * paint time.
530: */
531: for (i= 0; i<nFaces; i++) {
532: parFonts[i].cySpace = rectStrip.bottom / parFonts[i].nFonts;
533: parFonts[i].hdc = CreateCompatibleDC (hdc);
534:
535: /* When there is only one font, then make a small bitmap. If there
536: * is more than one, then make a bitmap the whole height of the window.
537: */
538: height = (parFonts[i].nFonts == 1) ?
539: parFonts[i].lf[0].lfHeight + ALLFONTBORDER :
540: rectStrip.bottom;
541: hbm = CreateCompatibleBitmap (hdc, rectStrip.right,height);
542:
543: SelectObject (parFonts[i].hdc, hbm);
544: FillRect (parFonts[i].hdc, &rectStrip, GetStockObject(WHITE_BRUSH));
545: SelectObject (parFonts[i].hdc, GetStockObject(NULL_BRUSH));
546:
547: /* step through each font for the face name. Establish a bounding
548: * rectangle for the name, write the name and mark with bitmaps if apropos
549: */
550: for (j = 0; j<parFonts[i].nFonts; j++) {
551: rectClip.left = 0;
552: rectClip.right = rectClip.left + CXDEF - 5;
553: rectClip.top = j*parFonts[i].cySpace+ALLFONTBORDER;
554: rectClip.bottom = rectClip.top+ parFonts[i].lf[j].lfHeight;
555: rightshift = 0;
556:
557:
558: /* for true type fonts, add special bitmap on left, top */
1.1.1.2 ! root 559: if (parFonts[i].Type[j] & TRUETYPE_FONTTYPE) {
1.1 root 560: DrawBitmapXY (parFonts[i].hdc, hbmtt,rectClip.left,rectClip.top);
561: rightshift = BMSIZE;
562: }
563:
564:
565: /* for printer fonts, add printer bitmap on left, shifted down
566: * for display fonts, create a logical font to draw the face name with.
567: */
568: if (parFonts[i].Type[j] & DEVICE_FONTTYPE) {
569: DrawBitmapXY (parFonts[i].hdc, hbmdevice,rectClip.left,rectClip.top+ BMSIZE);
570: rightshift = BMSIZE;
571: hNewFont = NULL;
572: } else {
573: hNewFont = CreateFontIndirect (&(parFonts[i].lf[j]));
574: SelectObject (parFonts[i].hdc, hNewFont);
575: }
576:
577: /* iff bitmap drawn, shift text over to the right. */
578: rectClip.left+=rightshift;
579:
580: /* draw the face name in the rectangle allotted. */
581: ExtTextOut (parFonts[i].hdc,
582: rectClip.left, rectClip.top, ETO_CLIPPED,
583: &rectClip,
584: parFonts[i].lf[j].lfFaceName,
1.1.1.2 ! root 585: CharStrLen(parFonts[i].lf[j].lfFaceName),
1.1 root 586: NULL );
587:
588:
589: DeleteObject (hNewFont);
590: }
591: }
592:
593: /* make one final strip on the far right side as a white space buffer */
594: hbm = CreateCompatibleBitmap (hdc, rectStrip.right, rectStrip.bottom);
595: SelectObject (parFonts[nFaces].hdc, hbm);
596: FillRect (parFonts[nFaces].hdc, &rectStrip, GetStockObject(WHITE_BRUSH));
597:
598: ReleaseDC (hwnd, hdc);
599: DeleteObject (hbmtt);
600: DeleteObject (hbmdevice);
601: }
602:
603:
604:
605:
606:
607: /* In the callback functions from the enumerations, there is a limited
608: * ability to pass in parameters. For that reason, declare the following
609: * global variables to be used by any of the call back functions.
610: */
611: HDC hdcGlobal;
612: PARFONTS parFontsGlobal;
613: int iFace,jFont;
614: int nFaces;
615:
616: /* General call structure:
617: *
618: * BuildFontList()
619: * EnumFonts
620: * MyEnumCount()
621: * LocalAlloc
622: * EnumFonts
623: * MyEnumFaces()
624: * EnumFonts
625: * MyEnumCount()
626: * LocalAlloc
627: * LocalAlloc
628: * LocalAlloc
629: * EnumFonts
630: * MyEnumCopy()
631: */
632:
633:
634:
635: /**************************************************************************\
636: * function: BuildFontList
637: *
638: * input parameters:
639: * hdcIn - hdc to query the fonts for.
640: * retnFaces - (OUT) pointer to nFaces value
641: *
642: * Enumerate all of the fonts for this DC allocating and filling up the
643: * parFonts structure as needed.
644: \**************************************************************************/
645: PARFONTS BuildFontList(HDC hdcIn, LPINT retnFaces)
646: {
647:
648: nFaces = 0;
649:
650: /* hdcGlobal is global variable also used by the callback functions. */
651: hdcGlobal = hdcIn;
652:
653: /* count the total number of face names. */
654: EnumFonts (hdcGlobal, NULL, (FONTENUMPROC)MyEnumCount, (LPARAM)&nFaces);
655:
656:
657: /* allocate the pointer to the array of PArFont structures. */
658: parFontsGlobal = (PARFONTS)LocalAlloc (LPTR, sizeof(ARFONTS) * (nFaces+1));
659:
660: /* step through all fonts again. For each one fill a LOGFONT and
661: * a TEXTMETRIC stucture.
662: */
663: iFace = 0;
664: EnumFonts (hdcGlobal, NULL, (FONTENUMPROC)MyEnumFaces, (LPARAM)NULL);
665:
666: *retnFaces = nFaces;
667: return parFontsGlobal;
668: }
669:
670:
671:
672:
673:
674:
675:
676: /**************************************************************************\
677: * function: MyEnumFaces
678: *
679: * input parameters: c.f. EnumFonts
680: *
681: * Count the number of fonts for this particular face name. Allocate the
682: * LOGFONT and TEXTMETRIC arrays large enough to hold all of them. Then
683: * enumerate the fonts once again to fill in these arrays.
684: \**************************************************************************/
685: int APIENTRY MyEnumFaces(
686: LPLOGFONT lpLogFont,
687: LPTEXTMETRIC lpTEXTMETRICs,
688: DWORD fFontType,
689: LPVOID lpData)
690: {
691: int nFonts;
692:
693:
694: UNREFERENCED_PARAMETER (lpTEXTMETRICs);
695: UNREFERENCED_PARAMETER (fFontType);
696: UNREFERENCED_PARAMETER (lpData);
697:
698:
699: nFonts = 0;
700: EnumFonts (hdcGlobal, lpLogFont->lfFaceName, (FONTENUMPROC)MyEnumCount, (LPARAM)&nFonts);
701:
702:
703: parFontsGlobal[iFace].lf = (LPLOGFONT)LocalAlloc (LPTR, sizeof(LOGFONT) * nFonts);
704: parFontsGlobal[iFace].tm = (LPTEXTMETRIC)LocalAlloc (LPTR, sizeof(TEXTMETRIC) * nFonts);
705: parFontsGlobal[iFace].Type = (LPINT)LocalAlloc (LPTR, sizeof(int) * nFonts);
706:
707: if ((parFontsGlobal[iFace].lf == NULL) ||
708: (parFontsGlobal[iFace].tm == NULL) ||
709: (parFontsGlobal[iFace].Type == NULL)) {
1.1.1.2 ! root 710: MessageBox (hwndMain, TEXT("alloc failed"), MBERROR,MBERRORFLAGS);
1.1 root 711: return FALSE;
712: }
713:
714: parFontsGlobal[iFace].nFonts = nFonts;
715:
716: jFont = 0;
717: EnumFonts (hdcGlobal, lpLogFont->lfFaceName, (FONTENUMPROC)MyEnumCopy, (LPARAM)NULL);
718:
719: iFace++;
720:
721: return TRUE;
722: }
723:
724:
725:
726: /**************************************************************************\
727: * function: MyEnumCopy
728: *
729: * input parameters: c.f. EnumFonts
730: *
731: * Each time that this function is called, copy the LOGFONT and TEXTMETRIC
732: * structures into the proper place in the global arrays. Incr jFont.
733: \**************************************************************************/
734: int APIENTRY MyEnumCopy(
735: LPLOGFONT lpLogFont,
736: LPTEXTMETRIC lpTEXTMETRICs,
737: DWORD fFontType,
738: LPVOID lpData)
739: {
740: LOGFONT *lplf;
741: TEXTMETRIC *lptm;
742: int *pType;
743:
744: UNREFERENCED_PARAMETER (lpData);
745:
746: lplf = parFontsGlobal[iFace].lf;
747: lptm = parFontsGlobal[iFace].tm;
748: pType = parFontsGlobal[iFace].Type;
749:
750: lplf[jFont] = *lpLogFont;
751: lptm[jFont] = *lpTEXTMETRICs;
752: pType[jFont] = fFontType;
753:
754: jFont++;
755: return TRUE;
756: }
757:
758:
759:
760: /**************************************************************************\
761: * function: MyEnumCount
762: *
763: * input parameters: c.f. EnumFonts
764: *
765: * Simply increment the variable that lpData points to.
766: \**************************************************************************/
767: int APIENTRY MyEnumCount(
768: LPLOGFONT lpLogFont,
769: LPTEXTMETRIC lpTEXTMETRICs,
770: DWORD fFontType,
771: LPINT lpData)
772: {
773: UNREFERENCED_PARAMETER (lpLogFont);
774: UNREFERENCED_PARAMETER (lpTEXTMETRICs);
775: UNREFERENCED_PARAMETER (fFontType);
776:
777: (*lpData)++;
778: return TRUE;
779: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.