Оконные координаты, цвета, отображение строк




Московская финансово-промышленная академия

 

 

Емельянов А.А.

Сальников Ю.Н.

Емельянова Н.З.

Основы программирования для
информатиков и инженеров.

Часть 2 (продолжение): Прикладное программирование в Windows

 

 

Москва, 2004


УДК 681.3.06

ББК 24.4.9

Е 60

 

Емельянов А.А., Сальников Ю.Н., Емельянова Н.З. Основы программирования для информатиков и инженеров. Часть 2: Прикладное программирование в Windows / Под ред. проф. А.А. Емельянова. – М.: МФПА, 2004. – 351 с.

 

Рецензенты:

1) Шориков Андрей Федорович, д.ф.-м.н., профессор, зав. кафедрой Информационных систем в экономике, Уральский государственный экономический университет, г. Екатеринбург.

2) Кафедра Информационных систем в экономике и управлении, Санкт-Петербургский государственный инженерно-экономичес-кий университет (ИНЖЭКОН).

 

 

В первой части книги в систематической форме излагаются основы программирования Windows-приложений на языках С/С++. Подробно рассмотрены возможности операционной системы в части API. Даются рекомендации: как надо программировать, как разрабатывать программу, как ее писать. Практические примеры различной сложности ориентированы на работу в среде Microsoft Visual C++.

Все учебные проекты, изложенные в книге, отлажены авторами в Windows XP (всего – 42 проекта различной сложности). Поэтому книга может быть хорошей основой для создания практикумов по дисциплинам «Операционные системы, среды и оболочки», «Высокоуровневые методы информатики и программирования», «Архитектура информационных систем».

Рекомендовано учебно-методическим объединением вузов по образованию в области прикладной информатики в качестве учебного пособия студентам, обучающимся по специальностям «Прикладная информатика в экономике» и «Информационные системы».

 

 

Ó Емельянов А.А., 2004

Ó Сальников Ю.Н., 2004

Ó Емельянова Н.З., 2004

Ó Московская финансово-промышленная академия, 2004

 

Глава 8. Виртуальное окно: работа с текстом

8.1. Оконные координаты, цвета, отображение строк

8.2. Виртуальное окно

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

8.4. Создание собственных шрифтов

 

Глава 9. Программирование графики

9.1. Логическая система координат

9.2. Пиксели, линии, дуги, прямоугольники, эллипсы и секторы

9.3. Работа с перьями и кистями

9.4. Технология виртуального окна

9.5. Режимы отображения и области вывода

 

Глава 10. Работа с панелями инструментов

10.1. Общие элементы управления

10.2. Подключение и инициализация общих элементов управления

10.3. Работа с панелью инструментов

10.4. Создание растрового изображения для панели инструментов

10.5. Включение подсказок

 

Глава 11. Спины, ползунки и индикаторы процессов

11.1. Работа со спином

11.2. Создание спина с «приятельским» окном

11.3. Работа с ползунком

11.4. Индикатор процесса

 

Глава 12. Многозадачность: процессы и потоки

12.1. Создание нового процесса (отдельной задачи)

12.2. Многопотоковые программы

12.3. Работа с несколькими потоками

12.4. Синхронизация процессов и потоков: семафоры

12.5. Обработка событий

 

Глава 13. Приемы программного управления вычислительным процессом

13.1. Использование функций Проводника Explorer для работы в файловой системе

13.2. Создание собственных динамических библиотек (dll-файлов)

13.3. Работа с буфером обмена Clipboard

 

Литература

 


Глава 8. Виртуальное окно: работа с текстом

 

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

Что же касается других аспектов программирования в среде Windows, то нужно сказать, что программист имеет практически неограниченные возможности по управ­лению выводом текста в рабочей области окна. Естественно, в этой главе невозможно описать все аспекты работы с текстом в Windows. Однако она содержит достаточно информации, используя которую Вы сможете без труда разобраться во всех остальных вопросах, связанных с манипулированием текстом.

