скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыУчебное пособие: Ознакомление с приложениями 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 легко наблюдать этот эффект, изменяя с помощью панели управления (control panel) размеры используемых шрифтов и наблюдая за отображением стандартных диалогов.

 

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

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

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

 

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

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

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

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

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

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

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

В тех случаях, когда приложение нуждалось в собственных ресурсах, необходимо было отдельно описать эти ресурсы в специальном текстовом файле описания ресурсов (rc–файле). Вместе с компиляторами до сих поставляется специальный компилятор ресурсов RC.EXE, который воспринимает файл описания ресурсов, компилирует его и создает файл ресурсов приложения (res–файл). Затем тот–же компилятор ресурсов может объединить уже построенный выполняемый файл с файлом ресурсов приложения.

Таким образом построение приложения состояло из следующих этапов:

·   разработка исходных текстов — .c, .cpp, .h, .hpp, .rc и .def файлы;

·   компиляция исходного текста программы — из .c и .cpp получаем .obj (иногда .lib);

·   компиляция ресурсов приложения — из .rc получаем .res;

·   компоновка приложения — из .obj и .lib получаем .exe;

·   встраивание ресурсов приложения в выполняемый файл — из .exe и .res получаем рабочий .exe.

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

Следующий этап

Очевидно, что необходимость перечислять кучу имен функций в файле описания приложения никого не приводила в восторг. Поэтому на следующем этапе была включена поддержка Windows–приложений непосредственно в компиляторы[17]. Для этого было добавлено ключевое слово _export (иногда __export), которое применяется при описании экспортируемых функций непосредственно в тексте C–программы. Для таких функций компилятор включает в объектный файл специальную информацию, так что компоновщик может правильно собрать выполняемый файл. Так, например, было сделано в первом примере для оконной процедуры:

  LRESULT WINAPI _export proc( ...

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

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

Библиотеки со списками функций, которые можно импортировать из Windows (то есть экспортированных компонентами Windows) входят в состав всех компиляторов. Иногда может возникнуть необходимость использования нестандартного компонента (или собственной динамически загружаемой библиотеки), для которых соответствующей библиотеки с ссылками нет. В таком случае можно воспользоваться специальным приложением — implib.exe — которое входит в состав большинства компиляторов (если его нет в составе компилятора, то значит его возможности реализованы в каком–либо другом инструменте, как, например, wlib.exe в Watcom C/C++). Implib позволяет по имеющемуся файлу динамически загружаемой библиотеки (.dll) или файлу описания проекта модуля библиотеки (.def), содержащему список экспортированных функций, построить библиотечный файл (.lib), с ссылками на функции библиотеки.

Первоначально, стремясь максимально уменьшить время загрузки модулей в память, при экспортировании функций им присваивались уникальные номера (назначаются разработчиком, либо просто по порядку). Конкретная функция однозначно определяется именем экспортирующей библиотеки динамической загрузки и идентификатором функции. Для задания идентификаторов экспортируемых функций используется файл описания модуля. Однако использование номеров вместо имен является не слишком удобным для человека, поэтому в Windows используются оба метода — функции доступны как по их идентификаторам, так и по их именам. Для Windows API общепринятым методом считается использование идентификаторов Microsoft следит за тем, что бы все  документированные функции сохраняли свои идентификаторы. А в Win32 API предполагается использование имен; более того, Microsoft не гарантирует, что идентификаторы документированных функций не будут изменяться.

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

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

Если вы используете какую–либо систему поддержки проектов (Watcom IDE, Microsoft Developer Studio, Borland IDE, Symantec IDE и пр.) — а скорее всего это именно так — то вы должны только проследить за тем, что бы необходимые файлы были включены в проект. Система сама отследит, как и когда должен использоваться тот или иной исходный файл.

Обычно в проект включаются следующие файлы:

·   исходные тексты на C и C++ — файлы с расширениями .c, .cpp, .c++;

·   файл, содержащий ресурсы приложения, как правило только один, либо .rc либо .res;

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.