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