Annotation of mstools/samples/ttfonts/allfont.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.