Диалоговое окно Font (Шрифт)

   
На этом шаге мы рассмотрим использование стандартного диалогового окна Font (Шрифт).

   
Существует много приложений Windows, включая программы рисования, электронные таблицы и системы управления базами данных,
позволяющих пользователю выбрать шрифты различных размеров и цветов с различными атрибутами: подчеркивание, жирность, курсив и перечеркивание.
Эта широко распространенная функция реализуется окном диалога Font системы Windows, которую OWL инкапсулирует в своем
классе TChooseFontDialog.

   
Шрифты представляют собой, пожалуй, самые "хитрые" объекты, которыми должен управлять программист, разрабатывающий приложение Windows.
Чтобы выбирать и использовать шрифты, вы должны быть знакомы со структурой LOGFQNT, которая содержит информацию о шрифте, и вы должны
знать, как создать новые шрифты, если в этом возникнет необходимость.
   
В таблице 1 приведены поля структуры LOGFONT.

Таблица 1. Поля LOGFONT и их описание

ПолеОписание
lfHeightВысота шрифта в логических единицах.
lfWidthШирина шрифта в логических единицах.
lfEscapementУгол, под которым рисуется текст.
lfOrientationНаклон символа в десятых долях градуса.
lfWeightИспользуется для выбора обычного (400) или жирного (700) текста.
ifItalicНенулевое значение указывает курсив.
lfUnderlineНенулевое значение задает шрифт с подчеркиванием.
lfStrikeoutНенулевое значение задает перечеркнутый шрифт.
lfCharSetУстанавливает тип шрифта.
lfOutPrecisionЗадает точность вывода шрифта.
lfClipPrecisionОпределяет, как отсекаются символы, которые частично оказались за границей допустимой области.
lfQualityКачество вывода шрифта.
lfPitchAndFamilyШаг и семейство шрифта.
lfFaceNameОпределяет начертание шрифта.

   
При использовании окна диалога Font библиотеки OWL вам не нужно знать о том, как работают шрифты. Необходимо только иметь достаточные знания о самих шрифтах,
чтобы инициализировать структуру TChooseFontDialog::TData и создавать новый шрифт на основании информации, которую возвратит вам окно диалога. Следующий пример показывает,
как это делается.

#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dc.h>
#include <owl\choosefo.h>
#include <string.h>
#include "pr27_1.rc"

//Класс приложения
class TApp: public TApplication
{
  public:
	 TApp():TApplication(){}
	 void InitMainWindow();
};

//Класс основного окна
class TWndw : public TFrameWindow
{
  public:
	 TWndw(TWindow *parent, const char far *title);
	 ~TWndw();
  protected:
         TFont *font;
         TColor fontColor;
         char fontName[81];
         void CmChooseFont();
         void  Paint (TDC &paintDC, BOOL, TRect&);

