Жанр: Учеба

Техника программирования на турбо-С

сторінка №5

ла

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

В случае использования Монохромного Адаптера значение байта
атрибутов немного отличается от описанного выше. Поскольку
возможность использования различных цветов не поддерживается
контроллером МА, то разрешены только комбинации белого символа
на черном фоне или черного символа на белом фоне. Другие коды
цвета дают комбинации черного на черном или белого на белом.
Хотя следует отметить, что комбинация голубого символа и
черного фона формирует изображение подчеркнутого символа, что не
поддерживается уже контроллером CGA. Монохромный Адаптер, как и
CGA, поддерживает возможности задания интенсивности цвета и
режима мерцания символа.

Поскольку вы теперь знаете, где размещена видеопамять и что
в нее может быть записано, то можете использовать программу pokes
из библиотеки Турбо Си для формирования изображения на экране
дисплея. Ниже приводится листинг 5.1 маленькой программы под
названием vidpoke.c, которая записывает строку непосредственно в
видеопамять. Исходя из предположения, что на вашей машине
работает контроллер CGA, программа формирует для каждого символа
байт атрибута со значением 7, что соответствут отображению строки
в виде белых символов на черном фоне. Если вы используете
Монохромный Адаптер, измените в строке # define VSEG значение с
0xB800 на 0xB000.

Листинг 5.1: vidpoke.c

/* vidpoke.c */

#define VSEG 0x6800
char vdata [] = "Что сделал Кан?";
main()
{
char *vp;
int v;
for (v=0, vp = vdata; *vp; v +=2, vp++)
poke ( VSEG, v, 0x700| *vp);
}

"Снег" и обратный ход луча развертки
-----------------------------------------------------------------

Если вы запустите программу vidpoke.exe в цикле или
значительно увеличите длину выводимой строки, то сможете увидеть
на экране так называемый "снег", который появляется при
выполнении программы. Вы будете наблюдать "снег" только в случае
использования контроллера CGA или его аналога. Контроллеры ЕGA и
МА не дают подобного эффекта. Из нижеследующих объяснений вы
узнаете, почему возникает "снег" и как его можно устранить
программнми средствами.

"Снег" возникает при использовании контроллера CGA из-за
особенностей аппаратной архитектуры видеосистемы. Поскольку и
микропроцессор, и видеоконтроллер обращаются к одной видеопамяти,
то в случае одновременного обращения возникает необходимость в
координировании доступа к памяти. Работа видеоконтроллера
синхронизирована по времени с работой схемы развертки. Во время
формирования элемента изображения на экране видеоконтроллер
должен иметь доступ к ячейке памяти, которая содержит бит,
соответствующий этому элементу изображения. Видеопроцессор при
этом не может ждать, поскольку он жестко синхронизирован с
устройством формирования растра. Следовательно, если
видеоконтроллер и микропроцессор пытаются одновременно
обратиться к одной и той же ячейке памяти, то видеоконтроллер
должен иметь при этом более высокий приоритет. В хорошо
разработанной системе микропроцессор будет находиться в состоянии
ожидания, при котором запросы микропроцессора к видеопамяти не
поступают. В контроллерах МА и EGA использован этот принцип, и
вы можете не беспокоиться о конфликтных ситуациях между
микропроцессором и видеоконтроллером при доступе к видеопамяти.

Но в контроллере CGA в символьном режиме этого не выполняется,
поэтому вы должны сами предпринимать некоторые действия.

В случае использования контроллера CGA, если микропроцессору
нужно обратиться к видеопамяти для чтения или записи, то это ему
разрешается, а видеоконтроллеру доступ на это время запрещается.
А поскольку работа видеоконтроллерМZШ +
  
Эit$—

Глава 6


-------

Библиотека оконных функций
-----------------------------------------------------------------

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

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

