Annotation of mstools/samples/ntfonts/allfont.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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