	 DECLARE_RESPONSE_TABLE (TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)
  EV_COMMAND(CM_CHOOSEFONT, CmChooseFont),
END_RESPONSE_TABLE;

TWndw::TWndw(TWindow *parent, const char far *title):
		  TFrameWindow(parent,title)
{
	// Добавить меню к главному окну.
	AssignMenu("MENU_1");
	// Определить расположение и размеры окна.
	Attr.X=50;
	Attr.Y=50;
	Attr.W=GetSystemMetrics(SM_CXSCREEN)/3;
	Attr.H=GetSystemMetrics(SM_CXSCREEN)/4;
        // Инициализировать указатель шрифта, цвет и название.
        font = 0;
        fontColor = TColor::Black;
        strcpy(fontName,"System font");
}

// TWndw::~TWndw()
// Это деструктор главного окна.
TWndw::~TWndw()
{
  // Если объект шрифта существует, удалить его.
  if (font) delete font;
}

// TWndw::CmChooseFont()
// Эта функция реагирует на команду Choose Font,
// отображая диалоговое окно "Шрифт".
void TWndw::CmChooseFont()
{
  // Определить массив для сообщения об ошибке.
  char errorMsg[81];
  // Создать объект TData диалогового окна Font.
  TChooseFontDialog::TData fontData;
  // Инициализировать объект TData. 
  fontData.Flags = CF_EFFECTS | CF_TTONLY | 
     CF_FORCEFONTEXIST | CF_SCREENFONTS;
  fontData.Color = fontColor;
  // Создать диалоговое окно Font.
  TChooseFontDialog *dialog =
       new TChooseFontDialog (this, fontData);
  // Выполнить диалоговое окно Font. 
  int result = dialog->Execute();
  // Ответить на кнопку "OK" диалогового окна.
  if (result == IDOK)
  {
      // Удалить старый шрифт, если он существует.
      if (font) delete font;
      // Создать новый шрифт по выбору пользователя. 
      font = new TFont(&fontData.LogFont);
      // Получить цвет и название выбранного шрифта.
      fontColor = fontData.Color;
      strcpy(fontName, fontData.LogFont.lfFaceName);
      // Заставить окно перерисоваться. 
      Invalidate();
  }
  // Если произошла ошибка... 
  else if (fontData.Error != 0) 
         {
           // Вывести окно сообщений об ошибках. 
           wsprintf(errorMsg,"Ошибка #%ld.", fontData.Error); 
           MessageBox(errorMsg, "Ошибка",  MB_OK | MB_ICONEXCLAMATION);
         }
}

//TWndw::Paint()
// Эта функция переопределяет функцию Paint() из 
// TWindow и реагирует на сообщение WM_PAINT, которое 
// Windows посылает окну, если оно должно быть 
// повторно перерисовано.
void TWndw::Paint(TDC &paintDC, BOOL, TRect&)
{
  // Если имеется выбранный шрифт...
  if (font)
        // ... поместить его в контекст устройства.
        paintDC.SelectObject (*font); 
  // Установить цвет шрифта.
  paintDC.SetTextColor (fontColor);  
  // Вывести название шрифта в окне. 
  paintDC.TextOut(10, 10, fontName);
}

void TApp::InitMainWindow()
{
  TFrameWindow *wndw= new TWndw(0,"Диалоговое окно \"Выбор шрифта\"");
  SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
  return TApp().Run();
}

   
Файл ресурсов:

#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#define CM_EXIT        24310
#define CM_CHOOSEFONT    101


#ifdef RC_INVOKED

MENU_1 MENU
{
 POPUP "&File"
 {
  MENUITEM "E&xit", CM_EXIT
 }
 POPUP "&Font"
 {
  MENUITEM "&Choose Font...", CM_CHOOSEFONT
 }
}

#endif

Текст этого приложения можно взять здесь.

   
После запуска этой программы вы увидите окно, показанное на рисунке 1.


Рис.1. Результат работы приложения

   
Это окно отображает название текущего выбранного шрифта, которое рисуется выбранным шрифтом. Для изменения шрифта выберите из меню
Font команду Choose Font. Когда вы это сделаете, то увидите диалоговое окно Font, как показано на рисунке 2.


Рис.2. Окно выбора шрифта

   
Вы можете использовать это диалоговое окно не только для выбора начертания шрифта, но также для выбора точечного размера шрифта, цвета и атрибутов.
После указания шрифта выберите кнопку ОК для выхода из окна диалога. В рабочей области главного окна появится новый шрифт, как показано на рисунке 3.


Рис.3. Окно с выбранным шрифтом

   
Класс главного окна примера включает три защищенных члена-данных: font, fontcolor и fontName, которые являются соответственно объектом, цветом и названием текущего шрифта.
Программа инициализирует эти поля в конструкторе главного окна, устанавливая указатель шрифта в нуль, цвет шрифта в черный и название шрифта в "System font".

   
В отличие от предыдущих программ этой главы, оконный класс имеет деструктор:

TWndw::~TWndw()
{
  // Если объект шрифта существует, удалить его.
  if (font) delete font;
}

   
Деструктор отвечает за удаление объекта текущего выбранного шрифта, если он существует. Это освобождает ресурсы для других Windows-приложений.

   
Большинство действий программы осуществляется в функциях CmChooseFont() и Paint(). CmChooseFont() реагирует на команду Choose Font из пункта меню Font.
Эта функция сначала объявляет объект TChooseFontDialog::TData с именем fontData:

    TChooseFontDialog::TData  fontData; 

   
Затем инициализирует соответствующие члены-данные объекта fontData:

  fontData.Flags = CF_EFFECTS | CF_TTONLY | 
     CF_FORCEFONTEXIST | CF_SCREENFONTS;
  fontData.Color = fontColor;

   
Так как эта программа работает только с экранными шрифтами, то единственными элементами, которые необходимо инициализировать, являются Flags и Color.
Flags является совокупностью флагов, определяющих, каким образом должно выглядеть и функционировать диалоговое окно. В этом случае флаги указывают, что должен быть включен выбор
возможных действий (со шрифтом), должны быть перечислены только шрифты типа TrueType; должна посылаться ошибка, если выбранный шрифт или тип не существуют, и только экранные
шрифты должны быть перечислены в списке возможных шрифтов. (Таблица 2 содержит предопределенные константы, которые вы можете использовать для этих флагов.) Color - это цвет шрифта,
задаваемый по умолчанию. Он представляет собой тот цвет, который будет автоматически выбираться при появлении окна диалога. CmChooseFont() устанавливает это поле в значение fontСolor,
которое является текущим выбранным цветом шрифта.

Таблица 2. Константы флагов TChooseFontDialog::TData

ПолеОписание
CF_APPLYОтобразить кнопку Apply (Применить).
CF_ANSIONLYДопускает выбор только шрифтов с символами в ANSI-кодах.
CF_BOTHВыводить список шрифтов экрана и принтера.
CF_EFFECTSДопускает подчеркивание, перечеркивание и цвет.
CF_FIXEDPITCHONLYДопускает выбор только шрифтов с фиксированным шагом.
CF_FORCEFONTEXISTВыдавать ошибку, если пользователь выбрал несуществующий шрифт или тип.
CF_INITTOLOGFONTSTRUCTУстановить значения управляющих элементов диалога в соответствии со зачениями в LogFont.
CF_LIMITSIZEУстановить значения размера шрифта между SizeMin и SizeMax.
CF_NOSIMULATIONЗапрещает имитацию шрифта GDI.
CF_PRINTERFONTSВыводить список шрифтов только для принтера.
CF_SCALABLEONLYДопускает выбор только масштабируемых шрифтов.
CF_SCREENFONTSВыводить список шрифтов только для экрана.
CF_SHOWHELPПоказывает кнопку "Help" блока диалога.
CF_TTONLYДопускает выбор только шрифтов True Type.
CF_USESTYLEИспользует буфер STYLE для инициализации выбора типа шрифта.
CF_WYSIWYGРазрешает использовать только шрифты, доступные как для экрана, так и для принтера.

   
Замечание.
Объект TChooseColorDialog::TData является намного более сложным, чем может показаться из программы-примера. Эта структура заключает в себе 10 членов-данных. Например, при выборе шрифтов для принтера
вы должны установить поле TData.DС в значение DC-дескриптора принтера. Вы должны также использовать члены-данные TData.SizeMin и TData.SizeMax, чтобы обязать пользователя выбирать
размеры шрифта внутри определенного диапазона.

   
Таким образом, структура TChooseColorDialog::TData содержит следующие поля:

  • TColor Color - содержит цвет выбранного шрифта;
  • HDC DC - дескриптор выбранного контекста, в котором будет использоваться выбранный шрифт;
  • uint32 Error - содержит код ошибки. Если ошибок нет, это поле содержит 0;
  • uint32 Flags - набор флагов;
  • uint16 FontType - тип или имя шрифта;
  • LOGFONT LogFont - атрибуты шрифта;
  • int PrintSize - размер точки шрифта;
  • int SizeMax - максимальный размер шрифта;
  • int SizeMin - минимальный размер шрифта;
  • char far *Style - стиль шрифта (жирный, курсив, подчеркнутый, перечеркнутый).

   
После создания и инициализации объекта TData, CmChooseFont() создает диалоговое окно TChooseFontDialog с помощью вызова конструктора класса с двумя аргументами:
указателем на родительское окно и ссылкой на объект TChooseFontDialog::TData:

    TChooseFontDialog  *dialog = new  TChooseFontDialog (this, fontData);

   
Если пользователь завершает диалог по кнопке ОК, это означает, что он выбрал новый шрифт. В этом случае CmChooseFont() удаляет старый шрифт
(если он существовал), создает новый объект TFont из члена-данного LogFont объекта TData, получает новый цвет шрифта из элемента
Color и копирует имя нового шрифта из члена-данного lfFaceName объекта LogFont:

  if (result == IDOK)
  {
      // Удалить старый шрифт, если он существует.
      if (font) delete font;
      // Создать новый шрифт по выбору пользователя. 
      font = new TFont(&fontData.LogFont);
      // Получить цвет и название выбранного шрифта.
      fontColor = fontData.Color;
      strcpy(fontName, fontData.LogFont.lfFaceName);
      // Заставить окно перерисоваться. 
      Invalidate();
  }

   
Собрав вместе все данные, необходимые для нового шрифта, CmChooseFont() вызывает Invalidate() для того, чтобы послать в окно сообщение WM_PAINT,
которое заставит OWL вызвать функцию Paint() главного окна:

void TWndw::Paint(TDC &paintDC, BOOL, TRect&)
{
  // Если имеется выбранный шрифт...
  if (font)
        // ... поместить его в контекст устройства.
        paintDC.SelectObject (*font); 
  // Установить цвет шрифта.
  paintDC.SetTextColor (fontColor);  
  // Вывести название шрифта в окне. 
  paintDC.TextOut(10, 10, fontName);
}

   
Paint() сначала проверяет, указывает ли font на объект нового шрифта (помните, что при запуске программы значение font равно нулю).
Если новый шрифт существует, Paint() выбирает его в контекст устройства. В любом случае функция вызывает SetTextColor() вместе с fontColor,
чтобы установить цвет шрифта, а затем вызывает TextOut() для вывода названия шрифта, используя при этом текущий шрифт.

   
На следующем шаге мы рассмотрим диалоговые окна Find и Replace.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий