Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования для информатиков и инженеров. Часть 2 Прикладное программирование в Windows.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
603.45 Кб
Скачать

8.3. Изменение шрифтов

 

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

 

Использование встроенных шрифтов. Встроенные шрифты – это системные объекты, которые могут быть выбраны при помощи функции GetStockObject(). Макроимена, ассоциированные с некоторыми шрифтами, приводятся в таблице 8.4.

 

Таблица 8.4

Макроимена распространенных шрифтов

 

Макрос

Шрифт

1

ANSI_FIXED_FONT

Шрифт с фиксированным размером символов

2

ANSI_VAR_FONT

Шрифт с переменной шириной символов

3

DEVICE_DEFAULT_FONT

Шрифт для данного устройства, выбираемый по умолчанию

4

DEFAULT_GUI_FONT

Шрифт графического интерфейса, устанавливаемый по умолчанию

5

OEM_FIXED_FONT

OEM-шрифт

6

SYSTEM_FONT

Системный шрифт Windows

7

SYSTEM_FIXED_FONT

Шрифт, использовавшийся как системный в ранних версиях Windows

 

Системные шрифты используются в Windows для отображения меню и диалогов. В ранних версиях Windows использовался системный шрифт с постоянным размером символов. Во всех современных версиях, начиная с Windows 95, используются пропорциональные шрифты.

Выбор и использование встроенных шрифтов – очень простая задача. Для этого программа должна сначала создать дескриптор шрифта – переменную типа HFONT. Затем необходимо загрузить требуемый шрифт при помощи функции GetStockObject(), которая возвратит дескриптор шрифта. Чтобы переключить шрифт, следует выбрать шрифт при помощи функции SelectObject(), передав ей в качестве параметра полученный дескриптор шрифта. Функция SelectObject() возвратит дескриптор ста­рого шрифта, которой был текущим до этого (можно сохранить этот дескриптор и в нужный момент вернуться к использованию старого шрифта).

 

Пример 8-3. Следующий пример демонстрирует процедуру переключения шрифтов. В нем вводится новый пункт меню Шрифт. Каждый раз при выборе этой команды меню программа переключается между системным шрифтом по умолчанию и ANSI-пропорциональным шрифтом.

 

// Демонстрация встроенных шрифтов

#include <Windows.h>

#include <String.h>

#include <Stdio.h>

#include "Text.h"

 

LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);

char szWinName[] = "МоеОкно";  // Имя класса окна

char str[255];      // Буфер строки вывода

int X=0, Y=0;       // Текущие координаты строки

int maxX, maxY;     // Размеры экрана

HDC     memdc;      // DC виртуального окна

HBITMAP hbit;       // Растр - это виртуальное окно

HBRUSH  hbrush;     // Дескриптор кисти

HFONT holdf, hnewf; // Дескрипторы шрифтов

 

int WINAPI WinMain (HINSTANCE hThisInst,

                    HINSTANCE hPrevInst,

                    LPSTR lpszArgs,

                    int nWinMode)

   {

   HWND hwnd;

   MSG msg;

   WNDCLASS wcl;

   HACCEL hAccel;

   // Определить класс окна

   wcl.hInstance=hThisInst;   // Дескриптор приложения

   wcl.lpszClassName=szWinName;  // Имя класса окна

   wcl.lpfnWndProc=WindowFunc;   // Функция окна

   wcl.style=0;                  // Стиль по умолчанию

   wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка 

   wcl.hCursor=LoadCursor(NULL,IDC_ARROW) ;  // Курсор

   wcl.lpszMenuName="MYMENU";                // Меню

   wcl.cbClsExtra=0;             // Без дополнительной

   wcl.cbWndExtra=0;             // информации

   // Определить заполнение окна белым цветом

   wcl.hbrBackground=

                  (HBRUSH)GetStockObject(WHITE_BRUSH);

   if(!RegisterClass(&wcl)) // Зарегистр. класс окна

      return 0;

   // Создать окно

   hwnd=CreateWindow(szWinName,          // Имя класса

                     "Переключение шрифтов", 

                     WS_OVERLAPPEDWINDOW,// Стиль окна

                     CW_USEDEFAULT,    // Х-координата

                     CW_USEDEFAULT,    // Y-координата

                     CW_USEDEFAULT,     // Ширина окна

                     CW_USEDEFAULT,     // Высота окна

                     HWND_DESKTOP,  // Нет родит. окна 

                     NULL,                 // Нет меню

                     hThisInst, // Дескрип. приложения 

                     NULL); // Без дополит. аргументов

   // Загрузить акселераторы

   hAccel=LoadAccelerators(hThisInst,"MYMENU");

   ShowWindow(hwnd,nWinMode) ; // Показать окно и 

   UpdateWindow(hwnd);      // перерисовать содержимое

   // Запустить цикл обработки сообщений

   while(GetMessage (&msg,NULL,0,0))

      if(!TranslateAccelerator(hwnd,hAccel,&msg))

         {

         TranslateMessage(&msg); // Использ.Клавиатуры

         DispatchMessage (&msg); // Возврат к Windows

         }

   return msg.wParam;

   }

 