При компиляции оконных функций, вы должны принять решение о
том, какую именно оконную конфигурацию применить. Для стековых
окон определяется переменная времени компиляции FASTWINDOWS, для
слоеных окон она удаляется. Прикладная программа может быть
связана с любой библиотекой до тех пор, пока она не использует
возможности, поддерживаемые только для слоеных окон. Те
прикладные программы, которые используют возможности
исключительно слоеных окон, должны быть связаны с библиотекой
оконных функций, которая была компилирована без определения
FASTWINDOWS.

Стековые окна
-----------------------------------------------------------------

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

Вы будете обычно обращаться только к стековому окну,
образованному последним. Если вы сначала создали окно А, а затем
окно В, которое закрывает часть окна А, то при записи текста в
окно А может случиться, что часть текста попадет в часть окна В,
закрывающую окно А. Далее, если вы уничтожите окно A до
уничтожения окна В, то часть буфера сохранения окна А
запишется в начало части окна В.

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

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

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

Слоеные окна
-----------------------------------------------------------------

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

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

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

Рассмотрим рисунок 6.1. Три окна расположены так, что часть
окна А видима, часть закрыта окном В и часть - окном С. В буферах
сохранения каждого окна вы можете видеть границы частей других
окон, которые закрыты.

----------------------------------------------------------------¬
¦ ¦
¦ .------------¬ ¦
¦ . ¦ ¦ ¦
¦ . +-----------+ Буфер ¦
¦ . ¦ ¦ сохранения В ¦
¦ . ¦ ¦ ¦
¦ . ¦ ¦ ¦
¦ . L------------ ¦
¦ . . ¦
¦ . ¦
¦ . . ¦
¦ -----------¬ ¦
¦ -----+ B +----¬ . ¦
¦ ¦ A ¦ ¦ ¦ . ¦
¦ ¦ ¦ -----+----+---¬. . ¦
¦ ¦ ¦ ¦ C ¦. . ¦
¦ ¦ L-----¦ ¦ . ¦
¦ L----------¦ ¦ . ¦
¦ ¦ ¦ . ¦
¦ ¦ ¦ -------T----------T---¬ ¦
¦ L-------------- ¦ ¦ ¦ ¦ ¦
¦ . ¦ ¦ ¦ ¦ ¦
¦ . ¦ ¦ ¦ ¦ ¦
¦ . +------- ¦ ¦ ¦
¦ . +------------------ ¦ ¦
¦ . L---------------------- ¦
¦ Буфер сохранения С ¦
¦ ¦
L----------------------------------------------------------------

Рисунок 6.1. Три слоеных перекрывающихся окна.

Если вы запишите текстовую строку "now is the time" в окно
А, текст будет направлен в три различных места. Результат показан
на рисунке 6.2. Так как часть окна А, где записано "now",
является видимой, то слово записывается непосредственно в
видеопамять и может быть прочитано пользователем. Слова "is the"
являются частью окна А, которая закрыта окном В, поэтому эти
слова записываются в буфер сохранения окна В. Слово "time"
оказывается в той части окна А, которая покрыта окном С,
следовательно "time" записывается в буфер сохранения окна С.

----------------------------------------------------------------¬
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ . ----------¬ ¦
¦ . +---------+ ¦
¦ . ¦ is the ¦ Буфер сохранения В ¦
¦ . ¦ ¦ ¦
¦ --------¬ L---------- ¦
¦ --------+ B +------¬ . ¦
¦ ¦ A ¦ ---+------+-¬. . ¦
¦ ¦ now ¦ ¦ C ¦. . ¦
¦ ¦ L----+ ¦ . ¦
¦ L------------+ ¦ ------T--------T--¬ ¦
¦ L------------ ¦ ¦ time ¦ ¦ ¦
¦ . +------ ¦ ¦ ¦
¦ . +--------------- ¦ ¦
¦ . L------------------ ¦
¦ Буфер сохранения С ¦
¦ ¦
L----------------------------------------------------------------

Рисунок 6.2. Слоеные окна с текстом.

