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