Перечисление установленных шрифтов

В некоторых случаях приложение должно иметь возможность перечислить доступные шрифты и выбрать наиболее подходящий для конкретной операции. Приложение может перечислить доступные шрифты, вызвав функцию EnumFonts или EnumFontFamilies . Эти функции отправляют сведения о доступных шрифтах в функцию обратного вызова, которую предоставляет приложение. Функция обратного вызова получает сведения в структурах LOGFONT и NEWTEXTMETRIC . (Структура NEWTEXTMETRIC содержит сведения о шрифте TrueType. Когда функция обратного вызова получает сведения о шрифте, отличном от TrueType, эти сведения содержатся в структуре TEXTMETRIC .) Используя эти сведения, приложение может ограничить выбор пользователем только теми шрифтами, которые доступны.

Функция EnumFontFamilies аналогична функции EnumFonts, но включает некоторые дополнительные функции. EnumFontFamilies позволяет приложению использовать преимущества стилей, доступных со шрифтами TrueType. Новые и обновленные приложения должны использовать EnumFontFamilies вместо EnumFonts.

Шрифты TrueType организованы вокруг имени шрифта (например, Courier New) и имен стилей (например, курсивного, полужирного и экстра-полужирного). Функция EnumFontFamilies перечисляет все стили, связанные с указанным именем семейства, а не просто полужирные и курсивные атрибуты. Например, если система содержит шрифт TrueType с именем Courier New Extra-Bold, EnumFontFamilies перечисляет его вместе с другими шрифтами Courier New. Возможности EnumFontFamilies полезны для шрифтов с различными или необычными стилями, а также для шрифтов, которые пересекают международные границы.

Если приложение не предоставляет имя шрифта, функции EnumFonts и EnumFontFamilies предоставляют сведения об одном шрифте в каждом доступном семействе. Чтобы перечислить все шрифты в контексте устройства, приложение может указать null для имени шрифта, скомпилировать список доступных шрифтов, а затем перечислить каждый шрифт в каждом шрифте.

В следующем примере функция EnumFontFamilies используется для получения количества доступных семейств растровых, векторных и TrueType.

    UINT uAlignPrev; 
    int aFontCount[] = { 0, 0, 0 }; 
    char szCount[8];
        HRESULT hr;
        size_t * pcch; 
 
    EnumFontFamilies(hdc, (LPCTSTR) NULL, 
        (FONTENUMPROC) EnumFamCallBack, (LPARAM) aFontCount); 
 
    uAlignPrev = SetTextAlign(hdc, TA_UPDATECP); 
 
    MoveToEx(hdc, 10, 50, (LPPOINT)NULL); 
    TextOut(hdc, 0, 0, "Number of raster fonts: ", 24); 
    itoa(aFontCount[0], szCount, 10); 
        
        hr = StringCchLength(szCount, 9, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }
    TextOut(hdc, 0, 0, szCount, *pcch); 
 
    MoveToEx(hdc, 10, 75, (LPPOINT)NULL); 
    TextOut(hdc, 0, 0, "Number of vector fonts: ", 24); 
    itoa(aFontCount[1], szCount, 10);
        hr = StringCchLength(szCount, 9, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        } 
    TextOut(hdc, 0, 0, szCount, *pcch); 
 
    MoveToEx(hdc, 10, 100, (LPPOINT)NULL); 
    TextOut(hdc, 0, 0, "Number of TrueType fonts: ", 26); 
    itoa(aFontCount[2], szCount, 10);
        hr = StringCchLength(szCount, 9, pcch);
        if (FAILED(hr))
        {
        // TODO: write error handler 
        }
    TextOut(hdc, 0, 0, szCount, *pcch); 
 
    SetTextAlign(hdc, uAlignPrev); 
 
BOOL CALLBACK EnumFamCallBack(LPLOGFONT lplf, LPNEWTEXTMETRIC lpntm, DWORD FontType, LPVOID aFontCount) 
{ 
    int far * aiFontCount = (int far *) aFontCount; 
 
    // Record the number of raster, TrueType, and vector  
    // fonts in the font-count array.  
 
    if (FontType & RASTER_FONTTYPE) 
        aiFontCount[0]++; 
    else if (FontType & TRUETYPE_FONTTYPE) 
        aiFontCount[2]++; 
    else 
        aiFontCount[1]++; 
 
    if (aiFontCount[0] || aiFontCount[1] || aiFontCount[2]) 
        return TRUE; 
    else 
        return FALSE; 
 
    UNREFERENCED_PARAMETER( lplf ); 
    UNREFERENCED_PARAMETER( lpntm ); 
} 

В этом примере используются две маски, RASTER_FONTTYPE и TRUETYPE_FONTTYPE, чтобы определить тип перечисляемого шрифта. Если задан бит RASTER_FONTTYPE, шрифт будет растровый. Если задан бит TRUETYPE_FONTTYPE, шрифт будет шрифтом TrueType. Если ни бит не задан, шрифт является векторным. Третья маска, DEVICE_FONTTYPE, устанавливается, если устройство (например, лазерный принтер) поддерживает скачивание шрифтов TrueType; значение равно нулю, если устройство является видеоадаптером, принтером точечной матрицы или другим растром. Приложение также может использовать маску DEVICE_FONTTYPE, чтобы отличать растровые шрифты, предоставляемые GDI, от шрифтов, предоставляемых устройством. Система может имитировать полужирные, курсивные атрибуты, подчеркивания и зачеркивающие атрибуты для растровых шрифтов, предоставляемых GDI, но не для шрифтов, предоставляемых устройством.

Приложение также может проверка биты 1 и 2 в элементе tmPitchAndFamily структуры NEWTEXTMETRIC, чтобы определить шрифт TrueType. Если бит 1 равен 0, а бит 2 равен 1, шрифт будет шрифтом TrueType.

Векторные шрифты классифицируются как OEM_CHARSET, а не ANSI_CHARSET. Некоторые приложения определяют векторные шрифты, используя эти сведения, проверяя элемент tmCharSet структуры NEWTEXTMETRIC . Такая классификация обычно не позволяет средству сопоставления шрифтов выбирать векторные шрифты, если они не запрашиваются специально. (В большинстве приложений больше не используются векторные шрифты, так как их штрихи являются одиночными линиями, а рисование занимает больше времени, чем шрифты TrueType, которые предлагают те же функции масштабирования и поворота, которые требуют векторных шрифтов.)