Рисунок 6.3. показывает, что происходит при уничтожении окна
В. Часть окна А из его буфера сохранения поступает в
видеопамять, и слово "is" может теперь быть прочитано
пользователем. Однако, поскольку часть окна В была покрыта окном
С, то часть буфера сохранения окна В копируется в буфер
сохранения окна С, следовательно, буфер сохранения окна С теперь
содержит слова "the time".

----------------------------------------------------------------¬
¦ ¦
¦ ¦
¦ ¦
¦ ¦
¦ -----------------------¬ ¦
¦ ¦ A ----------+------¬ . ¦
¦ ¦ ¦ C ¦ . ¦
¦ ¦ now is ¦ ¦ . ¦
¦ ¦ ¦ ¦ . ¦
¦ L------------+ ¦ --------------------T--¬ ¦
¦ L----------------- ¦ the time ¦ ¦ ¦
¦ . ¦ ¦ ¦ ¦
¦ . ¦ ¦ ¦ ¦
¦ . +-------------------- ¦ ¦
¦ . L----------------------- ¦
¦ Буфер сохранения С ¦
¦ ¦
L----------------------------------------------------------------

Рисунок 6.3. Уничтожение слоеного окна.

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

Оконные функции
-----------------------------------------------------------------

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

WINDOW *establish_window(x,y,h,w)
---------------------------------

Эта функция создает окно, но не отображает его. (Для показа
окна воспользуйтесь функцией display_window). Параметры x и y
являются координатами верхнего левого угла окна. Эти параметры
выражаются в символьных позициях экрана, где координаты левого
верхнего угла самого экрана равны (0,0). Параметры h и w являются
высотой и шириной окна в символьных позициях. Эта функция не
вызовет никакого изменения экрана. Если вы создадите окно,
позиция и размеры которого не позволяют ему быть полностью
видимым, программное обеспечение установит позицию, при которой
оно полностью поместится на экране. Если ширина больше 80 или
высота больше 25, функция преобразует соответствующий размер до
максимально допустимого значения.

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

Окна располагаются в обратном порядке по отношению к их
созданию. Окно, созданное самым последним, является верхним окном
экрана и будет (при выдаче) закрывать окна, созданные ранее. Эта
иерархия зависит от порядка, в котором окна образуются, а не от
порядка их показа.

Функция establish_window возвращает указатель на структуру
WINDOW, которая определена во включаемом файле twindow.h. Этот
указатель используется при последующих вызовах оконных функций
для идентификации окна, к которому относится вызов. Передавайте
указатель NULL другим оконным функциям, если хотите работать с
окном, образованным последним.

void set_border(WINDOW *wnd, int btype)
---------------------------------------

Эта функция устанавливает тип оконной рамки. Целочисленный
параметр btype должен принимать одно из следующих значений:

. 0 - одинарные линии (по умолчанию);
. 1 - двойные линии;
. 2 - одинарные верх и низ, двойные боковые;
. 3 - двойные верх и низ, одинарные боковые;
. 4 - специальное проталкиваемое вниз окно меню с одинарными
линиями и t-блоком от верхнего левого до верхнего
правого угла.

void set_colors(WINDOW *wnd, int area, int bg, int fg, int inten)
-----------------------------------------------------------------

Эта функция устанавливает цвета для окна. Параметр area
может принимать следующие значения:

. ALL
. BORDER
. TITLE
. ACCENT
. NORMAL

Этот параметр определяет части окна, на которые
распространяется действие. ALL соответствует всем частям. BORDER
устанавливает цвета рамки окна, которая занимает односимвольный
ряд позиций вокруг него. TITLE устанавливает цвета заголовка,
размещаемого на верхней границе окна. ACCENT - это область,
используемая для блоков меню и другого выделенного текста,
который появляется в качестве временно подсвечиваемых частей
области NORMAL, где отображается весь текст. Целые числа bg и
fg задают цвета для фона и переднего плана различных частей
окна. Допускаются следующие цвета:

. RED - алый;
. GREEN - зеленый;
. BLUE - голубой;
. WHITE - белый;
. YELLOW - желтый;
. AQUA - аквамариновый;
. MAGENTA - красный;
. BLACK - черный.