В начале главы вводится понятие системы координат в окне. Затем описываются основные функции API, использующиеся для работы с текстом и с экраном, которые позволяют управлять выводом текста в рабочей области окна.

 

Оконные координаты, цвета, отображение строк

 

Оконные координаты. Как известно, TextOut() является стандартной функцией вывода текста в Win­dows. Она выводит текст в заданных координатах, которые всегда указываются относительно начала рабочей области окна. Таким образом, координаты строки, выводимой при помощи TextOut(), не зависят от положения самого окна на экране. По умолчанию координаты начала (верхнего левого угла) рабочей области равны нулю. Координата по оси X увеличивается при движении вправо, а координата по оси Y – при движении вниз.

До сих пор при задании координат в функции TextOut() и для позиционирования элементов в диалоге нас не интересовали единицы измерения координат. Сейчас следует подробнее рассмотреть этот вопрос. Прежде всего отметим, что координаты, задаваемые в TextOut(), являются логическими координатами. То есть единицы измерения координат для TextOut() (и любых других функций, отображающих что-либо на экране, включая функции вывода фафики, которые описаны в следую­щей главе) являются логическими единицами. В процессе вывода изображения на экран Windows преобразует логические единицы в пикселы. До сих пор нам не нужно было беспокоиться по этому поводу, поскольку по умолчанию логические единицы как раз и являются пикселами. Однако следует иметь в виду, что в Windows можно использовать различные режимы отображения (mappind modes), в которых подобное умолчание не работает.


Установка цветов текста и фона. При использовании функции TextOut() текст отображается на экране черным цветом на текущем фоне окна. Существует также возможность явного задания цвета текста и фона для него с помощью функций API SetTextColor() и SetBkColor():

 

COLORREF SetTextColor(HOC hdc, COLORREF color);

COLORREF SetBkColor (HDC hdc, COLORREF color);

 

Функция SetTextColor устанавливает текущий цвет текста для устройства, ассоциированного с контекстом hdc. Цвет задается параметром color (при этом устройство может выбирать реальный цвет, ближайший к задаваемому, который оно в состоянии отобразить). Функция SetBkColor() устанавливает цвет фона текста (или ближайший к нему возможный для устройства), задаваемый параметром color. Обе функции возвращают предыдущую установку соответствующего цвета, а при возник­новении ошибки – значение CLR_INVALID.

Цвет задается 32-битовым целым типа COLORREF. Windows позволяет задать цвет тремя различными способами. Первый, и наиболее общий, способ заключается в задании RGB-значения (Red, Green, Blue). RGB-значение комбинирует относительные интенсивности трех различных цветов, в результате чего получается реальный цвет. Второй способ определения цвета предполагает задание индекса цвета в логической палитре, а третий заключается в определении RGB-значения относитель­но текущей логической палитры. В этой главе используется только первый способ задания цвета.

Длинное целое, хранящее RGB-значение и передаваемое в качестве параметра в функции SetTextColor() и SetBkColor(), кодируется следующим образом (табл. 8.1.):

 

Таблица 8.1

Кодировка RGB-значений

 

Байт Цвет
  Байт 0 (младший) Красный
  Байт 1 Зеленый
  Байт 2 Синий
  Байт 3 (старший) Должен быть 0

 

Интенсивность каждого цвета в RGB-значении может задаваться в диапазоне от О до 255, причем значение 0 определяет минимальную, а значение 255 – максималь­ную интенсивность задаваемого цвета. Например, следующее длинное целое задает фиолетовый («марганцовочный» – magenta) цвет:

       

 


Хотя RGB-значения можно формировать вручную, в Windows определен макрос RGB(), предназначенный для этих целей:

COLORREF RGB(int red, int green, int blue);

Здесь значения Red, Ggreen и Blue должны принадлежать диапазону от 0 до 255. Таким образом, для задания марганцовочного цвета можно использовать RGB(255,0,255). Белый цвет задается при помощи RGB(255,255,255), а черный – при помощи RGB(0,0,0). Для задания других цветов необходимо комбинировать три базовых цвета с различной интенсивностью. Например, RGB(0,100,100) задает темный серо-голубой цвет. Вы можете поэкспериментировать с различными комбинациями RGB и определить наиболее подходящие цвета для своего приложения.

Установка режима отображения фона. Способом отображения фона при выводе текста можно управлять с помощью функции API SetBkMode():

 

int SetBkMode(HDC hdc, int mode);

 

Эта функция определяет, что произойдет с текущим цветом фона при выводе текста (и некоторых других видов графики). Режим отображения фона определяется параметром mode, который может задаваться одним из двух макросов: OPAQUE или TRANSPARENT. Функция возвращает значение предыдущего режима отображения фона или 0 в случае возникновения ошибки. Если значение mode равно OPAQUE, цвет фона при выводе текста каждый раз будет меняться на текущий цвет фона, заданный функцией SetBkColor(). Если mode равно TRANSPARENT, цвет фона при выводе текста не изменяется. В этом случае установка текущего цвета фона функцией SetBkColor() не дает никакого видимого эффекта. По умолчанию способ отображения фона задается как OPAQUE.

Получение метрик текста. Большинство шрифтов в Windows являются пропорциональными, поэтому сим­волы одного и того же кегля могут иметь различную ширину. Кроме того, высота символов и размер нижних выносных элементов (например, как у букв р и g) могут быть различными у разных шрифтов. Разными могут быть и расстояния между строками текста. Однако то, что эти (и многие другие) атрибуты шрифта могут изменяться, в данном случае не имеет большого значения; важно лишь то, что Windows требует, чтобы программист самостоятельно управлял практически всем процессом отображения текста.

Windows обеспечивает только минимальную поддержку отображения текста в рабочей области окна. Основной функцией вывода текста является TextOut(). Эта функция лишь выводит строку текста на экран, начиная с заданной позиции. Она никак не форматирует выводимый текст и даже не выполняет операции возврата каретки (CR) или перехода на новую строку (LF). Управление выводом текста в рабочую область окна полностью возлагается на программиста.

То обстоятельство, что размеры шрифтов могут быть разными (и что сами шрифты могут изменяться в процессе выполнения программы), предполагает, что должен существовать способ определения атрибутов текущего шрифта. Например, чтобы вывести на экран новую строку текста под выведенной строкой, необходимо определить высоту шрифта и интервал между строками. Функция API, с помощью которой приложение может получить информацию о текущем шрифте, называется GetTextMetrics() и имеет следующий прототип:

 

BOOL GetTextMetrics(HDC hdc, LPTEXTMETRIC lpTAttrib);

 

Здесь hdc является дескриптором контекста устройства отображения, который может быть получен при помощи функций GetDC() или BeginPaint(), a lpTAttrib должен быть указателем на структуру типа TEXTMETRIC, которая при успешном завершении функции будет содержать все параметры (метрики) выбранного шрифта. Структура TEXTMETRIC определяется следующим образом:

 

typedef struct tagTEXTMETRIC

{

LONG tmHeight; // Полная высота шрифта (кегль)

LONG tmAscent; // Высота над основной линией

LONG tmDescent; // Размер нижнего выступа

LONG tmlnternalLeading; // Размер верхнего выступа

LONG tmExternalLeading; // Межстрочный интервал

LONG tmAveCharWidth; // Средняя ширина символа

LONG tmMaxCharWidth; // Максимальная ширина символа

LONG tmWeight; // Насыщенность шрифта

LONG tmOverhang; // Дополнительная ширина символа

// - для специальных шрифтов

LONG tmDigitizedAspectX; // Горизонтальный аспект

LONG tmDigitizedAspectY; // Вертикальный аспект

BYTE tmFirstChar; // Первый символ

BYTE tmLastChar; // Последний символ

BYTE tmDefaultChar; // Символ по умолчанию

BYTE tmBreakChar; // Символ для обозн.границы слова

BYTE tmItalic; // Не 0, если шрифт наклон.(italic)

BYTE tmUnderlined; // Не 0, если буквы подчеркнуты

BYTE tmStruckOut; // Не 0, если буквы зачеркнуты

BYTE tmPitchAndFamily; // Семейство и гарнитура

BYTE tmCharSet; // Идентификатор множества символов

}

 

