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