Целое число inten определяет интенсивность символов
переднего плана и может принимать два значения:

. BRIGHT - яркая
. DIM - обычная

Все значения определены в исходном файле twindow.h, который
рассматривается позже в этой главе.

void set_title(WINDOW *wnd, char *title)
----------------------------------------

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

void set_intensity(WINDOW *wnd, int inten)
------------------------------------------

Эта функция устанавливает интенсивность фона для всех частей
окна. Значениями inten могут быть BRIGHT или DIM.

void display_window(WINDOW *wnd)
--------------------------------

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

void delete_window(WINDOW *wnd)
-------------------------------

Эта функция уничтожает созданное ранее окно. Если окно
является видимым (выдано с помощью display_window), то оно
очищается, и экран восстанавливается к его предыдущему образу.

void clear_window(WINDOW *wnd)
------------------------------

Эта функция заполняет текстовую область окна пробелами.

void hide_window(WINDOW *wnd)
-----------------------------

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

void wcursor(WINDOW *wnd, int x, int y)
---------------------------------------

Каждое окно обладает логической позицией курсора, которая
изменяется от 0,0 (верхний левый угол текстовой области окна) до
граничных размеров окна. Эта функция переставляет курсор в окне.

Функции wputehar и wprintf выдают текст относительно данной
позиции курсора. Они изменяют позицию курсора точно также, как
это происходило бы, если бы управление курсором осуществлялось с
помощью клавиатуры дисплея. Символ новой строки (\n)
устанавливает курсор в нулевой столбец следующей строки,
перемещая текст в окне вверх на одну строку, если курсор уже
находится в нижней строке окна. Символ табуляции (\t) перемещает
курсор к следующей позиции табуляции в окне. Табуляции
располагаются с интервалом в четыре символа.


void wprintf(WINDOW *wnd, char *fmt, ...)
-----------------------------------------

Эта функция является оконной версией стандартной функции
printf языка Си. Она использует стандартную функцию sprintf для
построения строки, выдаваемой в окно. Убедитесь, что
результирующая строка не длиннее 100 символов, или измените длину
в массиве dlin функции wprintf в исходном файле twindow.c.

void wputchar(WINDOW *wnd, int ch)
----------------------------------

Эта функция является оконной версией putchar. Она записывает
символ из ch в окно в текущую позицию курсора. Курсор при этом
продвигается дальше. Если символ является символом новой строки
(\n), курсор переставляется в нулевую позицию следующей строки.
Если символ является табуляцией (\t), курсор продвигается к
следующей позиции табуляции окна. Оконные позиции табуляции
располагаются в каждой четвертой позиции окна.

void reverse_video(WINDOW *wnd)
-------------------------------

После обращения к этой функции все вызовы wprintf и wputchar
будут при отображении использовать цвета ACCENT вместо NORMAL.

void normal_video(WINDOW *wnd)
------------------------------

После обращения к этой функции все вызовы wprintf и wputchar
будут при отображении использовать цвета NORMAL. Эта функция
используется для возврата к нормальному отображению после вызова
reverse_video.

void close_all()
----------------

Эта функция уничтожает все образованные окна.

void move_windom(WINDOW *wnd, int x, int y)
-------------------------------------------

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

void rmove_window(WINDOW *wnd, int x, int y)
--------------------------------------------

Эта функция перемещает окно путем добавления к значениям x и
y текущих координат левого верхнего угла окна. Используйте эту
функцию только для слоеных окон.

void forefront(WINDOW *wnd)
-------------

Список сторінок

Поділитися у соцмережах

☏ Замовлення реклами: +3805044-68-872

© Асоціація електронних бібліотек України

☝ Усі матеріали сайту (зокрема статті, зображення, рекламні оголошення тощо) призначені лише для попереднього ознайомлення. Усі права на публікації, представлені на сайті, належать їхнім законним власникам. Просимо Вас не зберігати копії інформації.