Большинство атрибутов шрифтов, получаемых программой с помощью этой функции, в примерах данной главы не используется. Сейчас для нас важны только те, которые применяются для определения расстояния между строками текста. Это значение понадобится, если Вы захотите вывести в окно несколько строк текста. В отличие от консольного приложения, использующего всегда только один шрифт фиксированного размера, в окне можно использовать несколько шрифтов. При этом каждый шрифт может иметь свой размер и межстрочный интервал. А это, в свою очередь, означает, что нельзя предварительно определить вертикальную (Y) коорди­нату следующей строки. Поэтому для определения начала следующей строки необ­ходимо вызвать функцию GetTextMetrics() и получить значения высоты символа и межстрочного интервала. Эти значения хранятся в полях tmHeight и tmExternalLeading соответственно. Сложив их, получаем расстояние между строками в логических единицах.

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

Имеется также расширенная, с несколькими дополнительными полями в конце, версия структуры TEXTMETRIC, которая называется NEWTEXTMETRIC. Дополни­тельные поля предназначены для поддержки работы с TrueType-шрифтами, обеспе­чивающими более широкие возможности масштабирования, поворотов и других операций над шрифтами. Вот эти новые поля:

 

DWORD ntmFlags; // Индикатор типа шрифта

UINT ntmSizeEM; // Размер комбинации em

UINT ntmCellHeight; // Высота шрифта

UINT ntmAvgWidth; // Средняя ширина символа

 

И хотя эти поля не используются в данной главе, в дальнейшем они могут сыграть важную роль при написании Ваших собственных приложений. Более подробную информацию о них Вы найдете в Руководстве Программиста по функциям и структурам данных API.

 

Определение длины строки. Поскольку различные символы одного и того же шрифта могут иметь разную ширину, нельзя определить длину строки текста в логических единицах, исходя только из информации о количестве выводимых символов. Поэтому результат функции strlen() не позволяет управлять выводом текста в окне. Для этих целей в Windows предусмотрена функция API GetTextExtentPoint32(), которая имеет следующий прототип:

 

BOOL GetTextExtentPoint32(HDC hdc, LPCSTR lpszString,

int len, LPSIZE lpSize);

 

 

Здесь hdc определяет контекст устройства вывода. Параметр lpszString задает указатель на строку, длину которой в логических единицах Вы хотите узнать. Параметр lenзадает количество символов в этой строке. Вычисленные ширина и высота строки текста в логических единицах записываются в структуру SIZE, указатель на которую задается параметром lpSize. Структура SIZE определяется следующим образом:

 

typedef struct tagSIZE

{

LONG cx; // Ширина

LONG су; // Высота

} SIZE;

 

После возврата из функции GetTextExtentPoint32() поле сх структуры SIZE содержит длину строки. Таким образом, это значение можно использовать для определения начала следующей строки в том случае, если Вы хотите выводить следующую строку, начиная с того места, где заканчивается предыдущая.

 

Получение системных метрик. Хотя Windows автоматически воспринимает и преобразует логические координа­ты в пиксели, Вам иногда может понадобиться определить реальные размеры и другие параметры экрана компьютера, на котором запускается Ваше приложение. Для получения этой информации используется функция API GetSystemMetrics():

 

int GetSystemMetrics(int what);

 

Параметр what определяет величину, которую Вы хотите получить. Размеры элементов экрана указываются в пикселях. В таблице 8.2. приведены некоторые макросы для полу­чения этих величин.

 

Таблица 8.2



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-03-31 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: