Продолжение. Начало см. в # 5, 6, 7/97.
Занятие четвертое
Дмитрий РамодинШрифты и пути
Итак, мы снова встретились с вами, чтобы продолжить изучение таинственных дебрей Windows API. На этом занятии вы научитесь узнавать шрифты, установленные в вашей операционной системе, и управлять их появлением на экране. Вы также узнаете, как создаются пути - еще один интересный графический объект ОС Windows.
Прежде всего выясним, что же такое шрифт. Это набор символов одного дизайна, отображающих текстовую и прочую символьную информацию на экране дисплея или на принтере. Первое, с чем вы встретитесь, это название шрифта (typeface). Многие наверняка используют в своих документах шрифты с названиями Times New Roman или Arial. Важной характеристикой шрифта является стиль (style):
Допускается комбинирование стилей. Так, можно выбрать, скажем, жирный курсив.
Шрифты, обладающие общими принципами начертания, принадлежат одному из семейств (Family). Всего таких семейств шесть (см. табл. 1).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
По способу создания изображения символа шрифты разделяются на растровые, векторные и шрифты TrueType. Растровые шрифты представляют собой набор пикселов, образующих начертание. Такие шрифты широко использовались в старых версиях Windows, поэтому интереса для нас не представляют. Векторные и TrueType-шрифты, напротив, применяются в настоящее время. Они хранятся как набор кривых, описываемых математическими уравнениями. За счет этого они не зависят от устройств вывода и могут масштабироваться до любых размеров без потери качества изображения.
И последняя характеристика, которая важна при использовании шрифтов, это кодировка. Ею определяется порядок расположения символов и их количество. Так, например, шрифтами с кириллической кодировкой KOI-8 нельзя показать текст, созданный в текстовом процессоре, который использует кириллическую кодировку ANSI 1251. Об этом следует помнить всегда.
Вы можете просмотреть все шрифты, установленные в вашей системе (см. врезку "Использование функции EnumFontFamilies()").
Создание шрифта - это операция, очень часто используемая программистами. При этом они оперируют не физическими шрифтами, которые реально существуют, а шрифтами логическими, т. е. теми, которые желательно получить в идеальном случае. А уже программа отображения шрифтов подбирает физический шрифт, наиболее похожий на заданный логический.
Для создания шрифтов используются всего лишь три функции:
CreateFont() - создает шрифт по заданным в ней параметрам;
CreateFontIndirect() - создает шрифт в соответствии со структурой LOGFONT, переданной функции;
ChooseFont() - выводит стандартную диалоговую панель Font и возвращает выбор пользователя.
Принципиального различия между CreateFont() и CreateFontIndirect() не существует. Просто в первом случае используется набор параметров, а во втором они собраны в виде структуры LOGFONT (см. врезку "Структура LOGFONT"), на базе которой создаются все логические шрифты. Что касается функции ChooseFont(), то она сама не создает никаких шрифтов, но помогает организовать диалог с пользователем, запросив у него, какой шрифт выбрать. Еще эта функция удобна тем, что она возвращает ссылку на структуру LOGFONT, уже заполненную данными на основе опроса пользователя. Нам остается лишь передать эту ссылку в качестве параметра функции CreateFontIndirect(), которая создаст требуемый шрифт. К сожалению, ChooseFont() можно применить лишь в тех программах, которые подразумевают общение с пользователем.
После того как шрифт создан, не забудьте выделить его в контексте устройства командой SelectObject(). С этого момента любой вывод текста будет производиться шрифтом, который вы создали.
Родственным векторным шрифтам понятием являются пути (paths) - кривые, описывающие контур сложных графических объектов. Пути очень распространены в программах работы с графикой и САПР. При этом создание путей - дело достаточно простое. Для этого нужно задать ограничители пути. Ограничители пути представляют собой вызовы пары базовых функций BeginPath() и EndPath(). Внутри этих ограничителей вы можете вставить практически любую функцию рисования GDI (см. табл. 2).
Записанный BeginPath() и EndPath() путь становится активным в контексте устройства. И с того момента с путем можно проделать следующие операции:
По поводу отрисовки пути позволю себе замечание. Если вы сначала отрисуете путь функцией StrokePath(), то после этого не заливайте его функцией FillPath(), потому что кроме заливки внутренней области, обрамленной путем, будет залит и сам путь. В результате, если вы выполнили путь черным цветом, а залили его красным, то контур также станет красным. Поэтому в таких случаях нужно использовать функцию одновременного рисования и заливки StrokeAndFillPath().
Теперь проиллюстрируем все сказанное примером программы, выполненной с использованием Borland C++ Builder.
Запустите Borland C++ Builder, создайте новый проект и перейдите в режим текстового редактирования формы нажатием комбинации клавиш
object Form1: TForm1 Left = 212 Top = 198 Width = ~748 Height = 300 Caption = 'Fonts Usage Demo' Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -13 Font.Name = 'MS Sans Serif' Font.Style = [] OnCreate = FormCreate OnDestroy = FormDestroy PixelsPerInch = 120 TextHeight = 16 object Bevel1: TBevel Left = 476 Top = 0 Width = 2 Height = 261 end object Label1: TLabel Left = 10 Top = 5 Width = 69 Height = 16 Caption = 'Font Family' end object Label2: TLabel Left = 10 Top = 60 Width = 73 Height = 16 Caption = 'Type Faces' end object Label3: TLabel Left = 370 Top = 5 Width = 77 Height = 16 Caption = 'Rotate angel' end object ComboBox1: TComboBox Left = 5 Top = 25 Width = 196 Height = 24 Style = csDropDownList ItemHeight = 16 Items.Strings = ( 'Don'#39't care' 'Roman' 'Swiss' 'Modern' 'Script' 'Decorative') TabOrder = 0 OnChange = ComboBox1Change end object ListBox1: TListBox Left = 5 Top = 80 Width = 196 Height = 181 ItemHeight = 16 TabOrder = 1 end object GroupBox1: TGroupBox Left = 210 Top = 5 Width = 136 Height = 106 Caption = 'Style' TabOrder = 2 object CheckBox1: TCheckBox Left = 20 Top = 20 Width = 91 Height = 17 Caption = 'Bold' TabOrder = 0 end object CheckBox2: TCheckBox Left = 20 Top = 40 Width = 97 Height = 17 Caption = 'Italic' TabOrder = 1 end object CheckBox3: TCheckBox Left = 20 Top = 60 Width = 97 Height = 17 Caption = 'Underline' TabOrder = 2 end object CheckBox4: TCheckBox Left = 20 Top = 80 Width = 97 Height = 17 Caption = 'Strikeout' TabOrder = 3 end end object Button1: TButton Left = 365 Top = 110 Width = 96 Height = 25 Caption = 'Show' TabOrder = 3 OnClick = Button1Click end object UpDown1: TUpDown Left = 436 Top = 40 Width = 15 Height = 24 Associate = Edit1 Min = 0 Max = 359 Position = 0 TabOrder = 4 Wrap = False end object Edit1: TEdit Left = 375 Top = 40 Width = 61 Height = 24 TabOrder = 5 Text = '0' end object GroupBox2: TGroupBox Left = 210 Top = 120 Width = 136 Height = 141 Caption = 'Font Color' TabOrder = 6 object Label4: TLabel Left = 90 Top = 30 Width = 26 Height = 16 Caption = 'Red' Color = clBtnFace Font.Charset = RUSSIAN_CHARSET Font.Color = clRed Font.Height = -13 Font.Name = 'MS Sans Serif' Font.Style = [] ParentColor = False ParentFont = False end object Label5: TLabel Left = 90 Top = 70 Width = 37 Height = 16 Caption = 'Green' Font.Charset = DEFAULT_CHARSET Font.Color = clGreen Font.Height = -13 Font.Name = 'MS Sans Serif' Font.Style = [] ParentFont = False end object Label6: TLabel Left = 90 Top = 110 Width = 27 Height = 16 Caption = 'Blue' Font.Charset = RUSSIAN_CHARSET Font.Color = clBlue Font.Height = -13 Font.Name = 'MS Sans Serif' Font.Style = [] ParentFont = False end object Edit2: TEdit Left = 10 Top = 25 Width = 51 Height = 24 TabOrder = 0 Text = '0' end object Edit3: TEdit Left = 10 Top = 65 Width = 51 Height = 24 TabOrder = 1 Text = '0' end object Edit4: TEdit Left = 10 Top = 105 Width = 51 Height = 24 TabOrder = 2 Text = '0' end object UpDown2: TUpDown Left = 61 Top = 25 Width = 15 Height = 24 Associate = Edit2 Min = 0 Max = 255 Position = 0 TabOrder = 3 Wrap = False end object UpDown3: TUpDown Left = 61 Top = 65 Width = 15 Height = 24 Associate = Edit3 Min = 0 Max = 255 Position = 0 TabOrder = 4 Wrap = False end object UpDown4: TUpDown Left = 61 Top = 105 Width = 15 Height = 24 Associate = Edit4 Min = 0 Max = 255 Position = 0 TabOrder = 5 Wrap = False end end object Button2: TButton Left = 365 Top = 170 Width = 96 Height = 26 Caption = 'Make Path' TabOrder = 7 OnClick = Button2Click end object Button3: TButton Left = 365 Top = 235 Width = 96 Height = 26 Caption = 'Fill Path' TabOrder = 8 OnClick = Button3Click end end
Снова нажмите
Теперь наберем исходный текст самой программы. Сначала создадим заголовочный файл main.h :
//-------------------------------------- #ifndef mainH #define mainH //-------------------------------------- #include#include #include #include #include #include //-------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TBevel *Bevel1; TComboBox *ComboBox1; TLabel *Label1; TLabel *Label2; TLabel *Label3; TLabel *Label4; TLabel *Label5; TLabel *Label6; TListBox *ListBox1; TGroupBox *GroupBox1; TGroupBox *GroupBox2; TCheckBox *CheckBox1; TCheckBox *CheckBox2; TCheckBox *CheckBox3; TCheckBox *CheckBox4; TButton *Button1; TButton *Button2; TUpDown *UpDown1; TUpDown *UpDown2; TUpDown *UpDown3; TUpDown *UpDown4; TEdit *Edit1; TEdit *Edit2; TEdit *Edit3; TEdit *Edit4; TButton *Button3; void __fastcall FormCreate(TObject *Sender); void __fastcall ComboBox1Change(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); void __fastcall Button3Click(TObject *Sender); private: // User declarations void __fastcall ClearPicture(void); HFONT __fastcall SetupFont (HDC, int, bool, bool, bool, bool, int, LPCTSTR, long); void __fastcall RemoveFont(HDC, HFONT); HFONT __fastcall SetupChoosenFont(void); void __fastcall ShowFonts(int); void __fastcall ShowCross(void); public: // User declarations __fastcall TForm1(TComponent* Owner); }; //-------------------------------------- int CALLBACK EnumFontProc (ENUMLOGFONT FAR*, TEXTMETRIC FAR*, int, LPARAM); //-------------------------------------- extern TForm1 *Form1; //-------------------------------------- #endif
В этом файле описываются сама форма и ссылки на все компоненты, размещенные на ней, а также задаются обработчики событий от компонентов.
Сама программа представлена файлом main.cpp, исходный текст которого приведен ниже.
//-------------------------------------- #include#pragma hdrstop #include "main.h" //-------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; HDC dc; //-------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //-------------------------------------- // Стирает старый рисунок //-------------------------------------- void __fastcall TForm1::ClearPicture(void) { InvalidateRect(Handle, NULL, true); UpdateWindow(Handle); } //-------------------------------------- // Отмечает крестиком место начала рисования //-------------------------------------- void __fastcall TForm1::ShowCross(void) { // Передвинуть перо MoveToEx(dc, 537, 100, NULL); // Нарисовать линию LineTo(dc, 544, 100); MoveToEx(dc, 540, 97, NULL); LineTo(dc, 540, 104); } //-------------------------------------- // Вспомогательная функция создания шрифта //-------------------------------------- HFONT __fastcall TForm1::SetupFont( HDC dc, int size, bool bold, bool italic, bool underline, bool strikeout, int family, LPCTSTR typeface, long rotation) { HFONT font = CreateFont( // Пересчитывает из логических единиц в типографские -MulDiv(size, GetDeviceCaps(dc, LOGPIXELSY), 72), 0, // Выбрать ширину автоматически rotation*10, // Угол поворота текста rotation*10, // Угол ориентации базовой линии bold, italic, underline, strikeout, // Стиль создаваемого шрифта DEFAULT_CHARSET, // Символьный набор по умолчанию OUT_DEFAULT_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, // Качество вывода по определению family | DEFAULT_PITCH, // Семейство шрифта typeface); // Название шрифта SetTextColor(dc, // Задать цвет текста RGB( StrToInt(Edit2->Text), StrToInt(Edit3->Text), StrToInt(Edit4->Text))); return SelectObject(dc, font); // Выбрать созданный шрифт } //-------------------------------------- // Вернуть старый шрифт //-------------------------------------- void __fastcall TForm1::RemoveFont(HDC dc, HFONT oldfont) { HFONT font = SelectObject(dc, oldfont); DeleteObject(font); } //-------------------------------------- // Задать шрифт на базе полученных от // пользователя данных //-------------------------------------- HFONT __fastcall TForm1::SetupChoosenFont(void) { return SetupFont( dc, 30, CheckBox1->Checked, CheckBox2->Checked, CheckBox3->Checked, CheckBox4->Checked, // Пересчитать индекс из списка в константу FF_ ComboBox1->ItemIndex << 4, (ListBox1->Items)->Strings[ListBox1->ItemIndex].c_str(), StrToInt(Edit1->Text)); } //-------------------------------------- // Показать все имеющиеся шрифты //-------------------------------------- void __fastcall TForm1::ShowFonts(int Family) { ListBox1->Clear(); // Перебрать установленные в системе шрифты EnumFontFamilies(dc, NULL, (FONTENUMPROC)EnumFontProc, (LPARAM)Family); // Отсортировать шрифты в алфавитном порядке ListBox1->Sorted = true; // Выделить первый шрифт из списка ListBox1->ItemIndex = 0; } //-------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { // Получить контекст устройства dc = GetDC(Handle); ComboBox1->ItemIndex = 0; // Показать все шрифты семейства Don't care ShowFonts(FF_DONTCARE); // Цвет подложки должен проглядывать // Уберите этот оператор и посмотрите, что получится!!! SetBkMode(dc, TRANSPARENT); } //-------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { // Освободить контекст устройства ReleaseDC(Handle, dc); } //-------------------------------------- // Пользователь выбрал другое семейство шрифтов // Нужно изменить список шрифтов //-------------------------------------- void __fastcall TForm1::ComboBox1Change(TObject *Sender) { // Чтобы определить константу семейства шрифтов FF_, // нужно сдвинуть номер выбранного из списка пункта // на четыре бита влево ShowFonts( (static_cast (Sender)->ItemIndex) << 4 ); } //-------------------------------------- // Функция косвенного вызова для перебора шрифтов // В качестве последнего произвольного параметра // ей передается константа FF_ выбранного // пользователем семейства шрифтов //-------------------------------------- int CALLBACK EnumFontProc( ENUMLOGFONT FAR* lf, TEXTMETRIC FAR* tm, int FontType, LPARAM FamilyRequested) { BYTE nFamily; // Выделить из структуры семейство шрифта nFamily = tm->tmPitchAndFamily & 0xF0; // Нас интересуют только TrueType-шрифты if(FontType == TRUETYPE_FONTTYPE) // Входит ли шрифт в семейство, // запрошенное пользователем? if(nFamily == FamilyRequested) // Тогда добавить его в список Form1->ListBox1->Items->Add( AnsiString((char*)lf->elfFullName)); return true; // Продолжаем перебор } //-------------------------------------- // Обработчик нажатия кнопки Show //-------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { HFONT old_font; ClearPicture(); // Задать шрифт по выбору пользователя old_font = SetupChoosenFont(); // Показать крестиком начало координат рисования ShowCross(); // Показать текст Font TextOut(dc, 540, 100, "Font", 4); // Вернуть старый шрифт RemoveFont(dc, old_font); } //-------------------------------------- // Обработчик нажатия кнопки Make Path //-------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { HFONT old_font; HPEN old_pen; ClearPicture(); old_font = SetupChoosenFont(); old_pen = SelectObject(dc, // Задать перо для рисования пути CreatePen(PS_SOLID, 1, // Считать цветовые константы // для задания пера RGB( StrToInt(Edit2->Text), StrToInt(Edit3->Text), StrToInt(Edit4->Text)))); // Создаем путь BeginPath(dc); ShowCross(); TextOut(dc, 540, 100, "Font", 4); // Заканчиваем создание пути EndPath(dc); // Показать путь StrokePath(dc); DeleteObject(SelectObject(dc, old_pen)); RemoveFont(dc, old_font); } //-------------------------------------- // Обработчик нажатия кнопки Fill Path //-------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { HFONT old_font; HPEN old_pen; HBRUSH old_brush; ClearPicture(); old_font = SetupChoosenFont(); old_pen = SelectObject(dc, CreatePen(PS_SOLID, 1, RGB( StrToInt(Edit2->Text), StrToInt(Edit3->Text), StrToInt(Edit4->Text)))); old_brush = SelectObject(dc, CreateSolidBrush( // Задаем инверсный цвет заливки RGB( ~StrToInt(Edit2->Text), ~StrToInt(Edit3->Text), ~StrToInt(Edit4->Text)))); BeginPath(dc); ShowCross(); TextOut(dc, 540, 100, "Font", 4); EndPath(dc); StrokeAndFillPath(dc); DeleteObject(SelectObject(dc, old_brush)); DeleteObject(SelectObject(dc, old_pen)); RemoveFont(dc, old_font); } //--------------------------------------
Правила пользования программой очень просты. Выберите из списка требуемое семейство шрифтов. Программа покажет вам все шрифты выбранного вами семейства. Выберите любое название шрифта, его стиль (жирный, курсивный, подчеркнутый или перечеркнутый), угол наклона и цвет из трех цветовых составляющих. Нажмите кнопку Show и взгляните на полученный результат.
Если вы проделаете то же самое, но нажмете кнопку Make Path, то надпись будет выполнена с помощью пути.
Получить залитый инверсным цветом путь можно, нажав кнопку Fill Path.
В качестве домашнего задания используйте различные функции для работы с путями.
Использование функции EnumFontFamilies()
Функция EnumFontFamilies() перебирает шрифты определенного семейства и описывается следующим образом:
int EnumFontFamilies( HDC hdc, // ссылка на контекст устройства LPCTSTR lpszFamily, // указатель на строку с именем семейства шрифта FONTENUMPROC lpEnumFontFamProc, // указатель на функцию косвенного вызова LPARAM lParam // произвольный параметр );
Некоторые параметры рассмотрим детальнее. Самый важный параметр - lpszFamily. Вы должны задать в нем название семейства шрифтов в виде строки, заканчивающейся нулем. Например, Roman. Тогда функция будет перебирать шрифты только этого семейства. Когда этот параметр задан как NULL, то произвольно выбирается по одному шрифту из каждого семейства. Но на практике это не работает, вернее работает совсем не так.
Внимание! Параметр lpszFamily в документации описан неправильно! Если вы передадите в нем название семейства шрифтов, то ничего не произойдет. Но если передать в нем конкретное название шрифта, например Arial Cyr, то функция найдет все шрифты с таким именем, включая Arial Cyr Bold, Arial Cyr Italic, Arial Cyr Underline и т.д. Если же вы передадите NULL в lpszFamily, то EnumFontFamilies() переберет абсолютно все шрифты, установленные в системе, включая системные, матричные и т. п.
lpEnumFontFamProc указывает на функцию косвенного вызова, к которой происходит обращение каждый раз, когда EnumFontFamilies() находит очередной шрифт. Описание функции косвенного вызова приводится далее.
Параметр lParam произволен. Вы можете передать через него любые данные, не превышающие по длине тип long. Это, к примеру, может быть указатель на буфер, куда следует складывать данные о найденных шрифтах.
Функция EnumFontFamilies() возвращает число, которое в свою очередь было возвращено ей функцией косвенного вызова.
Теперь рассмотрим, как описывается функция косвенного вызова типа FONTENUMPROC.
int CALLBACK EnumFontFamProc( ENUMLOGFONT FAR *lpelf, // указатель на данные логического шрифта TEXTMETRIC FAR *lpntm, // указатель на данные физического шрифта int FontType, // тип шрифта LPARAM lParam // пользовательский параметр, переданный от EnumFontFamilies() );
Мы не будем рассматривать структуры, адресуемые параметрами lpelf и lpntm, поскольку они очень большие. Отметим лишь отдельные их поля. У структуры ENUMLOGFONT нас интересует поле elfFullName, в которое записывается полное название найденного шрифта. У структуры TEXTMETRIC полезным для нас будет поле tmPitchAndFamily. Оно описывает пропорциональность и семейство шрифта. Обратите внимание, что семейство шрифта задается не строкой, а системной константой (см. таблицу).
Структура LOGFONT
Структура LOGFONT описывается в документации следующим образом:
typedef struct tagLOGFONT { LONG lfHeight; LONG lfWidth; LONG lfEscapement; LONG lfOrientation; LONG lfWeight; BYTE lfItalic; BYTE lfUnderline; BYTE lfStrikeOut; BYTE lfCharSet; BYTE lfOutPrecision; BYTE lfClipPrecision; BYTE lfQuality; BYTE lfPitchAndFamily; TCHAR lfFaceName[LF_FACESIZE]; } LOGFONT;
Кратко рассмотрим назначение ее полей.
lfHeight - определяет высоту шрифта в логических единицах. Чтобы получить это число из типографского размера в точках, Microsoft рекомендует пользоваться формулой lfHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72). Правда, это работает лишь в режиме отображения MM_TEXT.
lfWidth - определяет ширину шрифта в логических единицах. Вы можете присвоить этому полю ноль, тогда система сама подберет подходящую ширину на основе данных о шрифте и видеопараметрах компьютера.
lfEscapement - задает угол поворота шрифта против часовой стрелки в десятых градуса.
lfOrientation - в Windows 95 должен быть равен значению lfEscapement.
lfWeight - определяет вес шрифта, т. е. его "жирность" в диапазоне от 0 до 1000. Для нормального шрифта определена константа FW_NORMAL, равная 400, а для жирного шрифта используется константа FW_BOLD, равная 700. Если задан ноль, то выбирается вес шрифта по умолчанию.
lfItalic - если "истина", то это курсивный (наклонный) шрифт.
fUnderline - если "истина", то это подчеркнутый шрифт.
lfStrikeOut - если "истина", то это перечеркнутый шрифт.
lfCharSet - задает национальные и кодировочные особенности шрифта. Так, например, существует константа RUSSIAN_CHARSET. Чаще всего, правда, используется константа по умолчанию - DEFAULT_CHARSET.
lfOutPrecision - опция точности вывода шрифта. Используется исключительно в профессиональных системах. Для обычных программ лучше задавать ее как OUT_DEFAULT_PRECIS.
lfClipPrecision - задает точность отсечения символов, выходящих за пределы области отсечения. В обычных программах лучше просто задать CLIP_DEFAULT_PRECIS.
lfQuality - определяет качество отображения шрифта. Это означает, что на основе этой константы программа отображения шрифтов определяет, насколько точно должны соблюдаться заданные параметры шрифта при его выборе. Обычно этот параметр задается как DEFAULT_QUALITY. Это означает, что точность неважна. Для чернового вывода можно задать этот параметр как DRAFT_QUALITY. Если же требуется высокая точность, нужно использовать константу PROOF_QUALITY.
lfPitchAndFamily - задает семейство создаваемого шрифта и дополнительный параметр Pitch. Константы, определяющие семейства шрифтов, вы можете посмотреть в табл. 1. Что касается дополнительного параметра Pitch, то его рекомендуется всегда задавать как DEFAULT_PITCH.
fFaceName[] - это имя создаваемого шрифта, например Pragmatica, Courier New и т. д.
Функции GDI, создающие пути
В Windows NT для создания путей могут быть применены следующие функции
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Для Windows 95 список допустимых вызовов API меньше
|
|
|
|
|
|
|
|
|
|
|
|