Использование библиотеки Graph


Начиная с версии 4.0, в состав Турбо Паскаля включена мощная библиотека графических подпрограмм Graph, остающаяся практически неизменной во всех последующих версиях. Библиотека содержит в общей сложности более 50 процедур и функций, предоставляющих программисту самые разнообразные возможности управления графическим экраном. Для облегчения знакомства с библиотекой все входящие в нее процедуры и функции сгруппированы по функциональному принципу.
 
Переход в графический режим и возврат в текстовый
Стандартное состояние ПК после его включения, а также к моменту запуска программы из среды Турбо Паскаля соответствует работе экрана в текстовом режиме, поэтому любая программа, использующая графические средства компьютера, должна определенным образом инициировать графический режим работы дисплейного адаптера. После завершения работы программы ПК возвращается в текстовый режим.
 
Краткая характеристика графических режимов работы дисплейных адаптеров
Настройка графических процедур на работу с конкретным адаптером достигается за счет подключения нужного графического драйвера. Драйвер - это специальная программа, осуществляющая управление теми или иными техническими средствами ПК. Графический драйвер, как это не трудно догадаться, управляет дисплейным адаптером в графическом режиме. Графические драйверы разработаны фирмой Borland практически для всех типов адаптеров. Обычно они располагаются на диске в отдельном подкаталоге BGI в виде файлов с расширением BGI (от англ.: Borland Graphics Interface - графический интерфейс фирмы Borland). Например, CGA.BGI - драйвер для CG4-адаптера, EGA VGA.BGI - драйвер для адаптеров EGA и VGA и т.п.
Выпускаемые в настоящее время ПК оснащаются адаптерами, разработанными фирмой IBM, или совместимыми с ними. Если не учитывать уже упоминавшийся в гл.13 монохромный адаптер MDA, все они имеют возможность работы в графическом режиме. В этом режиме экран дисплея рассматривается как совокупность очень близко расположенных точек - пикселей, светимостью которых можно управлять с помощью программы.
Графические возможности конкретного адаптера определяются разрешением экрана, т.е. общим количеством пикселей, а также количеством цветов (оттенков), которыми может светиться любой из них. Кроме того, многие адаптеры могут работать с несколькими графическими страницами. Графической страницей называют область оперативной памяти, используемая для создания «карты» экрана, т.е. содержащая информацию о светимости (цвете) каждого пикселя. Ниже приводится краткая характеристика графических режимов работы наиболее распространенных адаптеров.
Адаптер CGA (Color Graphics Adapter - цветной графический адаптер) имеет 5 графических режимов. Четыре режима соответствуют низкой разрешающей способности экрана (320 пикселей по горизонтали и 200 по вертикали, т.е. 320x200) и отличаются только набором допустимых цветов - палитрой. Каждая палитра состоит из трех цветов, а с учетом черного цвета несветящегося пикселя - из четырех: палитра 0 (светло-зеленый, розовый, желтый), палитра 1 (светло-бирюзовый, малиновый, белый), палитра 2 (зеленый, красный, коричневый) и палитра 3 (бирюзовый, фиолетовый, светло-серый). Пятый режим соответствует высокому разрешению 640x200, но каждый пиксель в этом случае может светиться либо каким-то одним заранее выбранным и одинаковым для всех пикселей цветом, либо не светиться вовсе, т.е. палитра этого режима содержит два цвета. В графическом режиме адаптер CGA использует только одну страницу.
Адаптер EGA (Enhanced Graphics Adapter - усиленный графический адаптер) может полностью эмулировать графические режимы адаптера CGA. Кроме того, в нем возможны режимы: низкого разрешения (640x200, 16 цветов, 4 страницы) и высокого разрешения (640x350, 16 цветов, 1 страница). В некоторых модификациях используется также монохромный режим (640x350, 1 страница, 2 цвета).
Адаптер MCGA (Multi-Color Graphics Adapter - многоцветный графический адаптер) совместим с CGA и имеет еще один режим - 640x480, 2 цвета, 1 страница. Такими адаптерами оснащались младшие модели серии ПК PS/2 фирмы IBM. Старшие модели этой серии оснащаются более совершенными адаптерами VGA (Video Graphics Array -графический видеомассив. Адаптер VGA эмулирует режимы адаптеров CGA и EGA и дополняет их режимом высокого разрешения (640x480, 16 цветов, 1 страница).
Не так давно появились так называемые cynep-VGA адаптеры (SVGA) с разрешением 800x600 и более, использующие 256 и более цветовых оттенков. В настоящее время эти адаптеры получили повсеместное распространение, однако в библиотеке Graph для них нет драйверов. Поскольку SVGA совместимы с VGA, для управления современными графическими адаптерами приходится использовать драйвер EGAVGA.BGI и довольствоваться его относительно скромными возможностями.
Несколько особняком стоят достаточно популярные адаптеры фирмы Hercules. Адаптер HGC имеет разрешение 720x348, его пиксели могут светиться одним цветом (обычно светло-коричневым) или не светиться вовсе, т.е. это монохромный адаптер. Адаптер HGC+ отличается несущественными усовершенствованиями, а адаптер HIСС (Hercules In Color Card) представляет собой 16-цветный вариант HGC+.
 
Процедуры и функции
Процедура InitGraph. Инициирует графический режим работы адаптера. Заголовок процедуры:
Procedure InitGraph(var Driver,Mode: Integer; Path: String);
Здесь Driver - переменная типа Integer, определяет тип графического драйвера; Mode - переменная того же типа, задающая режим работы графического адаптера; Path - выражение типа String, содержащее имя файла драйвера и, возможно, маршрут его поиска.
К моменту вызова процедуры на одном из дисковых носителей информации должен находиться файл, содержащий нужный графический драйвер. Процедура загружает этот драйвер в оперативную память и переводит адаптер в графический режим работы. Тип драйвера должен соответствовать типу графического адаптера. Для указания типа драйвера в модуле предопределены следующие константы:
const
Detect=0;{Режим автоопределения типа}
CGA=1;
MCGA=2;
EGA=3;
EGA64=4;
EGAMono=5;
IBM8514=6;
HercMono=7;
ATT400=8;
VGA=9;
PC3270=10;
Большинство адаптеров могут работать в различных режимах. Для того, чтобы указать адаптеру требуемый режим работы, используется переменная Mode, значением которой в момент обращения к процедуре могут быть такие константы:


const

 

 

{ Адаптер CGA : }

 

 

CGACO = 0;

{Низкое разрешение, палитра

0}

CGAC1 = 1;

{Низкое разрешение, палитра

1}

CGAC2 = 2;

{Низкое разрешение, палитра

2}

CGAC3 = 3;

{Низкое разрешение, палитра

3}

CGAHi = 4;

{Высокое разрешение}

 

{Адаптер MCGA:}

 

 

MCGACO = 0;

{Эмуляция CGACO}

 

MCGAC1 = 1;

{Эмуляция CGAC1}

 

MCGAC2 = 2;

{Эмуляция CGAC2}

 

MCGAC3 = 3;

{Эмуляция CGAC3}

 

MCGAMed = 4;

{Эмуляция CGAHi}

 

MCGAHi = 5;

{640x480}

 

{Адаптер EGA :}

 

 

EGALo = 0;

{640x200, 16 цветов}

 

EGAHi = 1;

{640x350, 16 цветов}

 

EGAMonoHi = 3;

{640x350, 2 цвета}

 

{Адаптеры HGC и

HGC+:}

 

HercMonoHi = 0;

{720x348}

 

{АдаптерАТТ400:}

 

ATT400CO = 0;

{Аналог режима CGACO}

 

ATT400C1 = 1;

(Аналог режима CGAC1}

 

ATT400C2 = 2;

{Аналог режима CGAC2}

 

ATT400C3 = 3;

{Аналог режима CGAC3}

 

ATT400Med = 4;

{Аналог режима CGAHi}

 

ATT400H1 = 5;

{640x400, 2 цвета}

 

{Адаптер VGA:}
VGALo = 0;            {640x200}
VGAMed = 1;           {640x350}
VGAHi = 2;            {640x480}
PC3270H1 = 0;         {Аналог HercMonoHi}
{Адаптер 1ВМ8514}
IBM8514LO =0;      {640x480, 256 цветов}
IBM8514H1 = 1;     {1024x768, 256 цветов}
Пусть, например, драйвер CGA.BGI находится в каталоге TP\BGI на диске С и устанавливается режим работы 320x200 с палитрой 2. Тогда обращение к процедуре будет таким:
Uses Graph; 
var
Driver, Mode : Integer; 
begin
Driver := CGA;{Драйвер}
Mode := CGAC2;{Режим работы}
InitGraph(Driver, Mode,' С:\TP\BGI') ;
.......
Если тип адаптера ПК неизвестен или если программа рассчитана на работу с любым адаптером, используется обращение к процедуре с требованием автоматического определения типа драйвера:
Driver := Detect;
InitGraph(Driver, Mode, 'C:\TP\BGI');
После такого обращения устанавливается графический режим работы экрана, а при выходе из процедуры переменные Driver и Mode содержат целочисленные значения, определяющие тип драйвера и режим его работы. При этом для адаптеров, способных работать в нескольких режимах, выбирается старший режим, т.е. тот, что закодирован максимальной цифрой. Так, при работе с CGA -адаптером обращение к процедуре со значением Driver = Detect вернет в переменной Driver значение 1 (CGA) и в Mode -значение 4 (CGAHi), а такое же обращение к адаптеру VGA вернет Driver = 9 (VGA) и Mode = 2 (VGAHi).
Функция GraphResult. Возвращает значение типа Integer, в котором закодирован результат последнего обращения к графическим процедурам. Если ошибка не обнаружена, значением функции будет ноль, в противном случае - отрицательное число, имеющее следующий смысл:
const
grOk = 0;{Нет ошибок} 
grlnitGraph =-1;{He инициирован графический режим} 
grNotDetected =-2;{Не определен тип драйвера} 
grFileNotFind =-3;{Не найден графический драйвер} 
grlnvalidDriver =-4;{Неправильный тип драйвера}
grNoLoadMem =- 5;{Нет памяти для размещения драйвера}
grNoScanMem = - 6;{Нет памяти для просмотра областей}
grNoFloodMem =- 7;{Нет памяти для закраски областей}
grFontNotFound = -8;{Не найден файл со шрифтом}
grNoFontMem =- 9;{Нет памяти для размещения шрифта}
grlnvalidMode =-10;{Неправильный графический режим}
grError =-11;{Общая ошибка}
grIOError =-12;{Ошибка ввода-вывода}
grlnvalidFont =-13;{Неправильный формат шрифта}
grInvalidFontNum=-14; {Неправильный номер шрифта}
После обращения к функции GraphResult признак ошибки сбрасывается, поэтому повторное обращение к ней вернет ноль.
Функция GraphErrorMsg.
Возвращает значение типа String, в котором по указанному коду ошибки дается соответствующее текстовое сообщение. Заголовок функции:
Function GraphErrorMsg(Code: Integer): String;
Здесь Code - код ошибки, возвращаемый функцией GraphResult.
Например, типичная последовательность операторов для инициации графического режима с автоматическим определением типа драйвера и установкой максимального разрешения имеет следующий вид:
var
Driver, Mode, Error:Integer; 
begin
Driver := Detect;{Автоопределение драйвера} 
InitGraph(Driver, Mode,' ');{Инициируем графику}
Error := GraphResult;{Получаем результат}
if Error <> grOk then{Проверяем ошибку} 
begin{Ошибка в процедуре инициации}
WriteLn(GraphErrorMsg(Error));{Выводим сообщение}
.......
end 
else{Нет ошибки}
.......
Чаще всего причиной возникновения ошибки при обращении к процедуре InitGraph является неправильное указание местоположения файла с драйвером графического адаптера (например, файла CGA.BGI для адаптера CGA). Настройка на местоположение драйвера осуществляется заданием маршрута поиска нужного файла в имени драйвера при вызове процедуры InitGraph. Если, например, драйвер зарегистрирован в подкаталоге DRIVERS каталога PASCAL на диске D, то нужно использовать вызов:
InitGraph(Driver, Mode, 'd:\Pascal\Drivers');
Замечание. Во всех следующих примерах процедура InitGraph вызывается с параметром Driver в виде пустой строки. Такая форма обращения будет корректна только в том случае, когда нужный файл графического драйвера находится в текущем каталоге. Для упрощения повторения примеров скопируйте файл, соответствующий адаптеру Вашего ПК, в текущий каталог.
Процедура CloseGraph.
Завершает работу адаптера в графическом режиме и восстанавливает текстовый режим работы экрана. Заголовок:
Procedure CloseGraph;
Процедура RestoreCRTMode.
Служит для кратковременного возврата в текстовый режим. В отличие от процедуры CloseGraph не сбрасываются установленные параметры графического режима и не освобождается память, выделенная для размещения графического драйвера. Заголовок:
Procedure RestoreCRTMode;
Функция GetGraphMode.
Возвращает значение типа Integer, в котором содержится код установленного режима работы графического адаптера. Заголовок:
Function GetGraphMode: Integer;
Процедура SetGraphMode.
Устанавливает новый графический режим работы адаптера. Заголовок:
Procedure SetGraphMode(Mode: Integer);
Здесь Mode - код устанавливаемого режима.
Следующая программа иллюстрирует переход из графического режима в текстовый и обратно:
Uses Graph;
var .
Driver, Mode, Error : Integer; 
begin
{Инициируем графический режим}
Driver := Detect;
InitGraph(Driver, Mode, '');
Error := GraphResult; {Запоминаем результат}
i£ Error <> grOk then {Проверяем ошибку}
WriteLn(GraphErrorMsg(Error)) {Есть ошибка} 
else 
begin {Нет ошибки}
WriteLn ('Это графический режим'); 
WriteLn ('Нажмите "Enter"...':20); 
ReadLn;
{Переходим в текстовый режим} 
RestoreCRTMode;
WriteLn (' А это текстовый...'); 
ReadLn;
{Возвращаемся в графический режим} 
SetGraphMode (GetGraphMode); 
WriteLn ('Опять графический режим...'); 
ReadLn; 
CloseGraph 
end 
end.
В этом примере для вывода сообщений как в графическом, так и в текстовом режиме используется стандартная процедура WriteLn. Если Ваш ПК оснащен нерусифицированным адаптером CGA, вывод кириллицы в графическом режиме таким способом невозможен, в этом случае замените соответствующие сообщения так, чтобы использовать только латинские буквы.
Процедура DetectGraph.
Возвращает тип драйвера и режим его работы. Заголовок: 
Procedure DetectGraph(var Driver,Mode: Integer);
Здесь Driver - тип драйвера; Mode - режим работы.
В отличие от функции GetGraphMode описываемая процедура возвращает в переменной Mode максимально возможный для данного адаптера номер графического режима.
Функция GetDriverName.
Возвращает значение типа String, содержащее имя загруженного графического драйвера. Заголовок:
Function GetDriverName: String;
Функция GetMaxMode.
Возвращает значение типа Integer, содержащее количество возможных режимов работы адаптера. Заголовок:
Function GetMaxMode: Integer;
Функция GetModeName.
Возвращает значение типа String, содержащее разрешение экрана и имя режима работы адаптера по его номеру. Заголовок:
Function GetModName(ModNumber: Integer): String;
Здесь ModNumber - номер режима.
Следующая программа после инициации графического режима выводит на экран строку, содержащую имя загруженного драйвера, а также все возможные режимы его работы.
Uses Graph; 
var
a,b: Integer; 
begin
a := Detect;
InitGraph(a, b, '');
WriteLn(GetDriverName);
for a := 0 to GetMaxMode do 
WriteLn(GetModeName(a):10);
ReadLn;
CloseGraph 
end.
Процедура GetModeRange.
Возвращает диапазон возможных режимов работы заданного графического адаптера. Заголовок:
Procedure GetModeRange(Drv: Integer; var Min, Max: Integer);
Здесь Drv - тип адаптера; Min - переменная типа Integer, в которой возвращается нижнее возможное значение номера режима; Мах - переменная того же типа, верхнее значение номера.
Если задано неправильное значение параметра Drv, процедура вернет в обеих переменных значение -1. Перед обращением к процедуре можно не устанавливать графический режим работы экрана. Следующая программа выводит на экран названия всех адаптеров и диапазоны возможных номеров режимов их работы.
Uses Graph; 
var
D,L,H: Integer; 
const
N: array [1..11] of String [8] =
('CGA ', 'MCGA ', 'EGA ', 
'EGA64 ', 'EGAMono ', ЧВМ8514 ', 
'HercMono', 'ATT400 ', 'VGA ', 
'PC3270 ', 'Ошибка '); 

begin
WriteLn('Адаптер Мин. Макс.'); 
for D := 1 to 11 do 
begin
GetModeRange(D, L, H); 
WriteLn(N[D], L:7, H:10) 
end 
end.
 
Координаты, окна, страницы
Многие графические процедуры и функции используют указатель текущей позиции на экране, который в отличие от текстового курсора невидим. Положение этого указателя, как и вообще любая координата на графическом экране, задается относительно левого верхнего угла, который, в свою очередь, имеет координаты 0,0. Таким образом, горизонтальная координата экрана увеличивается слева направо, а вертикальная - сверху вниз.
Функции GetMaxX и GetMaxY.
Возвращают значения типа Word, содержащие максимальные координаты экрана в текущем режиме работы соответственно по горизонтали и вертикали. Например:
Uses Graph; 
var
a,b: Integer; 
begin
a := Detect; InitGraph(a, b, ''); 
WriteLn(GetMaxX, GetMaxY:5);
ReadLn; 
CloseGraph 
end.
Функции GetX и GetY.
Возвращают значения типа Integer, содержащие текущие координаты указателя соответственно по горизонтали и вертикали. Координаты определяются относительно левого верхнего угла окна или, если окно не установлено, экрана.
Процедура SetViewPort.
Устанавливает прямоугольное окно на графическом экране. Заголовок:
Procedure SetViewPort(XI,Y1,X2,Y2: Integer; ClipOn: Boolean);
Здесь X1...Y2 - координаты левого верхнего (XI,Y1) и правого нижнего (X2,Y2) углов окна; СНрОп - выражение типа Boolean, определяющее «отсечку» не умещающихся в окне элементов изображения.
Координаты окна всегда задаются относительно левого верхнего угла экрана. Если параметр ClipOn имеет значение True, элементы изображения, не умещающиеся в пределах окна, отсекаются, в противном случае границы окна игнорируются. Для управления этим параметром можно использовать такие определенные в модуле константы:
const
ClipOn = True; {Включить отсечку} 
ClipOff = False; {He включать отсечку}
Следующий пример иллюстрирует действие параметра СНрОп. Программа строит два прямоугольных окна с разными значениями параметра и выводит в них несколько окружностей. Для большей наглядности окна обводятся рамками (см.  1).
Uses Graph,CRT; 
var
x,y,e: Integer;
xll,yll,xl2,yl2, {Координаты 1-го окна}
x21,x22, {Левый верхний угол 2-го}
R, {Начальный радиус}
k: Integer; 
begin
DirectVideo := False {Блокируем прямой доступ к видеопамяти в модуле CRT}
{Инициируем графический режим}  
х := Detect; InitGraph(x, у, ''); 
{Проверяем результат} 
е := GraphResult; if e <> grOk then
WriteLn(GraphErrorMsg (e) ) {Ошибка} 
else
begin {Нет ошибки}
{Вычисляем координаты с учетом разрешения экрана}
x11:=GetMaxX div 60; 
x12:=GetMaxX div 3; 
y11:=GetMaxY div 4; y12:=2*y11;
R:=(x12-x11) div 4; x21:=x12*2;
x22:=x21+x12-x11; 
{Рисуем окна}
WriteLnt'ClipOn:':10,'ClipOff:':40); 
Rectangle(x11, y11, x12, y12); Rectangle(x21, y11 x22, y12);
{Назначаем 1-е окно и рисуем четыре окружности} 
SetViewPort(x11, y11, x12, y12, ClipOn); 
for k := 1 to 4 do
Circle(0,y11,R*k);
{Назначаем 2-е окно и рисуем окружности} 
SetViewPort(x21, y11, x22, y12, ClipOff); 
for k := 1 to 4 do
Circle(0,y11,R*k); 
{Ждем нажатия любой клавиши}
if ReadKey=#0 then k := ord(ReadKey); 
CloseGraph 
end 
end.
Процедура GetViewSettings.
Возвращает координаты и признак отсечки текущего графического окна. Заголовок:
Procedure GetViewSettings(var Viewlnfo: ViewPortType);
Здесь Viewlnfo - переменная типа ViewPortType. Этот тип в модуле Graph определен следующим образом:
type
ViewPortType = record
x1,y1,x2,y2: Integer; {Координаты окна} 
Clip : Boolean {Признак отсечки}
end ;
Процедура MoveTo.
Устанавливает новое текущее положение указателя. Заголовок:
Procedure MoveTo(X,Y: integer);
Здесь X, Y - новые координаты указателя соответственно по горизонтали и вертикали.
Координаты определяются относительно левого верхнего угла окна или, если окно не установлено, экрана.
Процедура MoveRel.
Устанавливает новое положение указателя в относительных координатах.
Procedure MoveRel(DX,DY: Integer);
Здесь DX.DY- приращения новых координат указателя соответственно по горизонтали и вертикали.
Приращения задаются относительно того положения, которое занимал указатель к моменту обращения к процедуре.
Процедура ClearDevice.
Очищает графический экран. После обращения к процедуре указатель устанавливается в левый верхний угол экрана, а сам экран заполняется цветом фона, заданным процедурой SetBkColor. Заголовок:
Procedure ClearDevice;
Процедура ClearViewPort.
Очищает графическое окно, а если окно не определено к этому моменту - весь экран. При очистке окно заполняется цветом с номером О из текущей палитры. Указатель перемещается в левый верхний угол окна. Заголовок:
Procedure ClearViewPort;
В следующей программе на экране создается окно, которое затем заполняется случайными окружностями ( 2). После нажатия на любую клавишу окно очищается. Для выхода из программы нажмите Enter.
Uses CRT,Graph; 
var
x1,y1,x2,y2,Err: Integer; 
begin
{Инициируем графический режим} 
xl := Detect; InitGraph(xl,x2,''); 
Err := GraphResult; if ErrogrOk then
WriteLn(GraphErrorMsg(Err)) 
else
begin
{Определяем координаты окна с учетом разрешения экрана} 
x1 := GetMaxX div 4,-y1 := GetMaxY div 4; 
x2 := 3*x1; y2 := 3*y1; 
{Создаем окно}
Rectangle(x1,y1,x2,y2);
SetViewPort(x1+1,y1+1,x2-1,y2-1,ClipOn); 
{Заполняем окно случайными окружностями} 
repeat
Сirclе(Random(Ge tMaxX),Random(Ge tMaxX)
Random(GetMaxX div 5)) 
until KeyPressed;
{Очищаем окно и ждем нажатия Enter} 
ClearViewPort;
OutTextXY(0,0,'Press Enter...1); 
ReadLn; 
CloseGraph 
end 
end.
Процедура GetAspectRatio.
Возвращает два числа, позволяющие оценить соотношение сторон экрана. Заголовок:
Procedure GetAspectRatio(var X,Y: Word);
Здесь X, Y - переменные типа Word. Значения, возвращаемые в этих переменных, позволяют вычислить отношение сторон графического экрана в пикселях. Найденный с их помощью коэффициент может использоваться при построении правильных геометрических фигур, таких как окружности, квадраты и т.п. Например, если Вы хотите построить квадрат со стороной L пикселей по вертикали, Вы должны использовать операторы
GetAspectRatio (Xasp, Yasp);
Rectangle(x1, y1, x1+L*round (Yasp/Xasp), y1+L);
а если L определяет длину квадрата по горизонтали, то используется оператор 
Rectangle (x1,y1,x1+L,y1+L*round(Xasp/Yasp));
Процедура SetAspectRatio.
Устанавливает масштабный коэффициент отношения сторон графического экрана. Заголовок:
Procedure SetAspectRatio(X,Y: Word);
Здесь X, Y- устанавливаемые соотношения сторон.
Следующая программа строит 20 окружностей с разными соотношениями сторон экрана ( 3).
Uses Graph,CRT; 
const
R =.50;
dx = 1000; 
var
d,m,e,k : Integer;
Xasp,Yasp: Word; 
begin
d := Detect;
InitGraph(d, m,.'');
e : = GraphResult;
if e <> grOk then
WriteLn(GraphErrorMsg(e)) 
else
begin
GetAspectRatio(Xasp, Yasp); 
for k := 0 to 20 do 
begin
SetAspectRatio(Xasp+k*dx,Yasp); 
Circle(GetMaxX div 2,GetMaxY div 2,R) 
end;
if ReadKey=#0 then k := ord(ReadKey); 
CloseGraph 
end 
end.
Процедура SetActivePage.
Делает активной указанную страницу видеопамяти. Заголовок:
Procedure SetActivePage(PageNum: Word);
Здесь PageNum - номер страницы.
Процедура может использоваться только с адаптерами, поддерживающими многостраничную работу (EGA, VGA и т.п.). Фактически процедура просто переадресует графический вывод в другую область видеопамяти, однако вывод текстов с помощью Write/WriteLn всегда осуществляется только на страницу, которая является видимой в данный момент (активная страница может быть невидимой). Нумерация страниц начинается с нуля.
Процедура SetVisualPage.
Делает видимой страницу с указанным номером. Обращение:
Procedure SetVisualPAge(PageNum: Word);
Здесь PageNum - номер страницы.
Процедура может использоваться только с адаптерами, поддерживающими многостраничную работу (EGA, VGA и т.п.). Нумерация страниц начинается с нуля.
Следующая программа сначала рисует квадрат в видимой странице и окружность -в невидимой. После нажатия на Enter происходит смена видимых страниц.
Uses Graph;
var
d,m,e: Integer; 
s : String; 
begin
d := Detect; InitGraph(d, m, ''); 
e := GraphResult; if e <> grOk then
WriteLn (GraphErrorMsg(e)) 

else {Нет ошибки. Проверяем, поддерживает ли драйвер многостраничную работу с видеопамятью:} 
if d in [HercMono,EGA,EGA64,MCGA,VGA] then 
begin {Используем многостраничный режим} 
if d<>HercMono then 
SetGraphMode(m-1); 
{Заполняем видимую страницу}
Rectangle(10,10,GetMaxX div 2,GetMaxY div 2); 
OutTextXY(0,0,'Page 0. Press Enter...'); 
{Заполняем невидимую} 
SetActivePage (1);
Circle(GetMaxX div 2, GetMaxY div 2, 100); 
OutTextXY(0,GetMaxY-10,'Page 1. Press Enter...'); 
{Демонстрируем страницы} 
ReadLn;
SetVisualPage(1); 
ReadLn;
SetVisualPage (0); 
ReadLn;
CloseGraph 
end 
else
begin {Драйвер не поддерживает многостраничный режим} 
s := GetDriverName; CloseGraph; 
WriteLn('Адаптер ',s,' использует только 1 страницу')
end
end.
Обратите внимание на оператор
if doHercMono then 
SetGraphMode(m-1);
С его помощью гарантированно устанавливается многостраничный режим работы на адаптерах EGA, MCGA, VGA. Как уже говорилось, после инициации графики с Driver=Detect устанавливается режим работы с максимально возможным номером; перечисленные адаптеры в этом режиме могут работать только с одной графической страницей, чтобы обеспечить работу с двумя страницами, следует уменьшить номер режима.
Многоугольники
Процедура Rectangle.
Вычерчивает прямоугольник с указанными координатами углов. Заголовок:
Procedure Rectangle(X1,Y1,X2,Y2: Integer);
Здесь X1... Y2 - координаты левого верхнего (X1, Y1) и правого нижнего (Х2, Y2) углов прямоугольника. Прямоугольник вычерчивается с использованием текущего цвета и текущего стиля линий.
В следующем примере на экране вычерчиваются 10 вложенных друг в друга прямоугольников.
Uses Graph, CRT; 
var
d,r,e,xl,yl, x2,y2,dx,dy: Integer; 
begin
{Инициируем графику} 
d := Detect; InitGraph(d, r, ' ') ; 
e := GraphResult; if e <> grOK then
WriteLn(GraphErrorMsg(e)) 
else 
begin
{Определяем приращения сторон} 
dx := GetMaxX div 20; 
dy := GetMaxY div 20; 
{Чертим вложенные прямоугольники} 
for d := 0 to 9 do
Rectangle(d*dx,d*dy,GetMaxX-d*dx,GetMaxY-d*dy); 
if ReadKey=#0 then d := ord(ReadKey); 
CloseGraph
end
end.
Процедура DrawPoly.
Вычерчивает произвольную ломаную линию, заданную координатами точек излома.
Procedure DrawPoly(N: Word; var Points)
Здесь N - количество точек излома, включая обе крайние точки; Points - переменная типа PointType, содержащая координаты точек излома.
Координаты точек излома задаются парой значений типа Word: первое определяет горизонтальную, второе - вертикальную координаты. Для них можно использовать следующий определенный в модуле тип:
type
PointType = record
х, у : Word
end;
При вычерчивании используется текущий цвет и текущий стиль линий. Вот как, например, можно с помощью этой процедуры вывести на экран график синуса:
Uses Graph; 
const
N = 100; {Количество точек графика} 
var
d, r, e: Integer;
m : array [O..N+1] of PointType; k : Word; 
begin
{Инициируем графику}
d := Detect; InitGraph(d, r, ''); 
e := GraphResult; if e <> grOk then
WriteLn(GraphErrorMsg(e)) 
else 
begin
{Вычисляем координаты графика} 
for k := 0 to N do with m[k] do 
begin
x := trunc(k*GetMaxX/N); 
у := trunc(GetMaxY*(-sin(2*Pi*k/N)+1)/2) 
end;
{Замыкаем график прямой линией} 
m[succ(N)].x := m[0] .x; 
m[succ(n)].y := m[0] .у; 
DrawPoly(N + 2, m); 
ReadLn; 
CloseGraph 
end 
end.
В этом примере для проведения горизонтальной прямой используется «замыкание» ломаной - первая и последняя координаты ее точек излома совпадают.
Замечу, что хотя количество точек излома N - выражение типа Word, на самом деле внутри процедуры на этот параметр накладываются ограничения, связанные с конечным размером используемой буферной памяти. Вы можете убедиться в этом с помощью, например, изменения N в предыдущем примере: при N=678 график перестанет выводиться на экран, а функция GraphResult будет возвращать значение -6 (не хватает памяти для просмотра областей). Таким образом, для этой программы пороговое значение количества точек излома составляет 679. В то же время для программы
Uses Graph; 
const
N=510; {Предельное значение, при котором на экране еще видна диагональная линия} 
var
d,k: Integer;
Coo: array [1..N] of PointType; 
begin
d := Detect; InitGraph(d,k,' ') ; 
for k := 1 to N do with Coo[k] do 
if odd(k) then 
begin 
X := 0; 
Y := 0 
end 
else 
begin
X := GetMaxX; 
Y := GetMaxY 
end;
DrawPoly(N,Coo); 
ReadLn; 
CloseGraph 
end.
это значение равно 510. В этой программе ломаная задается в виде многократно накладывающихся друг на друга диагональных линий.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика