
- •Введение
- •1. Общие принципы создания интерфейса
- •1.1. Эргономические характеристики интерфейса
- •1.2. Составные части интерфейса
- •1.3. Виды диалога
- •1.4. Процессы ввода – вывода
- •1.5. Методы разработки подпрограмм нижнего уровня
- •Int int86(int num, union regs *inregs, union regs *outregs);
- •Void pokeb(unsigned seg, unsigned off, char value);
- •Int getch();
- •2. Исчезающее меню
- •2.1. Алгоритм создания исчезающего меню
- •2.2. Сохранение и восстановление экрана
- •2.3. Вывод меню и рамки
- •2.4. Определение выбора пользователя
- •2.5. Подпрограмма исчезающего меню
- •3. Иерархическое меню
- •3.1. Фреймы меню
- •3.2. Подпрограмма активизации меню
- •3.3. Организация иерархического меню
- •3.4. Всплывающие окна
- •Void window(int num);
- •Void deactivate(int num);
- •4. Графический интерфейс
- •4.1. Организация меню в графическом режиме
- •Void outtextxy ( int X, int y, char *s);
- •4.2. Организация графического диалога
- •4.3. Особенности графического режима
- •Void putpixel (int color, int X, int y)
- •4.4. Форматы хранения графических файлов
- •5. Прикладной интерфейс для windows
- •5.1. Приложения Windows
- •5.2. Каркас приложения
- •5.3. Обработка сообщений в системе Windows
- •Int ReleaseDc(hwnd hwnd, hdc hdc);
- •Int MessageBox(hwnd hwnd, lpcstr lpText, lpcstr lpCaption, uint wMbType);
- •Int response;
- •5.4. Меню в системе Windows
- •5.5. Диалоги в системе Windows
- •Int DialogBox(hinstance hThisInst,
- •5.6. Пример программы, использующей список и окно ввода
- •6. Лабораторная 1
- •Варианты заданий
- •Пример выполнения задания
- •7 Лабораторная 2
- •Варианты заданий
- •Пример выполнения задания
4.3. Особенности графического режима
В режиме 13h видеопамять можно рассматривать как символьный массив, находящийся по адресу A0000h. Цвет точки (х, у) является байтом этого массива, имеющим индекс 320*у + х. Для вывода точки на экран достаточно записать цвет точки в этот байт, например, операторы:
char far *vid_mem = (char far *) 0xA0000000;
vid_mem + 320*y+x = 2;
приведут к появлению зеленой точки в позиции (х, у). Наша цель – рассмотреть методы записи и чтения точек в режимах 0х10 и 0х12.
Установка графического режима. Напишем подпрограмму, устанавливающую графический режим:
void setvmode (int mode)
{
union REGS r;
r.h.al = mode; r.h.ah = 0;
int86 (0x10, &r, &r);
}
Например, если вызвать setvmode (0x12), то установится режим VGA, 16 цветов, с разрешением 640х480 пикселов.
Отображение пикселов на экране. Вся видеопамять в режимах 10h и 12h, начиная с адреса 0А0000h, делится на 4 части, которые называются цветовыми или битовыми плоскостями. Адрес пиксела в видеопамяти в действительности относится не к одному, а к четырем битовым плоскостям. Команды считывания и записи взаимодействуют с видеопамятью через четыре 8-битовых регистра, каждый из которых относится к одной из битовых плоскостей и называется регистром защелки. Каждая битовая плоскость проектируется на видеопамять. Точка экрана (х, у) цвета i хранится в видеопамяти со смещением
PixelAddr = y*80 + x/8;
ее маска определяет позицию в байте и равна
PixelMask = 0x80>>(x%8).
Например,
при х
= 4 и у
= 0 маска равна
00001000b. Обмен между
видеопамятью и экраном можно представить
схемой (рис. 4.1):
Регистры графического контроллера. Графический контроллер имеет 9 восьмиразрядных регистров. Чтобы записать значения в один из регистров, нужно выполнить 2 команды:
outportb (0x3CE, номер_регистра);
outportb (0x3CF, значение);
Регистры имеют номера и названия, показанные на рис. 4.2:
Номер |
Название |
Значение по умолчанию |
0 |
Set / Reset |
00 |
1 |
Enable Set / Reset |
00 |
2 |
Color Compare |
00 |
3 |
Data Rotate |
00 |
4 |
Read Map Select |
00 |
5 |
Mode |
10h |
6 |
Miscelaneous |
05h |
7 |
Color Don’t Care |
0Fh |
8 |
Bit Mask |
FFh |
Рис.4.2. Регистры графического контроллера
В частности, регистр 5 определяет режимы чтения и записи. Имеется два режима чтения, им соответствуют значения 0 и 1 бита 3 регистра 5, и 4 режима записи, которым соответствуют значения двух младших битов регистра 5. Установка разрядов приводит к изменению режимов чтения и записи. Ниже приведена подпрограмма смены режимов чтения/записи:
void SetRWMode (int ReadMode, int WriteMode)
{
outportb (0x3CE, 5); // в регистр 5
outportb (0x3CF, WriteMode&3+(ReadMode&1)<<3); // записать значение
}
Режим чтения 0. Содержимое четырех битовых плоскостей, соответствующее байту видеопамяти, считывается в четыре регистра защелки. Один из регистров защелки считывается в байт видеопамяти, откуда его можно прочитать, как из обычной памяти, указав номер битовой плоскости в регистре 4.
Пример 1. Для того чтобы прочитать цвет точки, имеющей координаты (х, у), установим сначала режимы чтения и записи с помощью оператора
SetRWMode (0, 0);
а затем вызовем подпрограмму, возвращающую цвет точки:
int readpixel (int x, int y)
{ unsigned char pixelmask, // маска
latch; // для регистра защелки
unsigned int pixeladdr = y*80 + x/8;
int plane, color = 0; pixelmask = 0x80 >> (x%8);
for (plane=3; plane>=0; plane--)
{
outportb (0x3CE, 4); // в регистр 4
outportb (0x3CF, plane); // записать номер битовой плоскости
latch = peekb (0xA000, pixeladdr); latch = (latch&pixelmask)>>(7-x%8);
color = (color<<1)|latch;
}
return color; }
Режим чтения 1. Байт, в который читается байт из видеопамяти, называется байтом центрального процессора. В режиме чтения 1 содержимое четырех битовых плоскостей считывается в четыре регистра защелки. В байт центрального процессора записывается результат сравнения четырех регистров защелки с регистром 2. Пусть, например, регистр 2 равен 1011b. Тогда, если регистры защелки имеют содержимое, показанное на рис 4.3
3 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
2 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
Рис. 4.3. Содержимое регистров защёлки
то значение 1011b будет встречаться в столбцах, соответствующих битам 7, 4 и 1. Поэтому результат чтения в режиме 1 в данном случае равен 10010010b.
Чтобы исключить битовую плоскость из проверки на равенство, надо записать 0 в соответствующий бит регистра 7. В данном случае, чтобы исключить плоскость 2, нужно записать в регистр 7 число 1011b. Результат чтения будет равен 10011010b.
Действия в режиме чтения 1, после вызова функции SetRWMode (1, 0):
-
в регистр 7 записать маску;
-
в регистр 2 записать цвет;
-
прочитать байт, находящийся по адресу 0хА0000000 + у*80 + х/8, он будет результатом чтения.
Режим записи 0. Используются регистры:
-
регистр 0 - установки / сброса;
-
регистр 1 - разрешения установки / сброса;
-
регистр 3 - сдвига данных;
-
регистр 8 - двоичной маски.
Байт процессора может быть использован для обновления любой плоскости битов или всех плоскостей битов, а также для обновления любого из восьми пикселов или всех восьми пикселов.
Регистр двоичной маски указывает, какие биты из восьми могут быть модифицированы. Если некоторый бит в этом регистре равен нулю, то соответствующие ему 4 бита из регистров защелки просто копируются в битовые плоскости. Для каждого бита, равного 1, соответствующие биты регистров защелки объединяются либо с байтом процессора (если регистр 1 равен 0), либо со значением пиксела из регистра 0 (если регистр 1 равен 0Fh). Таким образом, возможны два случая:
-
Регистр 1 равен 0Fh. Регистр 0 действует с помощью операции, заданной в битах 4-3 регистра 3 на все биты регистров защелки. В случае, когда регистр 3 равен нулю, производится копирование цвета, заданного в регистре 0 во все точки, адресуемые байтом процессора, для которых биты двоичной маски равны 1.
Например,
в случае, когда регистр 0 равен 0101b,
а регистр 8 равен 00011111b,
в битовые плоскости запишутся
преобразованные данные, представленные
на рис 4.4.
В данном случае копирование производится в режиме COPY_PUT. Если биты 4-3 регистра 3 содержат число 01, то запись производится с преобразованием AND_PUT, число 10 – OR_PUT, число 11 – XOR_PUT. Для того чтобы записать точки заданного цвета на экран, в этом режиме необходимо произвести действия:
-
в регистр 1 записать 0Fh;
-
в регистр 0 записать цвет;
-
в регистр 8 записать маску;
-
записать любой байт по адресу 0хА0000000+80у+х/8;
-
восстановить исходные значения регистров 1 и 8.
Пример 2. Напишем подпрограмму записи точки цвета color в позицию (х, у):