home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / gdi / fonts / fontview / dialogs.c next >
C/C++ Source or Header  |  1997-10-05  |  33KB  |  790 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 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. #define NOMINMAX
  13. #include <windows.h>
  14. #include "FontView.h"
  15.  
  16. #include <stdlib.h>
  17.  
  18. #if !defined (APIENTRY)
  19. #define APIENTRY FAR PASCAL
  20. #endif
  21.  
  22. BOOL CenterWindow (HWND, HWND);
  23.  
  24.  
  25. typedef struct FONTENUM {
  26.     short       ft;
  27.     TEXTMETRIC  tm;
  28.     LOGFONT     lf;
  29. } FONTSTRUCT;
  30. typedef FONTSTRUCT      *PFONTSTRUCT;
  31. typedef FONTSTRUCT NEAR *NPFONTSTRUCT;
  32. typedef FONTSTRUCT FAR  *LPFONTSTRUCT;
  33.  
  34. typedef struct FONTLIST {
  35.     int     count;
  36.     HANDLE  hList;
  37. } FONTLIST;
  38. typedef FONTLIST        *PFONTLIST;
  39. typedef FONTLIST NEAR   *NPFONTLIST;
  40. typedef FONTLIST FAR    *LPFONTLIST;
  41.  
  42.  
  43. void SetDlgItemValue (HWND hDlg, int nIDDlgItem, int wValue, BOOL bSigned, int nBase)
  44. {
  45.     char szValue[20];
  46.  
  47.     switch (nBase) {
  48.         case 8:
  49.             wsprintf (szValue, "0o%o", wValue);
  50.             SetDlgItemText (hDlg, nIDDlgItem, szValue);
  51.             break;
  52.         case 16:
  53.             wsprintf (szValue, "0x%x", wValue);
  54.             SetDlgItemText (hDlg, nIDDlgItem, szValue);
  55.             break;
  56.         default:
  57.             SetDlgItemInt (hDlg, nIDDlgItem, wValue, bSigned);
  58.             break;
  59.     }
  60. }
  61.  
  62. int FAR PASCAL DlgEnumFontSizes (lpLogFont, lpTextMetric, nFontType, lpData)
  63.     LPLOGFONT lpLogFont;
  64.     LPTEXTMETRIC lpTextMetric;
  65.     short nFontType;
  66.     LPHANDLE lpData;
  67. {
  68.     HANDLE hFonts;
  69.     LPFONTSTRUCT pFS;
  70.     LPFONTLIST pFL;
  71.  
  72.     /*
  73.         This function will lock down the incoming handle, properly alloc, and realloc the
  74.         handle within it to hold the data of the fonts enumerated, then unlock the handle.
  75.     */
  76.     hFonts = *lpData;
  77.     pFL = (LPFONTLIST)GlobalLock (hFonts);
  78.     if (!pFL) {
  79.         return FALSE;
  80.     } else if (pFL->count == 0) {
  81.         pFL->hList = GlobalAlloc (GHND, sizeof(FONTSTRUCT));
  82.     } else {
  83.         pFL->hList = GlobalReAlloc (pFL->hList, sizeof(FONTSTRUCT)*(1+pFL->count), GMEM_MOVEABLE);
  84.     }
  85.  
  86.     if (pFL->hList) {
  87.         pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  88.         if (pFS) {
  89.             pFS[pFL->count].ft = nFontType;
  90.             pFS[pFL->count].tm = *lpTextMetric;
  91.             pFS[pFL->count].lf = *lpLogFont;
  92.             GlobalUnlock (pFL->hList);
  93.             pFL->count++;
  94.         }
  95.         GlobalUnlock (hFonts);
  96.  
  97.     } else {
  98.         GlobalUnlock (hFonts);
  99.         return FALSE;
  100.     }
  101.  
  102.     return TRUE;
  103. }
  104.  
  105. int FAR PASCAL DlgEnumFontNames (lpLogFont, lpTextMetric, nFontType, lpData)
  106.     LPLOGFONT lpLogFont;
  107.     LPTEXTMETRIC lpTextMetric;
  108.     short nFontType;
  109.     LPHANDLE lpData;
  110. {
  111.     HDC  hdc;
  112.     HWND hwnd;
  113.     HANDLE hInst;
  114.     FARPROC lpFontEnumProc;
  115.  
  116. /*
  117.    This function is just a pass through. For each face encountered, it will in turn enumerate all
  118.    sizes available. the lpData, which is a FAR * to a FONTSTRUCT structure will simply be passed
  119.    on to the second enumeration procedure which will fill it in.
  120.  */
  121.     hwnd = GetFocus();
  122. #if defined (WIN32)
  123.     hInst = (HANDLE)GetWindowLong (hwnd, GWL_HINSTANCE);
  124. #elif defined (WIN16)
  125.     hInst = (HANDLE)GetWindowWord (hwnd, GWW_HINSTANCE);
  126. #endif
  127.  
  128.     lpFontEnumProc = MakeProcInstance((FARPROC)DlgEnumFontSizes, hInst);
  129.     if (lpFontEnumProc) {
  130.         hdc  = GetDC(hwnd);
  131.         EnumFonts (hdc, lpLogFont->lfFaceName, (FONTENUMPROC)lpFontEnumProc, (LPARAM)lpData);
  132.         ReleaseDC(hwnd, hdc);
  133.         FreeProcInstance (lpFontEnumProc);
  134.     } else {
  135.         MessageBox (GetFocus(), "Couldn't create a proc instance", "FontView", MB_OK);
  136.         return FALSE;
  137.     }
  138.     return TRUE;
  139.  
  140.     lpTextMetric;  // unreferenced formal parameter
  141.     nFontType;     // unreferenced formal parameter
  142. }
  143.  
  144.  
  145.  
  146. BOOL APIENTRY SimpleDlgProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  147. {
  148.     int wmId;
  149.     static HBITMAP hbmFontView;
  150.     static BITMAP bmFontView;
  151.     RECT rect;
  152.     HDC hdc, hdcSrc;
  153.     HBITMAP hbmOld;
  154.     PAINTSTRUCT ps;
  155.     HANDLE hInst;
  156.  
  157. #if defined (WIN32)
  158.     hInst = (HANDLE)GetWindowLong (hwnd, GWL_HINSTANCE);
  159. #elif defined (WIN16)
  160.     hInst = (HANDLE)GetWindowWord (hwnd, GWW_HINSTANCE);
  161. #endif
  162.  
  163.     switch (msg) {
  164.         case WM_INITDIALOG:
  165.             CenterWindow (hwnd, GetWindow (hwnd, GW_OWNER));
  166.             hbmFontView = LoadBitmap (hInst, "FONTVIEW");
  167.             GetObject (hbmFontView,sizeof(BITMAP), &bmFontView);
  168.             if (!hbmFontView) MessageBeep(0);
  169.             return (TRUE);
  170.  
  171.         case WM_DESTROY:
  172.             DeleteObject (hbmFontView);
  173.             break;
  174.  
  175.         case WM_PAINT:
  176.             hdc = BeginPaint (hwnd, &ps);
  177.             GetWindowRect (hwnd, &rect);
  178.             ScreenToClient (hwnd, (LPPOINT)&rect.left);
  179.             ScreenToClient (hwnd, (LPPOINT)&rect.right);
  180.             hdc = GetDC (hwnd);
  181.             hdcSrc = CreateCompatibleDC (hdc);
  182.             hbmOld = SelectObject (hdcSrc, hbmFontView);
  183.             if (!BitBlt (hdc, 0, 0, bmFontView.bmWidth, bmFontView.bmHeight, hdcSrc, 0, 0, SRCCOPY)) {
  184.                 MessageBeep(0);
  185.             }
  186.             SelectObject (hdcSrc, hbmOld);
  187.             DeleteDC (hdcSrc);
  188.             EndPaint (hwnd, &ps);
  189.             break;
  190.  
  191.         case WM_COMMAND:
  192. #if defined (WIN32)
  193.             wmId = LOWORD(wParam);
  194. #elif defined (WIN16)
  195.             wmId = wParam;
  196. #endif
  197.             switch (wmId) {
  198.  
  199.                 case IDOK:
  200.                     EndDialog(hwnd, TRUE);
  201.                     return (TRUE);
  202.  
  203.                 case IDCANCEL:
  204.                     EndDialog(hwnd, TRUE);
  205.                     return (TRUE);
  206.             }
  207.             break;
  208.     }
  209.     return (FALSE);
  210.  
  211.     lParam; // unreferenced formal parameter
  212. }
  213.  
  214.  
  215. /*
  216.     This dialog will present edit controls for all the parameters of a CreateFont call.
  217.     The user can put any value in any of the fields, no validation is done. These parameters
  218.     are then used to create a font with, and that will be the font that will be displayed.
  219.  */
  220. BOOL APIENTRY CreateDlgProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  221. {
  222.     int wmId, i;
  223.     BOOL bDone;
  224. static LOGFONT lfDlg;
  225. static LPLOGFONT lplf;
  226.  
  227.     switch (msg) {
  228.         case WM_INITDIALOG:
  229.             CenterWindow (hwnd, GetWindow (hwnd, GW_OWNER));
  230.             lplf = (LOGFONT *)lParam;
  231.             lfDlg = *lplf;
  232.             SetDlgItemInt (hwnd, CFD_HEIGHT, (int)lfDlg.lfHeight, TRUE);
  233.             SetDlgItemInt (hwnd, CFD_WIDTH, (int)lfDlg.lfWidth, TRUE);
  234.             SetDlgItemInt (hwnd, CFD_ESCAPEMENT, (int)lfDlg.lfEscapement, TRUE);
  235.             SetDlgItemInt (hwnd, CFD_ORIENTATION, (int)lfDlg.lfOrientation, TRUE);
  236.             SetDlgItemInt (hwnd, CFD_WEIGHT, (int)lfDlg.lfWeight, FALSE);
  237.             SetDlgItemInt (hwnd, CFD_ITALIC, (int)lfDlg.lfItalic, FALSE);
  238.             SetDlgItemInt (hwnd, CFD_UNDERLINE, (int)lfDlg.lfUnderline, FALSE);
  239.             SetDlgItemInt (hwnd, CFD_STRIKEOUT, (int)lfDlg.lfStrikeOut, FALSE);
  240.             SetDlgItemInt (hwnd, CFD_CHARSET, (int)lfDlg.lfCharSet, FALSE);
  241.             SetDlgItemInt (hwnd, CFD_OUTPUTPRECISION, (int)lfDlg.lfOutPrecision, FALSE);
  242.             SetDlgItemInt (hwnd, CFD_CLIPPRECISION, (int)lfDlg.lfClipPrecision, FALSE);
  243.             SetDlgItemInt (hwnd, CFD_QUALITY, (int)lfDlg.lfQuality, FALSE);
  244.             SetDlgItemInt (hwnd, CFD_PITCHANDFAMILY, (int)lfDlg.lfPitchAndFamily, FALSE);
  245.             SetDlgItemText(hwnd, CFD_FACENAME, lfDlg.lfFaceName);
  246.  
  247.             return (TRUE);
  248.  
  249.         case WM_COMMAND:
  250. #if defined (WIN32)
  251.             wmId = LOWORD(wParam);
  252. #elif defined (WIN16)
  253.             wmId = wParam;
  254. #endif
  255.             switch (wmId) {
  256.                 case CFD_DEFAULT:
  257.                     // Set all elements to ZERO. This will give us a 'default' font
  258.                     for (i=CFD_BASE; i<=CFD_PITCHANDFAMILY; i++) {
  259.                         SetDlgItemInt (hwnd, i, 0, FALSE);
  260.                     }
  261.                     SetDlgItemText (hwnd, CFD_FACENAME, "");
  262.                     break;
  263.  
  264.                 case IDOK:
  265.                     // Get the data from the edit control, we will then use this for a 'CreatFont' call
  266.                     lfDlg.lfHeight = GetDlgItemInt (hwnd, CFD_HEIGHT, &bDone, TRUE);
  267.                     lfDlg.lfWidth = GetDlgItemInt (hwnd, CFD_WIDTH, &bDone, TRUE);
  268.                     lfDlg.lfEscapement = GetDlgItemInt (hwnd, CFD_ESCAPEMENT, &bDone, TRUE);
  269.                     lfDlg.lfOrientation = GetDlgItemInt (hwnd, CFD_ORIENTATION, &bDone, TRUE);
  270.                     lfDlg.lfWeight = GetDlgItemInt (hwnd, CFD_WEIGHT, &bDone, FALSE);
  271.                     lfDlg.lfItalic = (BYTE)GetDlgItemInt (hwnd, CFD_ITALIC, &bDone, FALSE);
  272.                     lfDlg.lfUnderline = (BYTE)GetDlgItemInt (hwnd, CFD_UNDERLINE, &bDone, FALSE);
  273.                     lfDlg.lfStrikeOut = (BYTE)GetDlgItemInt (hwnd, CFD_STRIKEOUT, &bDone, FALSE);
  274.                     lfDlg.lfCharSet = (BYTE)GetDlgItemInt (hwnd, CFD_CHARSET, &bDone, FALSE);
  275.                     lfDlg.lfOutPrecision = (BYTE)GetDlgItemInt (hwnd, CFD_OUTPUTPRECISION, &bDone, FALSE);
  276.                     lfDlg.lfClipPrecision = (BYTE)GetDlgItemInt (hwnd, CFD_CLIPPRECISION, &bDone, FALSE);
  277.                     lfDlg.lfQuality = (BYTE)GetDlgItemInt (hwnd, CFD_QUALITY, &bDone, FALSE);
  278.                     lfDlg.lfPitchAndFamily = (BYTE)GetDlgItemInt (hwnd, CFD_PITCHANDFAMILY, &bDone, FALSE);
  279.                     GetDlgItemText(hwnd, CFD_FACENAME, lfDlg.lfFaceName,20);
  280.                     // and copy the data into our external structure
  281.                     *lplf = lfDlg;
  282.                     EndDialog(hwnd, TRUE);
  283.                     return (TRUE);
  284.  
  285.                 case IDCANCEL:
  286.                     // Exit without changing anything
  287.                     EndDialog(hwnd, TRUE);
  288.                     return (TRUE);
  289.  
  290.             }
  291.             break;
  292.     }
  293.     return (FALSE);
  294.  
  295.     lParam; //unreferenced formal paramter
  296. }
  297.  
  298. /*
  299.  This dialog will display the TEXTMETRIC data that is retrieved from a 'GetTextMetric' call.
  300.  If the 'Select' button is clicked, then the current CreateFont data will be replaced with
  301.  as much data from TEXTMETRIC as possible.
  302. */
  303. BOOL APIENTRY MetricsDlgProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  304. {
  305. static LOGFONT lfDlg;
  306. static LPLOGFONT lplf;
  307. static TEXTMETRIC tm;
  308. static char szFacename[LF_FACESIZE];
  309.     int wmId;
  310.     BOOL bDone;
  311.     TEXTMETRIC tmTmp;
  312.     HFONT hfont, hfontPrev;
  313.     HDC   hdc;
  314.     char szBuffer[LF_FACESIZE+15];
  315.  
  316.  
  317.     switch (msg) {
  318.         case WM_INITDIALOG:
  319.             CenterWindow (hwnd, GetWindow (hwnd, GW_OWNER));
  320.             lplf = (LOGFONT *)lParam;
  321.             lfDlg = *lplf;
  322.  
  323.             hfont = CreateFontIndirect (&lfDlg);
  324.             hdc = GetDC (hwnd);
  325.             hfontPrev = SelectObject (hdc, hfont);
  326.             GetTextMetrics (hdc, &tm);
  327.             GetTextFace    (hdc, sizeof(szFacename), szFacename);
  328.             SelectObject (hdc, hfontPrev);
  329.             DeleteObject (hfont);
  330.             ReleaseDC (hwnd, hdc);
  331.  
  332.             wsprintf (szBuffer, "TextMetrics: %s", (LPSTR)szFacename);
  333.             SetWindowText (hwnd, szBuffer);
  334.  
  335.             SetDlgItemInt (hwnd, TMD_HEIGHT, (int)tm.tmHeight, TRUE);
  336.             SetDlgItemInt (hwnd, TMD_ASCENT, (int)tm.tmAscent, TRUE);
  337.             SetDlgItemInt (hwnd, TMD_DESCENT, (int)tm.tmDescent, TRUE);
  338.             SetDlgItemInt (hwnd, TMD_INTERNAL, (int)tm.tmInternalLeading, TRUE);
  339.             SetDlgItemInt (hwnd, TMD_EXTERNAL, (int)tm.tmExternalLeading, TRUE);
  340.             SetDlgItemInt (hwnd, TMD_AVEWIDTH, (int)tm.tmAveCharWidth, TRUE);
  341.             SetDlgItemInt (hwnd, TMD_MAXWIDTH, (int)tm.tmMaxCharWidth, TRUE);
  342.             SetDlgItemInt (hwnd, TMD_WEIGHT, (int)tm.tmWeight, TRUE);
  343.             SetDlgItemInt (hwnd, TMD_ITALIC, (int)tm.tmItalic, FALSE);
  344.             SetDlgItemInt (hwnd, TMD_UNDERLINE, (int)tm.tmUnderlined, FALSE);
  345.             SetDlgItemInt (hwnd, TMD_STRUCKOUT, (int)tm.tmStruckOut, FALSE);
  346.             SetDlgItemInt (hwnd, TMD_FIRSTCHAR, (int)tm.tmFirstChar, FALSE);
  347.             SetDlgItemInt (hwnd, TMD_LASTCHAR, (int)tm.tmLastChar, FALSE);
  348.             SetDlgItemInt (hwnd, TMD_DEFAULTCHAR, (int)tm.tmDefaultChar, FALSE);
  349.             SetDlgItemInt (hwnd, TMD_BREAKCHAR, (int)tm.tmBreakChar, FALSE);
  350.             SetDlgItemInt (hwnd, TMD_PITCHANDFAMILY, (int)tm.tmPitchAndFamily, FALSE);
  351.             SetDlgItemInt (hwnd, TMD_CHARSET, (int)tm.tmCharSet, FALSE);
  352.             SetDlgItemInt (hwnd, TMD_OVERHANG, (int)tm.tmOverhang, TRUE);
  353.             SetDlgItemInt (hwnd, TMD_DIGITIZEDASPECTX, (int)tm.tmDigitizedAspectX, TRUE);
  354.             SetDlgItemInt (hwnd, TMD_DIGITIZEDASPECTY, (int)tm.tmDigitizedAspectY, TRUE);
  355.  
  356.             return (TRUE);
  357.  
  358.         case WM_COMMAND:
  359. #if defined (WIN32)
  360.             wmId = LOWORD(wParam);
  361. #elif defined (WIN16)
  362.             wmId = wParam;
  363. #endif
  364.             switch (wmId) {
  365.                 case IDOK:
  366.                     // Lets pull in as much data from the TEXTMETRIC structure as possible...
  367.                     lfDlg.lfHeight         = tm.tmHeight;
  368.                     lfDlg.lfWidth          = tm.tmAveCharWidth;
  369.                     //lfDlg.lfEscapement - No Use
  370.                     //lfDlg.lfOrientation - No Use
  371.                     lfDlg.lfWeight         = tm.tmWeight;
  372.                     lfDlg.lfItalic         = tm.tmItalic;
  373.                     lfDlg.lfUnderline      = tm.tmUnderlined;
  374.                     lfDlg.lfStrikeOut      = tm.tmStruckOut;
  375.                     lfDlg.lfCharSet        = tm.tmCharSet;
  376.                     //lfDlg.lfOutPrecision - No Use
  377.                     //lfDlg.lfClipPrecision - No Use
  378.                     //lfDlg.lfQuality - No Use
  379.                     lfDlg.lfPitchAndFamily = tm.tmPitchAndFamily;
  380.                     lstrcpy(lfDlg.lfFaceName, szFacename);
  381.  
  382.                     // Lets create a font with this new data
  383.                     hfont = CreateFontIndirect (&lfDlg);
  384.                     hdc = GetDC (hwnd);
  385.                     hfontPrev = SelectObject (hdc, hfont);
  386.                     GetTextMetrics (hdc, &tmTmp);
  387.                     // Get the face name
  388.                     GetTextFace    (hdc, sizeof(szBuffer), szBuffer);
  389.                     SelectObject (hdc, hfontPrev);
  390.                     DeleteObject (hfont);
  391.                     ReleaseDC (hwnd, hdc);
  392.  
  393.                     // And verify that we did indeed get the same font.
  394.                     bDone = TRUE;
  395.                     bDone = bDone && (tm.tmHeight==tmTmp.tmHeight);
  396.                     bDone = bDone && (tm.tmAscent==tmTmp.tmAscent);
  397.                     bDone = bDone && (tm.tmDescent==tmTmp.tmDescent);
  398.                     bDone = bDone && (tm.tmInternalLeading==tmTmp.tmInternalLeading);
  399.                     bDone = bDone && (tm.tmExternalLeading==tmTmp.tmExternalLeading);
  400.                     bDone = bDone && (tm.tmAveCharWidth==tmTmp.tmAveCharWidth);
  401.                     bDone = bDone && (tm.tmMaxCharWidth==tmTmp.tmMaxCharWidth);
  402.                     bDone = bDone && (tm.tmWeight==tmTmp.tmWeight);
  403.                     bDone = bDone && (tm.tmItalic==tmTmp.tmItalic);
  404.                     bDone = bDone && (tm.tmUnderlined==tmTmp.tmUnderlined);
  405.                     bDone = bDone && (tm.tmStruckOut==tmTmp.tmStruckOut);
  406.                     bDone = bDone && (tm.tmFirstChar==tmTmp.tmFirstChar);
  407.                     bDone = bDone && (tm.tmLastChar==tmTmp.tmLastChar);
  408.                     bDone = bDone && (tm.tmDefaultChar==tmTmp.tmDefaultChar);
  409.                     bDone = bDone && (tm.tmBreakChar==tmTmp.tmBreakChar);
  410.                     bDone = bDone && (tm.tmPitchAndFamily==tmTmp.tmPitchAndFamily);
  411.                     bDone = bDone && (tm.tmCharSet==tmTmp.tmCharSet);
  412.                     // Did it work?
  413.                     if (bDone) {
  414.                         *lplf = lfDlg;
  415.                         EndDialog(hwnd, TRUE);
  416.                         return (TRUE);
  417.                     } else {
  418.                         // We need to take a close look at the font verification
  419.                         // code. Currently, it sometimes will report that the
  420.                         // font didn't get properly selected, even if it did.
  421.                         *lplf = lfDlg;
  422.                         EndDialog(hwnd, TRUE);
  423.                         return (TRUE);
  424.  
  425.                         // This is what we want to do once we beef up the font
  426.                         // verification code:
  427.                         lfDlg = *lplf;
  428.                         MessageBox (GetFocus(),
  429.                             "Unable to re-create font from TextMetrics",
  430.                             "FontView", MB_OK);
  431.                     }
  432.                     break;
  433.  
  434.                 case IDCANCEL:
  435.                     EndDialog(hwnd, TRUE);
  436.                     return (TRUE);
  437.  
  438.             }
  439.             break;
  440.     }
  441.     return (FALSE);
  442.  
  443.     /* Just For Reference */
  444.     lParam;
  445. }
  446.  
  447.  
  448. BOOL FillEnumFields (HWND hwnd, int iType, LPTEXTMETRIC ptm, LPLOGFONT plf, int nBase)
  449. {
  450.             SetDlgItemValue (hwnd, TMD_HEIGHT, (int)ptm->tmHeight, TRUE, nBase);
  451.             SetDlgItemValue (hwnd, TMD_ASCENT, (int)ptm->tmAscent, TRUE, nBase);
  452.             SetDlgItemValue (hwnd, TMD_DESCENT, (int)ptm->tmDescent, TRUE, nBase);
  453.             SetDlgItemValue (hwnd, TMD_INTERNAL, (int)ptm->tmInternalLeading, TRUE, nBase);
  454.             SetDlgItemValue (hwnd, TMD_EXTERNAL, (int)ptm->tmExternalLeading, TRUE, nBase);
  455.             SetDlgItemValue (hwnd, TMD_AVEWIDTH, (int)ptm->tmAveCharWidth, TRUE, nBase);
  456.             SetDlgItemValue (hwnd, TMD_MAXWIDTH, (int)ptm->tmMaxCharWidth, TRUE, nBase);
  457.             SetDlgItemValue (hwnd, TMD_WEIGHT, (int)ptm->tmWeight, TRUE, nBase);
  458.             SetDlgItemValue (hwnd, TMD_ITALIC, (int)ptm->tmItalic, FALSE, nBase);
  459.             SetDlgItemValue (hwnd, TMD_UNDERLINE, (int)ptm->tmUnderlined, FALSE, nBase);
  460.             SetDlgItemValue (hwnd, TMD_STRUCKOUT, (int)ptm->tmStruckOut, FALSE, nBase);
  461.             SetDlgItemValue (hwnd, TMD_FIRSTCHAR, (int)ptm->tmFirstChar, FALSE, nBase);
  462.             SetDlgItemValue (hwnd, TMD_LASTCHAR, (int)ptm->tmLastChar, FALSE, nBase);
  463.             SetDlgItemValue (hwnd, TMD_DEFAULTCHAR, (int)ptm->tmDefaultChar, FALSE, nBase);
  464.             SetDlgItemValue (hwnd, TMD_BREAKCHAR, (int)ptm->tmBreakChar, FALSE, nBase);
  465.             SetDlgItemValue (hwnd, TMD_PITCHANDFAMILY, (int)ptm->tmPitchAndFamily, FALSE, nBase);
  466.             SetDlgItemValue (hwnd, TMD_CHARSET, (int)ptm->tmCharSet, FALSE, nBase);
  467.             SetDlgItemValue (hwnd, TMD_OVERHANG, (int)ptm->tmOverhang, TRUE, nBase);
  468.             SetDlgItemValue (hwnd, TMD_DIGITIZEDASPECTX, (int)ptm->tmDigitizedAspectX, TRUE, nBase);
  469.             SetDlgItemValue (hwnd, TMD_DIGITIZEDASPECTY, (int)ptm->tmDigitizedAspectY, TRUE, nBase);
  470.  
  471.             SetDlgItemValue (hwnd, CFD_HEIGHT, (int)plf->lfHeight, TRUE, nBase);
  472.             SetDlgItemValue (hwnd, CFD_WIDTH, (int)plf->lfWidth, TRUE, nBase);
  473.             SetDlgItemValue (hwnd, CFD_ESCAPEMENT, (int)plf->lfEscapement, TRUE, nBase);
  474.             SetDlgItemValue (hwnd, CFD_ORIENTATION, (int)plf->lfOrientation, TRUE, nBase);
  475.             SetDlgItemValue (hwnd, CFD_WEIGHT, (int)plf->lfWeight, FALSE, nBase);
  476.             SetDlgItemValue (hwnd, CFD_ITALIC, (int)plf->lfItalic, FALSE, nBase);
  477.             SetDlgItemValue (hwnd, CFD_UNDERLINE, (int)plf->lfUnderline, FALSE, nBase);
  478.             SetDlgItemValue (hwnd, CFD_STRIKEOUT, (int)plf->lfStrikeOut, FALSE, nBase);
  479.             SetDlgItemValue (hwnd, CFD_CHARSET, (int)plf->lfCharSet, FALSE, nBase);
  480.             SetDlgItemValue (hwnd, CFD_OUTPUTPRECISION, (int)plf->lfOutPrecision, FALSE, nBase);
  481.             SetDlgItemValue (hwnd, CFD_CLIPPRECISION, (int)plf->lfClipPrecision, FALSE, nBase);
  482.             SetDlgItemValue (hwnd, CFD_QUALITY, (int)plf->lfQuality, FALSE, nBase);
  483.             SetDlgItemValue (hwnd, CFD_PITCHANDFAMILY, (int)plf->lfPitchAndFamily, FALSE, nBase);
  484.             SetDlgItemText(hwnd, CFD_FACENAME, plf->lfFaceName);
  485.  
  486.             SetDlgItemValue (hwnd, ED_TYPE, (int)iType, FALSE, nBase);
  487.  
  488.             return TRUE;
  489. }
  490.  
  491.  
  492. BOOL DrawSample (HWND hwnd, LPLOGFONT plf)
  493. {
  494.     HFONT   hfont, hfontPrev;
  495.     HDC     hdc;
  496.     RECT    r;
  497.  
  498.     hfont = CreateFontIndirect (plf);
  499.     hdc = GetDC (hwnd);
  500.     hfontPrev = SelectObject (hdc, hfont);
  501.     GetWindowRect (hwnd, &r);
  502.     ScreenToClient (hwnd, (LPPOINT)&r.left);
  503.     ScreenToClient (hwnd, (LPPOINT)&r.right);
  504.  
  505.     Rectangle (hdc, r.left, r.top, r.right, r.bottom);
  506.  
  507.     InflateRect (&r, -1, -1);
  508.     SetTextAlign (hdc, TA_BOTTOM | TA_CENTER);
  509.     ExtTextOut (hdc, r.left + ((r.right-r.left)/2), r.bottom, ETO_CLIPPED, &r,"AaBbCcDdEe 012345", 17, NULL);
  510.  
  511.     SelectObject (hdc, hfontPrev);
  512.     DeleteObject (hfont);
  513.     ReleaseDC (hwnd, hdc);
  514.     return TRUE;
  515. }
  516.  
  517.  
  518. /*
  519.     Display a dialog that the user can use to enumerate through all of the fonts in the system.
  520.     Show him not only all of the metrics for the font, but a sample of the font as well.
  521.     If the user picks the 'Select' button, then the Metrics of this font will be used for
  522.     the CreateFont call.
  523. */
  524. BOOL APIENTRY EnumDlgProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  525. {
  526.     static HANDLE /*TO FONTLIST*/ hFonts;
  527.     static int iLoc=0;
  528.     static int count=0;
  529.     static BOOL bHex = FALSE;
  530.     static LOGFONT *lplf;
  531.     static LOGFONT lfDlg;
  532.     int wmId, i, j;
  533.     HANDLE hInst;
  534.     HWND   hwndItem;
  535.     HDC hdc;
  536.     FARPROC lpEnumFonts;
  537.     LPFONTLIST    pFL;
  538.     LPFONTSTRUCT  pFS;
  539.     char szTmp[80];
  540.     HFONT hfont, hfontPrev;
  541.     BOOL bDone;
  542.     TEXTMETRIC tmTmp;
  543.  
  544.  
  545.     switch (msg) {
  546.         case WM_INITDIALOG:
  547.             lplf = (LOGFONT *)lParam;
  548.             lfDlg = *lplf;
  549.             iLoc = 0;
  550.             count = 0;
  551.             bHex = FALSE;
  552.             /* First, lets enumerate ALL fonts, and store them in our list */
  553.             hFonts = GlobalAlloc (GHND, sizeof(FONTLIST));
  554.             if (hFonts) {
  555.  
  556. #if defined (WIN32)
  557.     hInst = (HANDLE)GetWindowLong (hwnd, GWL_HINSTANCE);
  558. #elif defined (WIN16)
  559.     hInst = (HANDLE)GetWindowWord (hwnd, GWW_HINSTANCE);
  560. #endif
  561.  
  562.                 lpEnumFonts = MakeProcInstance((FARPROC)DlgEnumFontNames, hInst);
  563.                 if (lpEnumFonts) {
  564.                     hdc  = GetDC(hwnd);
  565.                     // The enumeration function will lock down the handle
  566.                     EnumFonts (hdc, NULL, (FONTENUMPROC)lpEnumFonts, (LPARAM)&hFonts);
  567.                     // The handle will come back to us properly unlocked
  568.                     ReleaseDC(hwnd, hdc);
  569.                     FreeProcInstance (lpEnumFonts);
  570.  
  571.                  }
  572.             }
  573.             pFL = (LPFONTLIST)GlobalLock (hFonts);
  574.             if (pFL) {
  575.                 pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  576.                 if (pFS) {
  577.                     iLoc = 0;
  578.                     j = 100;
  579.                     for (i=0; i<pFL->count; i++) {
  580.                         if (lstrcmp(lfDlg.lfFaceName, pFS[i].lf.lfFaceName) == 0) {
  581.                             if (abs(lfDlg.lfHeight-pFS[i].lf.lfHeight) < j) {
  582.                                 j = abs(lfDlg.lfHeight-pFS[i].lf.lfHeight);
  583.                                 iLoc = i;
  584.                             }
  585.                         }
  586.                     }
  587.                     FillEnumFields (hwnd, pFS[iLoc].ft, &pFS[iLoc].tm, &pFS[iLoc].lf, (bHex?16:10));
  588.                     hwndItem = GetDlgItem (hwnd, ED_SAMPLE);
  589.                     DrawSample (hwndItem, &pFS[iLoc].lf);
  590.                     GlobalUnlock (pFL->hList);
  591.  
  592.                 }
  593.                 count = pFL->count;
  594.                 GlobalUnlock (hFonts);
  595.  
  596.             }
  597.             /* now fill in the dialog values */
  598.             wsprintf (szTmp, "EnumFonts %d of %d", iLoc+1, count);
  599.             SetWindowText (hwnd, szTmp);
  600.             CenterWindow (hwnd, GetWindow (hwnd, GW_OWNER));
  601.  
  602.             return TRUE;
  603.  
  604.         case WM_PAINT:
  605.             pFL = (LPFONTLIST)GlobalLock (hFonts);
  606.             if (pFL) {
  607.                 pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  608.                 if (pFS) {
  609.                     FillEnumFields (hwnd, pFS[iLoc].ft, &pFS[iLoc].tm, &pFS[iLoc].lf, (bHex?16:10));
  610.                     hwndItem = GetDlgItem (hwnd, ED_SAMPLE);
  611.                     DrawSample (hwndItem, &pFS[iLoc].lf);
  612.                     GlobalUnlock (pFL->hList);
  613.                 }
  614.                 GlobalUnlock (hFonts);
  615.             }
  616.             return 0;
  617.  
  618.         case WM_COMMAND:
  619. #if defined (WIN32)
  620.             wmId = LOWORD(wParam);
  621. #elif defined (WIN16)
  622.             wmId = wParam;
  623. #endif
  624.             switch (wmId) {
  625.  
  626.                 case ED_HEX:
  627.                     // Display the data in either Hex mode or Dec mode.
  628.                     bHex = !bHex;
  629.                     CheckDlgButton (hwnd, wmId, bHex);
  630.                     pFL = (LPFONTLIST)GlobalLock (hFonts);
  631.                     if (pFL) {
  632.                         pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  633.                         if (pFS) {
  634.                             FillEnumFields (hwnd, pFS[iLoc].ft, &pFS[iLoc].tm, &pFS[iLoc].lf, (bHex?16:10));
  635.                             if (GlobalUnlock (pFL->hList)) {
  636.                                 MessageBox (GetFocus(), "In HEX", "Unlock pFL->hList", MB_OK);
  637.                             }
  638.                         }
  639.                         if (GlobalUnlock (hFonts)) {
  640.                             MessageBox (GetFocus(), "In HEX", "Unlock hFonts", MB_OK);
  641.                         }
  642.  
  643.                     }
  644.                     break;
  645.  
  646.                 case ED_PREV:
  647.                     pFL = (LPFONTLIST)GlobalLock (hFonts);
  648.                     if (pFL) {
  649.                         if (iLoc > 0) {
  650.                             iLoc--;
  651.                             pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  652.                             if (pFS) {
  653.                                 FillEnumFields (hwnd, pFS[iLoc].ft, &pFS[iLoc].tm, &pFS[iLoc].lf, (bHex?16:10));
  654.                                 hwndItem = GetDlgItem (hwnd, ED_SAMPLE);
  655.                                 DrawSample (hwndItem, &pFS[iLoc].lf);
  656.                                 GlobalUnlock (pFL->hList);
  657.                             }
  658.                         }
  659.                         GlobalUnlock (hFonts);
  660.                     }
  661.                     wsprintf (szTmp, "EnumFonts %d of %d", iLoc+1, count);
  662.                     SetWindowText (hwnd, szTmp);
  663.                     break;
  664.  
  665.                 case ED_NEXT:
  666.                     pFL = (LPFONTLIST)GlobalLock (hFonts);
  667.                     if (pFL) {
  668.                         if ((pFL->count-1) > iLoc) {
  669.                             iLoc++;
  670.                             pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  671.                             if (pFS) {
  672.                                 FillEnumFields (hwnd, pFS[iLoc].ft, &pFS[iLoc].tm, &pFS[iLoc].lf, (bHex?16:10));
  673.                                 hwndItem = GetDlgItem (hwnd, ED_SAMPLE);
  674.                                 DrawSample (hwndItem, &pFS[iLoc].lf);
  675.                                 GlobalUnlock (pFL->hList);
  676.                             }
  677.  
  678.                         }
  679.                         GlobalUnlock (hFonts);
  680.                     }
  681.                     wsprintf (szTmp, "EnumFonts %d of %d", iLoc+1, count);
  682.                     SetWindowText (hwnd, szTmp);
  683.                     break;
  684.  
  685.                 case IDOK:
  686.                     // Copy the LOGFONT structure from the enumeration list, into our private LF
  687.                     pFL = (LPFONTLIST)GlobalLock (hFonts);
  688.                     bDone = FALSE;
  689.                     if (pFL) {
  690.                         if ((pFL->count-1) >= iLoc) {
  691.                             pFS = (LPFONTSTRUCT)GlobalLock (pFL->hList);
  692.                             if (pFS) {
  693.                                 lfDlg = pFS[iLoc].lf;
  694.  
  695.                     // Lets create a font with this new data
  696.                     hfont = CreateFontIndirect (&lfDlg);
  697.                     hdc = GetDC (hwnd);
  698.                     hfontPrev = SelectObject (hdc, hfont);
  699.                     GetTextMetrics (hdc, &tmTmp);
  700.                     // Get the face name
  701.                     GetTextFace    (hdc, sizeof(szTmp), szTmp);
  702.                     SelectObject (hdc, hfontPrev);
  703.                     DeleteObject (hfont);
  704.                     ReleaseDC (hwnd, hdc);
  705.  
  706.                     // And verify that we did indeed get the same font.
  707.                     bDone = TRUE;
  708.                     bDone = bDone && (pFS[iLoc].tm.tmHeight==tmTmp.tmHeight);
  709.                     bDone = bDone && (pFS[iLoc].tm.tmAscent==tmTmp.tmAscent);
  710.                     bDone = bDone && (pFS[iLoc].tm.tmDescent==tmTmp.tmDescent);
  711.                     bDone = bDone && (pFS[iLoc].tm.tmInternalLeading==tmTmp.tmInternalLeading);
  712.                     bDone = bDone && (pFS[iLoc].tm.tmExternalLeading==tmTmp.tmExternalLeading);
  713.                     bDone = bDone && (pFS[iLoc].tm.tmAveCharWidth==tmTmp.tmAveCharWidth);
  714.                     bDone = bDone && (pFS[iLoc].tm.tmMaxCharWidth==tmTmp.tmMaxCharWidth);
  715.                     bDone = bDone && (pFS[iLoc].tm.tmWeight==tmTmp.tmWeight);
  716.                     bDone = bDone && (pFS[iLoc].tm.tmItalic==tmTmp.tmItalic);
  717.                     bDone = bDone && (pFS[iLoc].tm.tmUnderlined==tmTmp.tmUnderlined);
  718.                     bDone = bDone && (pFS[iLoc].tm.tmStruckOut==tmTmp.tmStruckOut);
  719.                     bDone = bDone && (pFS[iLoc].tm.tmFirstChar==tmTmp.tmFirstChar);
  720.                     bDone = bDone && (pFS[iLoc].tm.tmLastChar==tmTmp.tmLastChar);
  721.                     bDone = bDone && (pFS[iLoc].tm.tmDefaultChar==tmTmp.tmDefaultChar);
  722.                     bDone = bDone && (pFS[iLoc].tm.tmBreakChar==tmTmp.tmBreakChar);
  723.                     bDone = bDone && (pFS[iLoc].tm.tmPitchAndFamily==tmTmp.tmPitchAndFamily);
  724.                     bDone = bDone && (pFS[iLoc].tm.tmCharSet==tmTmp.tmCharSet);
  725.                     // Did it work?
  726.                     if (bDone) {
  727.                         *lplf = lfDlg;
  728.                         //EndDialog(hwnd, TRUE);
  729.                         //return (TRUE);
  730.                     } else {
  731.                         // Again, font verification code is'nt quite up to
  732.                         // snuff yet, so just Select the font anyway:
  733.                         *lplf = lfDlg;
  734.  
  735.                         // ...and this is what we want to do once we fix the
  736.                         // font verification code:
  737.                         //lfDlg = *lplf;
  738.                         //MessageBox (GetFocus(),
  739.                         //    "Unable to re-create font from TextMetrics",
  740.                         //    "FontView", MB_OK);
  741.                     }
  742.  
  743.  
  744.                                 GlobalUnlock (pFL->hList);
  745.                             }
  746.                         }
  747.                         GlobalUnlock (hFonts);
  748.                     }
  749.  
  750.  
  751.                     // Now set our master lf to this value. This way, we 'could' verify that the
  752.                     // LOGFONT structure will in fact select this particular font, we just aren't yet
  753.                     // *lplf = lfDlg;
  754.  
  755.                     pFL = (LPFONTLIST)GlobalLock (hFonts);
  756.                     if (pFL) {
  757.                         if (GlobalFree (pFL->hList)) {
  758.                             MessageBox (GetFocus(), "Failed To Free", "pFL->hList", MB_OK);
  759.                         } else {
  760.                             GlobalUnlock (hFonts);
  761.                             if (GlobalFree (hFonts)) {
  762.                                 MessageBox (GetFocus(), "Failed To Free", "hFonts", MB_OK);
  763.                             }
  764.                         }
  765.                     }
  766.                     EndDialog(hwnd, TRUE);
  767.                     return (bDone);
  768.  
  769.                 case IDCANCEL:
  770.                     pFL = (LPFONTLIST)GlobalLock (hFonts);
  771.                     if (pFL) {
  772.                         if (GlobalFree (pFL->hList)) {
  773.                             MessageBox (GetFocus(), "Failed To Free", "pFL->hList", MB_OK);
  774.                         } else {
  775.                             GlobalUnlock (hFonts);
  776.                             if (GlobalFree (hFonts)) {
  777.                                 MessageBox (GetFocus(), "Failed To Free", "hFonts", MB_OK);
  778.                             }
  779.                         }
  780.                     }
  781.                     EndDialog(hwnd, TRUE);
  782.                     return (TRUE);
  783.             }
  784.             break;
  785.     }
  786.     return (FALSE);
  787.  
  788.     lParam; // unreferenced formal parameter
  789. }
  790.