Смекни!
smekni.com

Ознакомление с приложениями Windows (стр. 10 из 18)

· если приложение способно выводить на принтер, то надо иметь в виду, что вместо принтера может оказаться плоттер, который хорошо рисует линии, но совершенно не может выводить растровых изображений, либо АЦПУ, которое способно только печатать текст. Перед выводом рисунков следует проверять возможности данного устройства[13].

Работа с контекстом устройства

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

Собственно существует две группы методов получения контекста устройства — создание и получение контекста устройства. Разница связана с тем, что создание и, позже, уничтожение контекста устройства занимает некоторое время. Если вы собираетесь осуществлять вывод на принтер, то эти затраты времени ничтожно малы по сравнению со всем временем печати. Однако, если вы собираетесь только осуществлять рисование в окне (которое может обновляться очень часто), то даже сравнительно быстрая операция создания контекста, повторенная многократно, займет значительное время. Поэтому в Windows существует несколько заранее созданных контекстов, соответствующих дисплею. При выводе в окно контекст создавать не надо, надо воспользоваться одной из функций, возвращающих такой заранее заготовленный контекст устройства.

Более того, в Windows методы, создающие контекст, предназначены для работы с устройством целиком, а методы, возвращающие уже существующий — с окном. Разница заключается в применении системы координат, связанной с контекстом. В первом случае система координат связана с верхним левым углом устройства, а во втором случае — с верхним левым углом внутренней области окна[14].

Сейчас мы сосредоточимся только на двух способах получения контекста устройства и на некоторых общих правилах применения этого контекста. С первым способом мы уже познакомились — он основан на функциях BeginPaint и EndPaint, а второй на функциях GetDC и ReleaseDC:

HDC GetDC( hWnd );
void ReleaseDC( hWnd, hDC );

Оба способа возвращают заранее заготовленный контекст устройства, однако делают это по разному. Функции BeginPaint и EndPaint предназначены для обработки сообщения WM_PAINT. В других случаях пользоваться этими функциями не рекомендуется. Это связано с тем, что:

· эти функции объявляют окно корректным

· возвращаемый контекст устройства соответствует даже не внутренней области окна, а только неверной области. То есть система координат контекста будет связана с верхним левым углом окна, а вот область рисования будет соответствовать только неверной области. При попытке рисовать на таком контексте все, что не попадает в неверную область, не будет рисоваться. Это сделано для некоторого ускорения перерисовки окна.

· функция BeginPaint дополнительно принимает меры к закраске фона той кисточкой, которая была задана при регистрации класса окна. Это позволяет при разработке обработчика сообщения WM_PAINT не заботиться о закраске фона окна.

Вторая рассматриваемая пара функций (GetDC, ReleaseDC) этих операций не делает, но зато она возвращает контекст для всей внутренней области окна, а не только для неверной области. При необходимости использовать именно эти функции в обработчике сообщения WM_PAINT необходимо самостоятельно принять меры к закраске фона и к объявлению окна корректным.

Все рассматриваемые нами функции для получения контекста устройства приводились в паре — функция для получения и функция для освобождения. Это связано с тем, что применение полученного контекста устройства должно быть ограничено обработкой только текущего сообщения. Оставлять такой контекст занятым нельзя, так как в системе зарезервировано только 8 таких контекстов; если контекст не освободить, то несколько одновременно отображаемых окон (а в Windows почти всегда одновременно работает несколько приложений), могут занять все контексты и при попытке что–то нарисовать в следующем окне возникнет ошибка.

В процессе рисования вы будете постоянно изменять атрибуты контекста — выбирать новые кисти, перья, изменять цвета и режимы рисования и так далее. Все эти изменения действуют только в то время, пока контекст существует. Как только контекст освобождается (или уничтожается, если он был создан), то все изменения, сделанные в его атрибутах, пропадают. Контекст, который вы получаете, практически всегда[15] настроен стандартным образом.

Системы координат Windows

При рисовании на контексте устройства вам придется задавать координаты выводимого текста и изображаемых фигур в определенной системе координат. Система координат, связанная с контекстом устройства — система координат GDI, определяет правила преобразования координат x и y всеми функциями GDI. Вы можете сами определять различные масштабные коэффициенты по обеим осям, задавать положение начала отсчета этой системы координат, либо использовать одну из стандартных систем координат GDI. В главе, посвященной выводу графических изображений на контексте устройства, мы подробнее познакомимся с этими системами координат.

Сейчас же надо выделить несколько основных систем координат, применяемых Windows, и уточнить области применения этих систем координат.

Первая рассматриваемая система координат — система координат менеджера окон. В этой системе ось x направлена по горизонтали направо, ось y — по вертикали вниз. Начало отсчета (0,0) связана либо с верхним левым углом дисплея, либо с верхним левым углом внутренней области родительского окна. Цена одной единицы этой системы координат равна одной единице устройства (пикселю). Для пересчета координат из системы отсчета, связанной с внутренней областью окна в систему отсчета, связанную с экраном (и наоборот) используются функции ClientToScreen и ScreenToClient.

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

При описании панелей диалогов используется своя собственная система координат — система координат панели диалога. В этом случае начало отсчета помещается в верхний левый угол внутренней области панели диалога[16], ориентация осей координат сохраняется прежней, а в качестве единиц отсчета применяют по оси x — одну четвертую от средней ширины символа шрифта, а по оси y — одну восьмую от высоты шрифта. Обычно эти величины примерно соответствуют одному пикселю. Дополнительную информацию можно получить, например, из описания функции MapDialogUnits.

Сложность в применении этой системы координат связана с понятием средней ширины символа. Дело в том, что подавляющее большинство шрифтов является пропорциональными — то есть каждый символ шрифта имеет свою ширину. Для вычисления «средней ширины» применяют ширины символов алфавита, взвешенные с учетом частотности встречи символов в общелитературном тексте. Как правило — английском. Все это может привести к некоторым ошибкам в задании положения и размеров при использовании иного языка, чем английский, особенно если при этом используются нестандартные шрифты. В Windows–95 легко наблюдать этот эффект, изменяя с помощью панели управления (controlpanel) размеры используемых шрифтов и наблюдая за отображением стандартных диалогов.

Как построить приложение

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

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

Как строили Windows–приложения в самом начале

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

Основные сложности были связаны с двумя особенностями приложений для Windows:

· приложение поддерживало динамическую загрузку библиотек. В случае DOS все необходимое для работы приложения находилось в файле образа задачи, а в случае Windows большое количество функций, необходимых приложению, содержится в динамически загружаемых библиотеках (часто это компоненты операционной системы). В таких случаях говорят, что приложение импортирует (import) функции. В то же время приложение должно предоставлять часть своих функций для того, что бы их вызывала операционная система (как, скажем, оконная процедура). В этих случаях говорят, что приложение экспортирует (export) функции.