Перерисовка изображения
Рассмотрим следующую абстракцию, цель которой — показать, что за содержимое
окон на экране отвечают оконные процедуры тех приложений, которым эти окна
принадлежат. Роль Windows в этом процессе минимальна и состоит в том, что при
определенных действиях с окном оконной процедуре, отвечающей за связь с этим
окном, посылается сообщение WM_PAINT. Получив это сообщение, оконная проце-
дура должна уметь заново перерисовать содержимое всего окна или
части. Для
общего случая это, если задуматься, не такая уж простая задача.
Если у вас возникают трудности с пониманием этого момента работы приложе-
ний в Windows, попробуйте развить абстракцию со школьной доской. Представь-
те себе школьный класс, в котором процесс обучения выглядит очень необычно.
Вместо обычной школьной доски на стене есть некоторая ограниченная область
(экран монитора). У каждого ученика (исполняемого файла) есть в портфеле своя
доска (окно приложения), которая может (или не может, в зависимости от кон-
струкции) менять свой размер. На всех учеников один комплект цветных мелков
(контекст устройства), обладание которым разрешает ученику что-то рисовать на
своей доске. Ученик объясняется с присутствующими графическими образами,
выводя их на свою доску. Но прежде доску нужно повесить на стену в пределах
ограниченной области. Для этого ученик, как ему и положено, подымает руку. Учи-
тель (Windows) обязательно помогает ученику выйти к
области на
стене (запускает на выполнение задачу) и повесить свою доску. Действия учителя
и ученика в ходе этого процесса соответствуют определенному алгоритму и дей-
Глава
Создание Windows-приложений на ассемблере
каркасного приложения. В результате могут быть закрыты частично или
полностью доски учеников, вышедших к доске ранее и не ушедших пока на свои
места в классе. При этом информация в скрытых частях расположенных ниже до-
сок других учеников уничтожается в пределах ограниченной области.
Итак, доска ученика с помощью учителя повешена в пределах области на стене,
и для того чтобы рисовать на ней, ученик должен попросить у учителя комплект
мелков (см. функцию API GetDC или BeginPaint в листинге 16.4). Если ученик его
получает, то он может начинать процесс рисования на своей доске. Как только уче-
ник
этот процесс, он должен вернуть учителю комплект мелков (функ-
ция
Далее ученик может закончить ответ и, забрав свою доску, занять
свое место в классе (приложение завершило работу и «ушло» на диск). Если уче-
ник делает это, то, забирая свою доску, он открывает доски других учеников, и... на
этих досках обнаруживаются черные дыры, причем местоположение этих дыр со-
ответствует местам, которые были скрыты доской их ушедшего
Чтобы
сгладить этот конфуз, учитель срочно оповещает об этом (Windows посылает со-
общение WM_PAINT) учеников, у которых было испорчено содержимое досок. Каж-
дый из этих учеников должен, попросив у учителя комплект мелков, перерисовать
содержимое своей доски.
Данная абстракция довольно точно отражает логику работы Windows, причем
не только в обозначенном нами контексте. Вы можете дополнить и развить ее
в нужную вам сторону.
Как решается проблема перерисовки изображения практически? Для этого су-
ществует несколько способов, самый общий из которых заключается в использо-
вании
окна. Суть перерисовки изображения на основе виртуального
окна заключается в использовании приложением некоторой области памяти для
направления в него всего вывода программы. Реальный вывод в окно приложения
осуществляется только как реакция на получение сообщения
He забы-
вайте, что программа с помощью функции
может сама себе послать
сообщение
когда ей потребуется вывести новый фрагмент изображения
в окно приложения. Понятие виртуального окна настолько важно для организа-
ции работы Windows, что Win32 API содержит ряд функций, поддерживающих
работу с этим окном:
и
Рассмотрим порядок их использования в реаль-
ном приложении.
Работа с виртуальным окном в программе организуется в два этапа: создание
виртуального окна и организация непосредственной работы с ним. Создать вирту-
альное окно целесообразно при обработке сообщения
то есть в момент
создания окна приложения. Работать с этим окном можно в любое время, когда
требуется вывод в окно.
Для наглядности обсуждения приведем фрагмент программы на языке C/C++:
оконной процедуры из программы на языке C/C++
case
размеры экрана
maxX =
=
растровое изображение, совместимое с окном
Углубленное программирование на ассемблере для Win32
= GetDC
= CreateCompatibleDC
=
(hdc,
SelectObject (memdc,
окно серым цветом
=
SelectObject (memdc,
(memdc, 0, 0, maxX, maxY,
ReleaseDC (hwnd,
case
окно
hdc =
(hwnd,
дескриптор реального окна
растровое изображение из памяти на экран
(hdc, 0, 0, maxX, maxY, memdc, 0, 0,
E n d P a i n t (hwnd,
дескриптор
*
в окно где-то в программе
X, Y, str,
строку
немедленного вывода в окно вызываем функцию
InvalidateRect (hwnd, NULL,
Физически виртуальное окно представляет собой растровое изображение, хра-
нящееся в памяти. Работа с этой областью памяти организуется так же, как и с ок-
ном приложения на экране монитора. Это означает, что для работы с ним необхо-
димо создать контекст устройства памяти, совместимый с контекстом окна. Это
действие реализуется двумя функциями: с помощью функции
приложе-
ние получает контекст окна; функция
создает совместимый
с контекстом окна контекст памяти memdc. После этого функцией
создается совместимое с реальным окном на экране растровое изобра-
жение. Его размеры должны соответствовать размеру окна, для работы с которым
оно строится. Поэтому предварительно с помощью функции
должны быть получены размеры окна и переданы как параметры в функцию
которая возвращает дескриптор на созданное растровое
изображение. После этого функция
выбирает созданное растровое
изображение в контекст памяти, который, в свою очередь, является совместимым
с контекстом окна. Благодаря такой цепочке связей обращение к растровому изоб-
ражению в памяти производится аналогично
к реальному окну. На
практике это означает, что во всех функциях, выводящих изображение в окно, на
месте параметра, соответствующего контексту устройства, необходимо указывать
контекст устройства памяти. Например, функция
будет вызываться сле-
дующим образом:
push
push offset
push 150
push 10
push
TextOutA
В пятой строке этого фрагмента функции TextOutQ передается не контекст окна,
а контекст виртуального окна, что и приводит к выводу не в реальное окно, а в вир-
туальное, являющееся растровым изображением. Как мы уже отметили, в програм-
есть только одно место, где производится вывод в реальное окно, — это фраг-
мент программы, обрабатывающий сообщение WM_PAINT. В случае виртуального
Глава 16. Создание Windows-приложений на ассемблере
окна здесь располагается функция
которая копирует содержимое
растрового изображения из контекста памяти в контекст реального окна. Таким
образом постоянно обеспечивается актуальное содержимое окна приложения.
В листинге 16.8 приведены фрагменты текста программы на языке ассембле-
ра, демонстрирующей практическую реализацию способа перерисовки окна при-
ложения с использованием виртуального окна. Полный текст программы находится
среди файлов, прилагаемых к книге, в каталоге
данной главы.
Do'stlaringiz bilan baham: |