/* FONTLIST.C - Font Enumeration Program */ #include #include #include #include "winundoc.h" #include "fontlist.h" typedef struct { GLOBALHANDLE hGMem; short nCount; } ENUMER; typedef struct { short nFontType; LOGFONT lf; TEXTMETRIC tm; } FONT; long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG); int FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *); int FAR PASCAL EnumAllFonts (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *); char szAppName [] = "FontList"; int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow) HANDLE hInstance, hPrevInstance; LPSTR lpszCmdLine; /* command line */ int nCmdShow; /* show-window type (open/icon) */ { HWND hWnd; /* window handle */ MSG msg; /* message */ WNDCLASS wndclass; if (!hPrevInstance) { wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (!RegisterClass (&wndclass)) return FALSE; } hWnd = CreateWindow (szAppName, "Font Enumeration", WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); ShowWindow (hWnd, nCmdShow); /* Shows the window */ UpdateWindow (hWnd); /* Sends WM_PAINT message */ while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); /* Translates virtual key codes */ DispatchMessage (&msg); /* Dispatches message to window */ } return msg.wParam; /* Returns the value from PostQuitMessage */ } int FAR PASCAL EnumAllFaces (lf, tm, nFontType, enumer) LPLOGFONT lf; LPTEXTMETRIC tm; short nFontType; ENUMER FAR * enumer; { LPSTR lpFaces; if (NULL == GlobalReAlloc (enumer->hGMem, (DWORD) LF_FACESIZE * (1 + enumer->nCount), GMEM_MOVEABLE)) return 0; lpFaces = GlobalLock (enumer->hGMem); lstrcpy (lpFaces + enumer->nCount * LF_FACESIZE, lf->lfFaceName); GlobalUnlock (enumer->hGMem); enumer->nCount ++; return 1; } int FAR PASCAL EnumAllFonts (lf, tm, nFontType, enumer) LPLOGFONT lf; LPTEXTMETRIC tm; short nFontType; ENUMER FAR * enumer; { FONT FAR * font; if (NULL == GlobalReAlloc (enumer->hGMem, (DWORD) sizeof (FONT) * (1 + enumer->nCount), GMEM_MOVEABLE)) return 0; font = (FONT FAR *) GlobalLock (enumer->hGMem) + enumer->nCount; font->nFontType = nFontType; font->lf = *lf; font->tm = *tm; GlobalUnlock (enumer->hGMem); enumer->nCount ++; return 1; } void Display (hDC, xChar, yChar, font) HDC hDC; short xChar, yChar; FONT FAR * font; { static FONT f; static char *szYN [] = { "No", "Yes"}; static char *szCS [] = { "ANSI", "?????", "Kanji", "OEM"}; static char *szOP [] = { "Default", "String", "Char", "Stroke"}; static char *szCP [] = { "Default", "Char", "Stroke", "?????"}; static char *szQU [] = { "Draft", "Default", "Proof", "?????"}; static char *szP1 [] = { "Default", "Fixed", "Variable", "?????"}; static char *szP2 [] = { "Fixed", "Variable"}; static char *szFA [] = { "Don't Care", "Roman", "Swiss", "Modern", "Script", "Decorative", "?????", "?????"}; static char *szVR [] = { "Vector", "Raster"}; static char *szGD [] = { "GDI", "Device"}; static struct { short x; short y; char *szFmt; short *pData; } shorts [] = { 1, 1, "LOGFONT", NULL, 1, 2, "-------", NULL, 1, 3, "Height: %10d", &f.lf.lfHeight, 1, 4, "Width: %10d", &f.lf.lfWidth, 1, 5, "Escapement: %10d", &f.lf.lfEscapement, 1, 6, "Orientation: %10d", &f.lf.lfOrientation, 1, 7, "Weight: %10d", &f.lf.lfWeight, 28, 1, "TEXTMETRIC", NULL, 28, 2, "----------", NULL, 28, 3, "Height: %5d", &f.tm.tmHeight, 28, 4, "Ascent: %5d", &f.tm.tmAscent, 28, 5, "Descent: %5d", &f.tm.tmDescent, 28, 6, "Int. Leading: %5d", &f.tm.tmInternalLeading, 28, 7, "Ext. Leading: %5d", &f.tm.tmExternalLeading, 28, 8, "Ave. Width: %5d", &f.tm.tmAveCharWidth, 28, 9, "Max. Width %5d", &f.tm.tmMaxCharWidth, 28, 10, "Weight: %5d", &f.tm.tmWeight, 51, 10, "Overhang: %10d", &f.tm.tmOverhang, 51, 11, "Digitized X: %10d", &f.tm.tmDigitizedAspectX, 51, 12, "Digitized Y: %10d", &f.tm.tmDigitizedAspectY }; static struct { short x; short y; char *szFmt; BYTE *pData; } bytes [] = { 51, 3, "First Char: %10d", &f.tm.tmFirstChar, 51, 4, "Last Char: %10d", &f.tm.tmLastChar, 51, 5, "Default Char: %10d", &f.tm.tmDefaultChar, 51, 6, "Break Char: %10d", &f.tm.tmBreakChar, }; static struct { short x; short y; char *szFmt; BYTE *pData; char **szArray; short sAnd; short sShift; } strings [] = { 1, 8, "Italic: %10s", &f.lf.lfItalic, szYN, 1, 0, 1, 9, "Underline: %10s", &f.lf.lfUnderline, szYN, 1, 0, 1,10, "Strike-Out: %10s", &f.lf.lfStrikeOut, szYN, 1, 0, 1,11, "Char Set: %10s", &f.lf.lfCharSet, szCS, 0xc0, 6, 1,12, "Out Prec: %10s", &f.lf.lfOutPrecision, szOP, 3, 0, 1,13, "Clip Prec: %10s", &f.lf.lfClipPrecision, szCP, 3, 0, 1,14, "Quality: %10s", &f.lf.lfQuality, szQU, 3, 0, 1,15, "Pitch: %10s", &f.lf.lfPitchAndFamily, szP1, 3, 0, 1,16, "Family: %10s", &f.lf.lfPitchAndFamily, szFA, 0x70, 4, 28,11, "Italic: %5s", &f.tm.tmItalic, szYN, 1, 0, 28,12, "Underline: %5s", &f.tm.tmUnderlined, szYN, 1, 0, 28,13, "Strike-Out %5s", &f.tm.tmStruckOut, szYN, 1, 0, 51, 7, "Pitch: %10s", &f.tm.tmPitchAndFamily, szP2, 1, 0, 51, 8, "Family: %10s", &f.tm.tmPitchAndFamily, szFA, 0x70, 4, 51, 9, "Char Set: %10s", &f.tm.tmCharSet, szCS, 0xc0, 6, 36,15, "Font Type: %6s", (BYTE *) &f.nFontType, szVR, 1, 0, 55,15, "%s", (BYTE *) &f.nFontType, szGD, 2, 1 }; char szBuffer [80]; int i; f = *font; for (i = 0; i < sizeof shorts / sizeof shorts [0]; i++) TextOut (hDC, xChar * shorts[i].x, yChar * shorts[i].y, szBuffer, sprintf (szBuffer, shorts[i].szFmt, *shorts[i].pData)); for (i = 0; i < sizeof bytes / sizeof bytes [0]; i++) TextOut (hDC, xChar * bytes[i].x, yChar * bytes[i].y, szBuffer, sprintf (szBuffer, bytes[i].szFmt, *bytes[i].pData)); for (i = 0; i < sizeof strings / sizeof strings [0]; i++) TextOut (hDC, xChar * strings[i].x, yChar * strings[i].y, szBuffer, sprintf (szBuffer, strings[i].szFmt, (strings[i].szArray) [(*strings[i].pData & strings[i].sAnd) >> strings[i].sShift])); TextOut (hDC, xChar, yChar * 17, szBuffer, sprintf (szBuffer, "Face Name: %10s", f.lf.lfFaceName)); } HDC GetPrinterIC () { char szPrinter [64]; char *szDevice, *szDriver, *szOutput; GetProfileString ("windows", "device", "", szPrinter, 64); if ((szDevice = strtok (szPrinter, ",")) && (szDriver = strtok (NULL, ", ")) && (szOutput = strtok (NULL, ", "))) return CreateIC(szDriver, szDevice, szOutput, NULL); return NULL; } long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam) HWND hWnd; /* window handle */ unsigned iMessage; /* type of message */ WORD wParam; /* additional information */ LONG lParam; /* additional information */ { static BOOL bHaveInfo = FALSE; static ENUMER enumer1, enumer2; static FARPROC lpfnEnumAllFaces, lpfnEnumAllFonts; static short xChar, yChar, nCurrent; static WORD wCurrentDC = IDM_SCREEN; HANDLE hInstance; HDC hDC; HFONT hFont; HMENU hMenu; FONT FAR *font; LPSTR lpFaces; PAINTSTRUCT ps; short i; TEXTMETRIC tm; switch (iMessage) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam)->hInstance; lpfnEnumAllFaces = MakeProcInstance (EnumAllFaces, hInstance); lpfnEnumAllFonts = MakeProcInstance (EnumAllFonts, hInstance); hDC = GetDC (hWnd); GetTextMetrics (hDC, (LPTEXTMETRIC) &tm); xChar = tm.tmAveCharWidth; yChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC (hWnd, hDC); break; case WM_COMMAND: if (wParam == IDM_EXIT) { SendMessage (hWnd, WM_CLOSE, 0, 0L); break; } else if (wParam == wCurrentDC) break; hMenu = GetMenu (hWnd); CheckMenuItem (hMenu, wCurrentDC, MF_UNCHECKED); CheckMenuItem (hMenu, wCurrentDC = wParam, MF_CHECKED); /* NO break - fall through */ case WM_DEVMODECHANGE: case WM_FONTCHANGE: bHaveInfo = FALSE; InvalidateRect (hWnd, NULL, TRUE); break; case WM_PAINT: if (!bHaveInfo) { if (enumer2.hGMem) GlobalFree (enumer2.hGMem); enumer1.hGMem = GlobalAlloc (GHND, 1L); enumer1.nCount = 0; enumer2.hGMem = GlobalAlloc (GHND, 1L); enumer2.nCount = 0; if (NULL == enumer1.hGMem || NULL == enumer2.hGMem) goto MEMORY_ERROR; if (wCurrentDC == IDM_SCREEN) hDC = CreateIC ("DISPLAY", NULL, NULL, NULL); else hDC = GetPrinterIC (); if (hDC) { if (0 == EnumFonts (hDC, NULL, lpfnEnumAllFaces, (LPSTR) &enumer1)) goto MEMORY_ERROR; lpFaces = GlobalLock (enumer1.hGMem); for (i = 0; i < enumer1.nCount; i++) if (0 == EnumFonts (hDC, lpFaces + 1 * LF_FACESIZE, lpfnEnumAllFonts, (LPSTR) &enumer2)) goto MEMORY_ERROR; GlobalUnlock (enumer1.hGMem); enumer2.nCount--; DeleteDC (hDC); bHaveInfo = TRUE; } GlobalFree (enumer1.hGMem); SetScrollRange (hWnd, SB_VERT, 0, enumer2.nCount, FALSE); SetScrollPos (hWnd, SB_VERT, nCurrent = 0, TRUE); } hDC = BeginPaint (hWnd, &ps); if (bHaveInfo) { font = (FONT FAR *) GlobalLock (enumer2.hGMem) + nCurrent; Display (hDC, xChar, yChar, font); hFont = SelectObject (hDC, CreateFontIndirect (&font->lf)); TextOut (hDC, 1 * xChar, 19 * yChar, "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", 52); GlobalUnlock (enumer2.hGMem); DeleteObject (SelectObject (hDC, hFont)); } EndPaint (hWnd, &ps); break; case WM_KEYDOWN: switch (wParam) { case VK_HOME: SendMessage (hWnd, WM_VSCROLL, SB_TOP, 0L); break; case VK_END: SendMessage (hWnd, WM_VSCROLL, SB_BOTTOM, 0L); break; case VK_LEFT: case VK_UP: case VK_PRIOR: SendMessage (hWnd, WM_VSCROLL, SB_LINEUP, 0L); break; case VK_RIGHT: case VK_DOWN: case VK_NEXT: SendMessage (hWnd, WM_VSCROLL, SB_LINEDOWN, 0L); break; } break; case WM_VSCROLL: switch (wParam) { case SB_TOP: nCurrent = 0; break; case SB_BOTTOM: nCurrent = enumer2.nCount; break; case SB_LINEUP: case SB_PAGEUP: nCurrent--; break; case SB_LINEDOWN: case SB_PAGEDOWN: nCurrent++; break; case SB_THUMBPOSITION: nCurrent = LOWORD (lParam); break; default: return 0L; } nCurrent = min (max (0, nCurrent), enumer2.nCount); SetScrollPos (hWnd, SB_VERT, nCurrent, TRUE); InvalidateRect (hWnd, NULL, TRUE); break; MEMORY_ERROR: MessageBox (hWnd, "Cannot allocate memory, must end.", szAppName, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL); /* NO break - fall through */ case WM_CLOSE: DestroyWindow (hWnd); break; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (hWnd, iMessage, wParam, lParam); } return 0L; }