Annotation of mstools/samples/ttfonts/allfont.c, revision 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.