home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 7.ddi / MWHC.007 / U4 < prev    next >
Encoding:
Text File  |  1991-10-23  |  16.8 KB  |  475 lines

  1. /*-----------------------------------------
  2.    FONTLIST.C -- Font Enumeration Program
  3.                  (c) Charles Petzold, 1990
  4.   -----------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <string.h>
  8. #include "fontlist.h"
  9.  
  10. typedef struct
  11.      {
  12.      GLOBALHANDLE hGMem ;
  13.      short        nCount ;
  14.      }
  15.      ENUMER;
  16.  
  17. typedef struct
  18.      {
  19.      short        nFontType ;
  20.      LOGFONT      lf ;
  21.      TEXTMETRIC   tm ;
  22.      }
  23.      FONT ;
  24.  
  25. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
  26.  
  27. #ifdef __HIGHC__
  28. typedef ENUMER lpFAR *LPENUMER ;
  29. typedef FONT lpFAR *LPFONT; 
  30.  
  31. int  FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, LPENUMER) ;
  32. int  FAR PASCAL EnumAllFonts (LPLOGFONT, LPTEXTMETRIC, short, LPENUMER) ;
  33. #else
  34. int  FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *) ;
  35. int  FAR PASCAL EnumAllFonts (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *) ;
  36. #endif
  37.  
  38. char szAppName[] = "FontList" ;
  39.  
  40. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  41.                     LPSTR lpszCmdLine, int nCmdShow)
  42.      {
  43.      HWND     hwnd ;
  44.      MSG      msg ;
  45.      WNDCLASS wndclass ;
  46.  
  47.      if (!hPrevInstance) 
  48.           {
  49.           wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  50.           wndclass.lpfnWndProc   = WndProc ;
  51.           wndclass.cbClsExtra    = 0 ;
  52.           wndclass.cbWndExtra    = 0 ;
  53.           wndclass.hInstance     = hInstance ;
  54.           wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  55.           wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  56.           wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
  57.           wndclass.lpszMenuName  = szAppName ;
  58.           wndclass.lpszClassName = szAppName ;
  59.  
  60.           RegisterClass (&wndclass) ;
  61.           }
  62.      hwnd = CreateWindow (szAppName, "Font Enumeration",
  63.                           WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  64.                           CW_USEDEFAULT, CW_USEDEFAULT,
  65.                           CW_USEDEFAULT, CW_USEDEFAULT,
  66.                           NULL, NULL, hInstance, NULL) ;
  67.  
  68.      ShowWindow (hwnd, nCmdShow) ;
  69.      UpdateWindow (hwnd) ;
  70.  
  71.      while (GetMessage (&msg, NULL, 0, 0))
  72.           {
  73.           TranslateMessage (&msg) ;
  74.           DispatchMessage (&msg) ;
  75.           }
  76.      return msg.wParam ;
  77.      }
  78.  
  79. int FAR PASCAL EnumAllFaces (LPLOGFONT lf, LPTEXTMETRIC tm,
  80. #ifdef __HIGHC__
  81.                              short nFontType, LPENUMER enumer)
  82. #else
  83.                              short nFontType, ENUMER FAR *enumer)
  84. #endif
  85.      {
  86.      LPSTR lpFaces ;
  87.  
  88.      if (NULL == GlobalReAlloc (enumer->hGMem,
  89.                          (DWORD) LF_FACESIZE * (1 + enumer->nCount),
  90.                          GMEM_MOVEABLE))
  91.           return 0 ;
  92.  
  93.      lpFaces = GlobalLock (enumer->hGMem) ;
  94.      lstrcpy (lpFaces + enumer->nCount * LF_FACESIZE, lf->lfFaceName) ;
  95.      GlobalUnlock (enumer->hGMem) ;
  96.      enumer->nCount ++ ;
  97.      return 1 ;
  98.      }
  99.  
  100. int FAR PASCAL EnumAllFonts (LPLOGFONT lf, LPTEXTMETRIC tm,
  101. #ifdef __HIGHC__
  102.                              short nFontType, LPENUMER enumer) {
  103.      LPFONT font ;
  104. #else
  105.                              short nFontType, ENUMER FAR *enumer) {
  106.      FONT FAR *font ;
  107. #endif
  108.  
  109.      if (NULL == GlobalReAlloc (enumer->hGMem,
  110.                          (DWORD) sizeof (FONT) * (1 + enumer->nCount),
  111.                          GMEM_MOVEABLE))
  112.           return 0 ;
  113.  
  114. #ifdef __HIGHC__
  115.      font = (LPFONT) GlobalLock (enumer->hGMem) + enumer->nCount ;
  116. #else
  117.      font = (FONT FAR *) GlobalLock (enumer->hGMem) + enumer->nCount ;
  118. #endif
  119.      font->nFontType = nFontType ;
  120.      font->lf = *lf ;
  121.      font->tm = *tm ;
  122.  
  123.      GlobalUnlock (enumer->hGMem) ;
  124.      enumer->nCount ++ ;
  125.      return 1 ;
  126.      }
  127.  
  128. #ifdef __HIGHC__
  129. void Display (HDC hdc, short cxChar, short cyChar, LPFONT font)
  130. #else
  131. void Display (HDC hdc, short cxChar, short cyChar, FONT FAR *font)
  132. #endif
  133.      {
  134.      static FONT f ;
  135.  
  136.      static char *szYN [] = { "No",         "Yes" } ;
  137.      static char *szCS [] = { "ANSI",       "?????",   "Kanji",    "OEM" } ;
  138.      static char *szOP [] = { "Default",    "String",  "Char",    "Stroke" } ;
  139.      static char *szCP [] = { "Default",    "Char",    "Stroke",   "?????" } ;
  140.      static char *szQU [] = { "Draft",      "Default", "Proof",    "?????" } ;
  141.      static char *szP1 [] = { "Default",    "Fixed",   "Variable", "?????" } ;
  142.      static char *szP2 [] = { "Fixed",      "Variable" } ;
  143.      static char *szFA [] = { "Don't Care", "Roman",      "Swiss", "Modern",
  144.                               "Script",     "Decorative", "?????", "?????" } ;
  145.      static char *szVR [] = { "Stroke",     "Raster" } ;
  146.      static char *szGD [] = { "GDI",        "Device" } ;
  147.  
  148.      static struct 
  149.           {
  150.           short x ;
  151.           short y ;
  152.           char  *szFmt ;
  153.           short *pData ;
  154.           }
  155.           shorts [] = 
  156.           {
  157.            1,  1, "LOGFONT",            NULL, 
  158.            1,  2, "-------",            NULL,
  159.            1,  3, "Height:      %10d",  &f.lf.lfHeight,
  160.            1,  4, "Width:       %10d",  &f.lf.lfWidth,
  161.            1,  5, "Escapement:  %10d",  &f.lf.lfEscapement,
  162.            1,  6, "Orientation: %10d",  &f.lf.lfOrientation,
  163.            1,  7, "Weight:      %10d",  &f.lf.lfWeight,
  164.           28,  1, "TEXTMETRIC",         NULL,
  165.           28,  2, "----------",         NULL,
  166.           28,  3, "Height:       %5d",  &f.tm.tmHeight,
  167.           28,  4, "Ascent:       %5d",  &f.tm.tmAscent,
  168.           28,  5, "Descent:      %5d",  &f.tm.tmDescent,
  169.           28,  6, "Int. Leading: %5d",  &f.tm.tmInternalLeading,
  170.           28,  7, "Ext. Leading: %5d",  &f.tm.tmExternalLeading,
  171.           28,  8, "Ave. Width:   %5d",  &f.tm.tmAveCharWidth,
  172.           28,  9, "Max. Width:   %5d",  &f.tm.tmMaxCharWidth,
  173.           28, 10, "Weight:       %5d",  &f.tm.tmWeight,
  174.           51, 10, "Overhang:     %10d", &f.tm.tmOverhang,
  175.           51, 11, "Digitized X:  %10d", &f.tm.tmDigitizedAspectX,
  176.           51, 12, "Digitized Y:  %10d", &f.tm.tmDigitizedAspectY
  177.           } ;
  178.  
  179.      static struct 
  180.           {
  181.           short x ;
  182.           short y ;
  183.           char  *szFmt ;
  184.           BYTE  *pData ;
  185.           }
  186.           bytes [] = 
  187.           {
  188.           51,  3, "First Char:   %10d", &f.tm.tmFirstChar,
  189.           51,  4, "Last Char:    %10d", &f.tm.tmLastChar,
  190.           51,  5, "Default Char: %10d", &f.tm.tmDefaultChar,
  191.           51,  6, "Break Char:   %10d", &f.tm.tmBreakChar
  192.           } ;
  193.  
  194.      static struct 
  195.           {
  196.           short x ;
  197.           short y ;
  198.           char  *szFmt ;
  199.           BYTE  *pData ;
  200.           char  **szArray ;
  201.           short sAnd ;
  202.           short sShift ;
  203.           }
  204.           strings [] = 
  205.           {
  206.            1,  8, "Italic:      %10s",  &f.lf.lfItalic,         szYN, 1,    0,
  207.            1,  9, "Underline:   %10s",  &f.lf.lfUnderline,      szYN, 1,    0,
  208.            1, 10, "Strike-Out:  %10s",  &f.lf.lfStrikeOut,      szYN, 1,    0,
  209.            1, 11, "Char Set:    %10s",  &f.lf.lfCharSet,        szCS, 0xC0, 6,
  210.            1, 12, "Out  Prec:   %10s",  &f.lf.lfOutPrecision,   szOP, 3,    0,
  211.            1, 13, "Clip Prec:   %10s",  &f.lf.lfClipPrecision,  szCP, 3,    0, 
  212.            1, 14, "Quality:     %10s",  &f.lf.lfQuality,        szQU, 3,    0,
  213.            1, 15, "Pitch:       %10s",  &f.lf.lfPitchAndFamily, szP1, 3,    0,
  214.            1, 16, "Family:      %10s",  &f.lf.lfPitchAndFamily, szFA, 0x70, 4,
  215.           28, 11, "Italic:       %5s",  &f.tm.tmItalic,         szYN, 1,    0,
  216.           28, 12, "Underline:    %5s",  &f.tm.tmUnderlined,     szYN, 1,    0,
  217.           28, 13, "Strike-Out:   %5s",  &f.tm.tmStruckOut,      szYN, 1,    0,
  218.           51,  7, "Pitch:        %10s", &f.tm.tmPitchAndFamily, szP2, 1,    0,
  219.           51,  8, "Family:       %10s", &f.tm.tmPitchAndFamily, szFA, 0x70, 4,
  220.           51,  9, "Char Set:     %10s", &f.tm.tmCharSet,        szCS, 0xC0, 6,
  221.           36, 15, "Font Type:  %6s",    (BYTE *) &f.nFontType,  szVR, 1,    0,
  222.           55, 15, "%s",                 (BYTE *) &f.nFontType,  szGD, 2,    1
  223.           } ;
  224.     
  225.      char szBuffer [80] ;
  226.      int  i ;
  227.  
  228.      f = *font ;
  229.  
  230.      for (i = 0 ; i < sizeof shorts / sizeof shorts [0] ; i++)
  231.           TextOut (hdc, cxChar * shorts[i].x, cyChar * shorts[i].y, szBuffer,
  232.                    wsprintf (szBuffer, shorts[i].szFmt,
  233.                              *shorts[i].pData)) ;
  234.  
  235.      for (i = 0 ; i < sizeof bytes / sizeof bytes [0] ; i++)
  236.           TextOut (hdc, cxChar * bytes[i].x, cyChar * bytes[i].y, szBuffer,
  237.                    wsprintf (szBuffer, bytes[i].szFmt,
  238.                              *bytes[i].pData)) ;
  239.  
  240.      for (i = 0 ; i < sizeof strings / sizeof strings [0] ; i++)
  241.           TextOut (hdc, cxChar * strings[i].x, cyChar * strings[i].y, szBuffer,
  242.                    wsprintf (szBuffer, strings[i].szFmt,
  243. #ifdef __HIGHC__
  244.                              (LPSTR) ((strings[i].szArray)
  245. #else
  246.                              (PSTR) ((strings[i].szArray)
  247. #endif
  248.                                   [(*strings[i].pData & strings[i].sAnd) >>
  249.  
  250.                                         strings[i].sShift]))) ;
  251.  
  252.      TextOut (hdc, cxChar, cyChar * 17, szBuffer,
  253.               wsprintf (szBuffer, "Face Name:   %10s",
  254. #ifdef __HIGHC__
  255.                         (LPSTR) f.lf.lfFaceName)) ;
  256. #else
  257.                         (PSTR) f.lf.lfFaceName)) ;
  258. #endif
  259.      }
  260.  
  261. HDC GetPrinterIC ()
  262.      {
  263.      char szPrinter [64] ;
  264.      char *szDevice, *szDriver, *szOutput ;
  265.  
  266.      GetProfileString ("windows", "device", "", szPrinter, 64) ;
  267.  
  268.      if ((szDevice = strtok (szPrinter, "," )) &&
  269.          (szDriver = strtok (NULL,      ", ")) && 
  270.          (szOutput = strtok (NULL,      ", ")))
  271.           
  272.                return CreateIC (szDriver, szDevice, szOutput, NULL) ;
  273.  
  274.      return NULL ;
  275.      }
  276.  
  277. long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  278.      {
  279.      static BOOL    bHaveInfo = FALSE ;
  280.      static ENUMER  enumer1, enumer2 ;
  281.      static FARPROC lpfnEnumAllFaces, lpfnEnumAllFonts ;
  282.      static short   cxChar, cyChar, nCurrent ;
  283.      static WORD    wCurrentDC = IDM_SCREEN ;
  284.      HANDLE         hInstance ;
  285.      HDC            hdc ;
  286.      HFONT          hFont ;
  287.      HMENU          hMenu ;
  288. #ifdef __HIGHC__
  289.      LPFONT         font ;
  290. #else
  291.      FONT FAR       *font ;
  292. #endif
  293.      LPSTR          lpFaces ;
  294.      PAINTSTRUCT    ps ;
  295.      short          i ;
  296.      TEXTMETRIC     tm ;
  297.  
  298.      switch (message)
  299.           {
  300.           case WM_CREATE:
  301.                hInstance = ((LPCREATESTRUCT) lParam)-> hInstance ;
  302.                lpfnEnumAllFaces = MakeProcInstance (EnumAllFaces, hInstance) ;
  303.                lpfnEnumAllFonts = MakeProcInstance (EnumAllFonts, hInstance) ;
  304.  
  305.                hdc = GetDC (hwnd) ;
  306.                SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  307.  
  308.                GetTextMetrics (hdc, (LPTEXTMETRIC) &tm) ;
  309.                cxChar = tm.tmAveCharWidth ;
  310.                cyChar = tm.tmHeight + tm.tmExternalLeading ;
  311.  
  312.                ReleaseDC (hwnd, hdc) ;
  313.                return 0 ;
  314.                               
  315.           case WM_COMMAND:
  316.                if (wParam == IDM_EXIT)
  317.                     {
  318.                     SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
  319.                     return 0 ;
  320.                     }
  321.                else if (wParam == wCurrentDC)
  322.                     return 0 ;
  323.  
  324.                hMenu = GetMenu (hwnd) ;
  325.                CheckMenuItem (hMenu, wCurrentDC, MF_UNCHECKED) ;
  326.                CheckMenuItem (hMenu, wCurrentDC = wParam, MF_CHECKED) ;
  327.  
  328.                                         // fall through
  329.  
  330.           case WM_DEVMODECHANGE:
  331.           case WM_FONTCHANGE:
  332.                bHaveInfo = FALSE ;               
  333.                InvalidateRect (hwnd, NULL, TRUE) ;
  334.                return 0 ;
  335.  
  336.           case WM_PAINT:
  337.                if (!bHaveInfo)
  338.                     {
  339.                     if (enumer2.hGMem)
  340.                          GlobalFree (enumer2.hGMem) ;
  341.  
  342.                     enumer1.hGMem  = GlobalAlloc (GHND, 1L) ;
  343.                     enumer1.nCount = 0 ;
  344.  
  345.                     enumer2.hGMem  = GlobalAlloc (GHND, 1L) ;
  346.                     enumer2.nCount = 0 ;
  347.  
  348.                     if (NULL == enumer1.hGMem || NULL == enumer2.hGMem)
  349.                          goto MEMORY_ERROR ;
  350.  
  351.                     if (wCurrentDC == IDM_SCREEN)
  352.                          hdc = CreateIC ("DISPLAY", NULL, NULL, NULL) ;
  353.                     else
  354.                          hdc = GetPrinterIC () ;
  355.  
  356.                     if (hdc)
  357.                          {
  358.                          if (0 == EnumFonts (hdc, NULL, lpfnEnumAllFaces,
  359.                                                   (LPSTR) &enumer1))
  360.                               goto MEMORY_ERROR ;
  361.  
  362.                          lpFaces = GlobalLock (enumer1.hGMem) ;
  363.  
  364.                          for (i = 0 ; i < enumer1.nCount ; i++)
  365.                               if (0 == EnumFonts (hdc,
  366.                                              lpFaces + i * LF_FACESIZE,
  367.                                              lpfnEnumAllFonts,
  368.                                              (LPSTR) &enumer2))
  369.                                    goto MEMORY_ERROR ;
  370.  
  371.                          GlobalUnlock (enumer1.hGMem) ;
  372.                          enumer2.nCount-- ;
  373.      
  374.                          DeleteDC (hdc) ;
  375.                          bHaveInfo = TRUE ;
  376.                          }
  377.                     GlobalFree (enumer1.hGMem) ;
  378.                     SetScrollRange (hwnd, SB_VERT, 0, enumer2.nCount, FALSE) ;
  379.                     SetScrollPos   (hwnd, SB_VERT, nCurrent = 0, TRUE) ;
  380.                     }
  381.  
  382.                hdc = BeginPaint (hwnd, &ps) ;
  383.  
  384.                if (bHaveInfo)
  385.                     {
  386.                     SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  387.  
  388. #ifdef __HIGHC__
  389.                     font = (LPFONT) GlobalLock (enumer2.hGMem) + nCurrent ;
  390. #else
  391.                     font = (FONT FAR *) GlobalLock (enumer2.hGMem) + nCurrent ;
  392. #endif
  393.                     Display (hdc, cxChar, cyChar, font) ;
  394.  
  395.                     hFont = SelectObject (hdc, CreateFontIndirect (&font->lf));
  396.  
  397.                     TextOut (hdc, 1 * cxChar, 19 * cyChar,
  398.                         "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
  399.                          52) ;
  400.  
  401.                     GlobalUnlock (enumer2.hGMem) ;
  402.                     DeleteObject (SelectObject (hdc, hFont)) ;
  403.                     }
  404.  
  405.                EndPaint (hwnd, &ps) ;
  406.                return 0 ;
  407.  
  408.           case WM_KEYDOWN:
  409.                switch (wParam)
  410.                     {
  411.                     case VK_HOME:
  412.                          SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0L) ;
  413.                          break ;
  414.                     case VK_END:
  415.                          SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0L) ;
  416.                          break ;
  417.                     case VK_LEFT:
  418.                     case VK_UP:
  419.                     case VK_PRIOR:
  420.                          SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0L) ;
  421.                          break ;
  422.                     case VK_RIGHT:
  423.                     case VK_DOWN:
  424.                     case VK_NEXT:
  425.                          SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN, 0L) ;
  426.                          break ;
  427.                     default:
  428.                          return 0 ;
  429.                     }
  430.                return 0 ;
  431.  
  432.           case WM_VSCROLL:
  433.                switch (wParam)
  434.                     {
  435.                     case SB_TOP:
  436.                          nCurrent = 0 ;
  437.                          break ;
  438.                     case SB_BOTTOM:
  439.                          nCurrent = enumer2.nCount ;
  440.                          break ;
  441.                     case SB_LINEUP:
  442.                     case SB_PAGEUP:
  443.                          nCurrent -- ;
  444.                          break ;
  445.                     case SB_LINEDOWN:
  446.                     case SB_PAGEDOWN:
  447.                          nCurrent ++ ;
  448.                          break ;
  449.                     case SB_THUMBPOSITION:
  450.                          nCurrent = LOWORD (lParam) ;
  451.                          break ;
  452.                     default:
  453.                          return 0 ;
  454.                     }
  455.                nCurrent = min (max (0, nCurrent), enumer2.nCount) ;
  456.                SetScrollPos (hwnd, SB_VERT, nCurrent, TRUE) ;
  457.                InvalidateRect (hwnd, NULL, TRUE) ;
  458.                return 0 ;
  459.  
  460.           MEMORY_ERROR:
  461.                MessageBox (hwnd, "Cannot allocate memory, must end.",
  462.                     szAppName, MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL) ;
  463.  
  464.                                              // fall through
  465.           case WM_CLOSE:
  466.                DestroyWindow (hwnd) ;
  467.                return 0 ;
  468.  
  469.           case WM_DESTROY:
  470.                PostQuitMessage (0) ;
  471.                return 0 ;
  472.           }
  473.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  474.      }
  475.