// Следующая функция вызывается операционной системой

// Windows и получает в качестве параметров сообщения

// из очереди сообщений данного приложения

 

LRESULT CALLBACK WindowFunc(HWND hwnd,

                            UINT message,

                            WPARAM wParam,

                            LPARAM lParam)

   {

   HDC hdc;

   PAINTSTRUCT paintstruct;

   TEXTMETRIC tm;

   SIZE size;

   static fontswitch=0;

   switch(message)

      {

      case WM_CREATE:       // Получаем размеры экрана

         maxX=GetSystemMetrics(SM_CXSCREEN);

         maxY=GetSystemMetrics(SM_CYSCREEN);

         hdc=GetDC(hwnd);   // Совмест. с окном растр

         memdc=CreateCompatibleDC(hdc);

         hbit=CreateCompatibleBitmap(hdc,maxX,maxY);

         SelectObject(memdc,hbit);

         hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);

         SelectObject(memdc,hbrush);

         PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

         // Получить новый шрифт

         hnewf=(HFONT)GetStockObject(ANSI_VAR_FONT);

         ReleaseDC(hwnd,hdc);

         break;

      case WM_COMMAND:

         switch(LOWORD(wParam))

            {

            case ID_SHOW:

               SetTextColor(memdc,RGB(0,0,0)); // Черн

               SetBkMode(memdc,TRANSPARENT); // Не изм

               GetTextMetrics(memdc,&tm);   // Метрики

               sprintf(str,

                       "Высота шрифта %ld пикселей.",

                       tm.tmHeight);

               TextOut(memdc,X,Y,str,strlen(str));

               Y=Y+tm.tmHeight            // Следующая

                  +tm.tmExternalLeading;  // строка

               strcpy(str,"Это следующая строка. ");

               TextOut(memdc,X,Y,str,strlen(str));

               GetTextExtentPoint32(memdc,str, //Длина

                                    strlen(str), 

                                    &size);

               sprintf(str,

                       "Длина предыдущей строки %ld.", 

                       size.cx);

               X=size.cx; // В конец предыдущей строки

               TextOut(memdc,X,Y,str,strlen(str));

               Y=Y+tm.tmHeight            // Следующая

                  +tm.tmExternalLeading;  // строка

               X=0;                // X опять в начало

               sprintf(str,"Размеры экрана %d x %d.",

                       maxX,maxY);

               TextOut(memdc,X,Y,str,strlen(str));

               Y=Y+tm.tmHeight            // Следующая

                  +tm.tmExternalLeading;  // строка

               InvalidateRect(hwnd,NULL,1); //Сообщить

               break;

            case ID_FONT:

               if(!fontswitch)       // На новый шрифт

                  {

                  holdf=

                     (HFONT)SelectObject(memdc,hnewf);           

                  fontswitch=1;

                  }

               else                // На старый шрифт

                  {

                  SelectObject(memdc,holdf); 

                  fontswitch=0;

                  }

               break;

            case ID_RESET:

               X=Y=0;     // Стереть перерисовкой фона

               PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

               InvalidateRect(hwnd,NULL,1); //Сообщить

               break;

            case ID_HELP:

               MessageBox(hwnd,"F2: вывести текст\n"

                               "F3: сменить шрифт\n"

                               "F4: с начала экрана",

                               "Помощь",MB_OK);

               break;

            }

         break;

      case WM_PAINT:               // Перерисовка окна

         hdc=BeginPaint(hwnd,&paintstruct); // Пол. DC

         // Теперь копируем растр из памяти на экран

         BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);

         EndPaint(hwnd,&paintstruct); // Освободить DC

         break;

      case WM_DESTROY:         // Завершение программы  

         DeleteDC(memdc);  // Удалить виртуальное окно

         PostQuitMessage(0);

         break;

      default:

         // Все сообщения, не обрабатываемые в данной

         // функции, направляются на обработку по 

         // умолчанию

         return DefWindowProc(hwnd,message,

                              wParam,lParam);

      }

   return 0;

   }

 

Прежде чем компилировать эту программу, измените предыдущий файл ресурсов так, как показано ниже:

 

#include <Windows.h>

#include "Text.h"

 

MYMENU MENU

   {

   MENUITEM "&Текст",        ID_SHOW

   MENUITEM "&Сначала",      ID_RESET

   MENUITEM "Сменить шрифт", ID_FONT

   MENUITEM "Помощь",        ID_HELP

   }

MYMENU ACCELERATORS

   {

   VK_F2, ID_SHOW,  VIRTKEY

   VK_F3, ID_FONT,  VIRTKEY

   VK_F4, ID_RESET, VIRTKEY

   VK_F1, ID_HELP,  VIRTKEY

   }

 

И, наконец, добавьте еще одну строку в файл Text.h:

 

#define ID_SHOW  100

#define ID_RESET 101

#define ID_FONT  102

#define ID_HELP  103

 

Пример окна этой программы показан на рис. 8.2. Заметьте, что здесь режим рисования фона устанавливается в TRANSPARENT. Таким образом, текст, отображаемый в окне, не изменяет цвет фона.