возвращает целочисленный адрес позиции в окне, где расположены
символ и атрибут. Если окно не видимо, функция возвращает адрес в
буфере сохранения, вычисленный по координатам x и y. Если окно
видимо, сканируется список для поиска окон, более поздних, чем
адресуемое окно. Если более позднее окно закрывает позицию
адресуемого символа, возвращается адрес, соответствующий
сохраненному адресу этого окна. Если ни одно более позднее окно
не закрывает позицию символа, возвращается указатель NULL для
сообщения в точку вызова об использовании видеопамяти.
Функция displ и функция dget вызываются для выдачи и приема
видеосимвола и атрибута в и из слоеного окна. Эти функции
вызывают waddr для проверки необходимости чтения или записи в
область сохранения. Если нет, адресуется видеопамять.
Функция wsvap меняет местами содержимое буфера сохранения
слоеного окна и видеопамяти или, возможно, буферов сохранения
более поздних окон, которые закрывают адресуемое окно. Эта
функция использует displ и dget для выполнения изменения.
Функции vsave и vrstr работают со стековыми окнами. Vsave
копирует содержимое видеопамяти в буфер сохранения, а vrstr
копирует буфер сохранения в видеопамять.
Функция acline вызывается макросами accent и deaccent для
изменения выбранной строки окна на цветовую конфигурацию ACCENT
или NORMAL.
Функция add_list добавляет структуру WINDOW в конец списка.
Функция beg_list добавляет структуру WINDOW в начало списка.
Функция remove_list удаляет структуру WINDOW из списка.
Функция iusert_list вставляет структуру WINDOW в список
после другой заданной структуры WINDOW.
Функция verify_wnd ищет в списке заданный адрес структуры
WINDOW. Она возвращает истину или ложь в зависимости от наличия
или отсутствия структуры WINDOW в списке. Если заданный указатель
WINDOW равен NULL, функция возвращает адрес последней структуры
WINDOW в списке.
Функция error_message создает окно для выдачи специального
сообщения об ошибке. Сообщение записывается в окно вызовом
wprintf, и включается звуковой сигнал.
Функция clear_message очищает последнее сообщение об ошибке.
Примеры окон
-----------------------------------------------------------------
Далее рассматриваются возможности оконной библиотеки.
Приводятся примеры программ, каждая из которых иллюстрирует
рассматриваемые возможности. Примеры состоят из небольшой
управляющей программы с главной функцией, которая вызывает
функцию примера для демонстрируемой возможности. Функция примера
содержит вызовы ранее рассмотренных библиотечных функций и служит
иллюстрацией их использования. Каждый пример программы включает
проектный (.prj) файл, используемый Турбо Си для построения
выполняемой программы.
Затем эти же самые примеры функций будут объединены в один
выполняемый модуль, который демонстрирует оконные меню. Поэтому
они написаны без собственных main-функций.
Перемещение окна
-----------------
При использовании слоеных окон вам доступны функции,
позволяющие перемещать окно в абсолютную или относительную
позицию на экране. Заметим, что эти функции - move_window и rmove
_window - недоступны для стековых окон.
Программа, иллюстрирующая перемещение окна, приведена на
листингах 6.3, 6.4 и 6.5. Листинг 6.3 является маленькой
управляющей программой, а листинг 6.5 представляет проектный make
-файл. Обращайтесь к листингу 6.4, testmove.c, при чтении данного
описания.
Для запуска примера введите следующую команду:
c>move
(В этом и последующих примерах предполагается, что С
является вашим системным дисководом. Не вводите подсказку с>.).
Помимо иллюстрации движения окна, testmove.c показывает
также процесс создания окон, установку их цветов, выдачу на экран
и запись текста в них. Программа создает три окна, присваивает
каждому из них собственные цвета, выдает их и записывает цитату
во второе из трех окон. Этот пример иллюстрирует возможность
записи текста в окно, которое частично закрыто другим окном.
После запуска программы вы увидите на дисплее то, что показано на
рисунке 6.4.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД¬
¦ ¦
¦ C> ¦
¦ ¦
¦ ЪДДДДДДДДДДДДДДДДДДДДДД¬ ¦
¦ ЪДДДДДД¦ I wouldn't care who ¦ ¦
¦ ¦ ¦ wrote the laws if I ¦ ¦
¦ ¦ ¦ could write the ¦ ¦
¦ ¦ ¦ b ЪДДДДДДДДД¬ ¦ ¦
¦ ¦ ¦ ¦ ¦ferson ¦ ¦
¦ ¦ АДДД¦ ГДДДДДДДДЩ ¦
¦ ¦ ¦ ¦ ¦
¦ АДДДДДДДДДДґ ¦ ¦
¦ АДДДДДДДДДЩ ¦
¦ ¦
¦ ¦
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Рисунок 6.4. Перемещение слоеных окон.
Теперь программа ожидает нажатия клавиши. Программа
специально ждет нажатия одной из клавиш управления курсором или
клавиши <Ключ>. Каждое нажатие клавиши со стрелкой вызывает
перемещение окна на одну символьную позицию в направлении
стрелки. Функция rmove_window используется для перемещения окна.
Обратите внимание на то, как центральное окно перемещается между
двумя остальными.
Когда вы нажимаете клавишу <Ключ>, открытое первым окно
уничтожается. Еще одно нажатие вызывает уничтожение верхнего
окна. Заключительное нажатие уничтожает среднее окно с цитатой и
завершает программу.
Перемещение окна иллюстрирует использование оконных буферов
сохранения, запрограммированное в библиотеке. Поскольку требуется
определенная обработка для анализа каждого буфера при записи
символа в окно, работа функций усложняется по мере увеличения
размера окон и их количества. При перемещении большого слоеного
окна на старых медленных моделях ПЭВМ это можно наблюдать
визуально.
Листинг 6.3: move.c
/* move.c */
void testmove(void);
main()
{
testmove();
}
Листинг 6.4: testmove.c
/* testmove.c */
#include "twindow.h "
#include "keys.h"
void testmove()
{
WINDOW *wndA, *wndB, *wndC;
int c;
wndA = establish_window(5, 5, 9, 19);
wndB = establish_window(10, 3, 9, 23);
wndC = establish_window(13, 8, 9, 12);
set_colors(wndA, ALL, RED, YELLOW, BRIGHT);
set_colors(wndB, ALL, AQUA, YELLOW, BRIGHT);
set_colors(wndC, ALL, WHITE, YELLOW, BRIGHT);
display_window(wndA);
displey_window(wndB);
display_window(wndC);
wprintf(wndB, "\n I wouldn't care who");
wprintf(wndB, "\n wrote the laws if I");
wprintf(wndB, "\n could write the");
wprintf(wndB, "\n ballads.");
wprintf(wndB, "\n\n Thomas Jefferson");
do {
int x = 0, y = 0;
c = get_char();
switch (c) {
case FWD: x++;
break;
case BS: --x;
break;
case UP: --y;
break;
case DN: y++;
default: break;
}
if (x || y)
rmove_window(wndB, x, y);
} while (c != ESC);
delete_window(wndA);
get_char();
delete_window(wndC);
get_char();
delete_window(wndB);
}
Листинг 6.5: move.prj
move
testmove (twindow.h, keys.h)
twindow (twindow.h, keys.h)
ibmpc.obj
Подъем и опускание окон
-----------------------
С помощью функций forefront и rear_window вы можете поднять
окно в последнюю позицию, помещая его поверх всех остальных, а
также опустить окно в первую позицию, помещая его под всеми
остальными. Эта возможность применима в программах с несколькими
окнами, где пользователь выбирает одно из них для некоторой цели
путем временного перевода остальных на фон. Эта возможность
полезна в любых приложениях, в которых пользователь часто
переходит от окна к окну.
Программа, иллюстрирующая подъемы и опускания окон,
приведена в листингах 6.6, 6.7 и 6.8. Листинг 6.6 является
маленькой управляющей программой, а листинг 6.8 - проектным make-
файлом. Обращайтесь к листингу 6.7, promote.c, при чтении данных
разъяснений.
Для запуска примера введите следующую команду:
c>prom
Программа promote.c использует те же образцы трех окон, что
и программа testmove.c. Теперь все три окна включают записанный в
них текст, каждый из которых содержит имя окна: window A, window
B и window C. На рисунке 6.5 показан первоначально выданный
экран.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД¬
¦ ¦
¦ C> ¦
¦ ¦
¦ ЪДДДДДДДДДДДДДДДДДДД¬ ¦
¦ ¦ window B ¦ ¦
¦ ЪДДДДДґ ¦ ¦
¦ ¦ ¦ ЪДДДДДДДДДД¬ ¦ ¦
¦ ¦ win ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ АДДДДґ window C ГДДДЩ ¦
¦ ¦ ¦ ¦ ¦
¦ АДДДДДДДДДДґ ¦ ¦
¦ АДДДДДДДДДДЩ ¦
¦ ¦
¦ ¦
¦ ¦
¦ ¦
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Рисунок 6.5. Подъем слоеных окон.
Для подъема и опускания окон используется клавиатура.
Используйте нажатия клавиш с маленькими буквами а, b и с для
подъема окон, названных этими буквами. Используйте клавиши с
большими буквами для их опускания. Этот процесс продолжается до
тех пор, пока вы не нажмете клавишу <Ключ> для уничтожения одного
из окон. Еще два нажатия вызовут уничтожение остальных двух окон,
и программа завершится.
Листинг 6.6: prom.c
/* prom.c */
void promote(void);
main()
{
promote();
}
Листинг 6.7: promote.c
/* promote.c */
#include "twindow.h"
#include "keys.h"
void promote()
{
WINDOW *wndA, *wndB, *wndC;
int c;
wndA = establish_window(5, 5, 9, 19);
wndB = establish_window(10, 3, 9, 20);
wndC = establish_window(13, 8, 9, 12);
set_colors(wndA, ALL, RED, YELLOW, BRIGHT);
set_colors(wndB, ALL, AQUA, YELLOW, BRIGHT);
set_colors(wndC, ALL, WHITE, YELLOW, BRIGHT);
display_window(wndA);
display_window(wndB);
display_window(wndC);
wprintf(wndA, "\n\n Window A");
wprintf(wndB, "\n\n Window B");
wprintf(wndC, "\n\n Window C");
do {
c = get_char();
switch (c) {
case 'a': forefront(wndA);
break;
case 'b': forefront(wndB);
break;