|
Часть 10
Глава 14. Ввод и вывод
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В данной Главе кратко описываются стандартные (или встроен-
ные) функции и процедуры ввода-вывода Borland Pascal. Эти проце-
дуры и функции можно найти в модуле System.
Процедуры и функции ввода-вывода
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Append і Открывает существующий файл для добавле-і
і і ния. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Assign і Присваивает имя внешнего файла файловой пе-і
і і ременной. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і BlockRead і Считывает из нетипизированного файла однуі
і і или более записей. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і BlockWrite і Записывает в нетипизированный файл однуі
і і или более записей. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ChDir і Выполняет смену текущего каталога. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Close і Закрывает открытый файл. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Erase і Стирает внешний файл. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Eоf і Возвращает для файла состояние end-of-fileі
і і (конец файла). і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FilePos і Возвращает текущую позицию в файле. Дляі
і і текстовых файлов не используется. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FileSize і Возвращает текущий размер файла. Для текс-і
і і товых файлов не используется. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Flush і Сбрасывает буфер текстового файла вывода. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Getdir і Возвращает текущий каталог на заданном дис-і
і і ке. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і IОResult і Возвращает целое значение, являющееся сос-і
і і тоянием последней выполненной операции вво-і
і і да-вывода. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і MkDir і Создает подкаталог. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Read і Считывает одно или более значений из файлаі
і і в одну или более переменных. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Readln і Делает то же, что и Read, и выполняет про-і
і і пуск до начала следующей строки текстовогоі
і і файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Rеnаме і Переименовывает внешний файл. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Rеset і Открывает существующий файл. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Rewritе і Создает и открывает новый файл. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і RмDir і Удаляет пустой подкаталог. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Seek і Перемещает текущую позицию в файле на за-і
і і данный элемент. Для текстовых файлов не ис-і
і і пользуется. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SeekEof і Возвращает для текстового файла состояниеі
і і "конец файла". і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SeekEoln і Возвращает для текстового файла состояниеі
і і "конец строки". і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetTextBuf і Назначает для текстового файла буфер ввода-і
і і вывода. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Truncate і Усекает размер файла до текущей позиции.і
і і Для текстовых файлов не используется. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Write і Записывает в файл одно или более значений. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Writeln і Делает то же, что Write, но затем записы-і
і і вает в текстовый файл символ конца строки. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Файловый ввод-вывод
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Файловая переменная в Паскале - это любая переменная файло-
вого типа. В Паскале имеются три класса файлов: типизированный
файл, текстовый файл и нетипизированный файл.
Примечание: Синтаксис записи типов файлов представлен
в Главе 4, в разделе "Структурные типы".
Перед использованием файловой переменной она должна быть
связана с внешним файлом с помощью вызова процедуры Assign. Внеш-
ним файлом обычно является поименованный файл на диске, но он
также может представлять собой устройство, например, клавиатуру
или дисплей. Во внешних файлах сохраняется записанная в файл ин-
формация, или они служат источниками информации, которая считыва-
ется из файла.
Когда связь с внешним файлом установлена, для подготовки ее
к операции ввода или вывода файловая переменная должна быть "отк-
рыта". Существующий файл можно открыть с помощью процедуры Reset,
а новый файл можно создать и открыть с помощью процедуры Rewrite.
Текстовые файлы, открытые с помощью процедуры Reset доступны
только по чтению, а текстовые файлы, открытые с помощью процедуры
Rewrite, доступны только по записи. Типизированные и нетипизиро-
ванные файлы всегда допускают как чтение, так и запись, независи-
мо от того были они открыты с помощью процедуры Reset или с по-
мощью процедуры Rewrite.
Любой файл, представляет собой линейную последовательность
элементов, каждый из которых имеет тип элемента (или тип записи)
файла. Каждый элемент файла имеет номер. Первый элемент файла
считается нулевым элементом.
Обычно доступ к файлам организуется последовательно, то
есть, когда элемент считывается с помощью стандартной процедуры
Read или записывается с помощью стандартной процедуры Write, те-
кущая позиция файла перемещается к следующему по порядку элементу
файла. Однако к типизированным и нетипизированным файлам можно
организовать прямой доступ с помощью стандартной процедуры Sееk,
которая перемещает текущую позицию файла к заданному элементу.
Для определения текущей позиции в файле и текущего размера файла
можно использовать стандартные функции FilePоs и Filesize.
Когда программа завершает обработку файла, он должен закры-
ваться с помощью стандартной процедуры Close. После полного зак-
рытия файла связанный с ним внешний файл обновляется. Затем фай-
ловая переменная может быть связана с другим внешним файлом.
По умолчанию при всех обращениях к стандартным функциям и
процедурам ввода-вывода автоматически производится проверка на
наличие ошибок. При обнаружении ошибки программа прекращает рабо-
ту и выводит на экран сообщение об ошибке. С помощью директив
компилятора {$I+} и {$I-} эту автоматическую проверку можно вклю-
чить или выключить. Когда автоматическая проверка отключена, то
есть когда процедура или функция была скомпилирована с директивой
{$I-}, ошибки ввода-вывода, возникающие при работе программы, не
приводят к ее останову. При этом, чтобы проверить результат вы-
полнения операции ввода-вывода, нужно использовать стандартную
функцию IОResult.
Для очистки ошибки, которая может произойти, вы можете выз-
вать функцию IOResult. Если вы этого не сделаете, и текущим сос-
тоянием является {$I+}, то из-за оставшейся ошибки IOResult сле-
дующая операция ввода-вывода завершится с ошибкой.
Примечание: Если вы пишете программу дл Windows и не
хотите, чтобы Windows обрабатывала за вас ошибки ввода-вы-
вода на диск или другие ошибки ввода-вывода, вызовите
SetErrorMode(1).
Текстовые файлы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В данном разделе описываются операции ввода и вывода, ис-
пользующие файловую переменную стандартного текстового типа. За-
метим, что в Borland Pascal текстовый тип (тип Text) отличается
от символьного типа Char.
При открытии текстового файла внешний файл интерпретируется
особым образом: считается, что он представляет собой последова-
тельность символов, сгруппированных в строки, где каждая строка
заканчивается символом конца строки (end-of-line), который предс-
тавляет собой символ перевода каретки, за которым возможно следу-
ет символ перевода строки.
Для текстовых файлов существует специальный вид операций
чтения и записи (read и write), который позволяют вам считывать и
записывать значения, тип которых отличается от символьного типа
Char. Такие значения автоматически переводятся в символьное
представление и обратно. Например, Read(f,i), где i - переменная
целого типа, приведет к считыванию последовательности цифр, ин-
терпретации этой последовательности, как десятичного числа, и
сохранению его в i.
Как было отмечено ранее, имеются две стандартных переменных
текстового типа - это Input и Оutput. Стандартная файловая пере-
менная Input - это доступный только по чтению файл, связанный со
стандартным файлом ввода операционной системы (обычно это клавиа-
тура), а стандартная файловая переменная Оutput - это доступный
только по записи файл, связанный со стандартным файлом вывода
операционной системы (обычно это дисплей). Перед началом выполне-
ния программы DOS файлы Input и Оutput автоматически открываются,
как если бы были выполнены следующие операторы:
Assign(Input,'');
Reset(Input);
Assign(Output,'');
Rewrite(Output);
Так как Windows не поддерживает непосредственно ориентиро-
ванный на текст ввод и вывод, файлы Input и Output по умолчанию в
прикладной программе Windows не присваиваются, и любая попытка
чтения из этих файлов или записи в них приведет к ошибке вво-
да-вывода. Однако, если прикладная программа использует модуль
WinCrt, то Input и Output будут ссылаться на прокручиваемое текс-
товое окно. Модуль WinCrt содержит всю логику управления, необхо-
димую для эмуляции текстового экрана в операционной среде
Windows, поэтому в прикладной программе, использующей модуль
WinCrt, не требуется никаких приемов программирования, специфи-
ческих для Windows.
Для некоторых из стандартных процедур и функций, список ко-
торых приведен в данном разделе, не требуется явно указывать в
качестве параметра файловую переменную. Если этот параметр опу-
щен, то по умолчанию будут рассматриваться переменные Input или
Output, в зависимости от того, будет ли процедура или функция
ориентирована на ввод или на вывод. Например, Read(х) соответс-
твует Read(Input,х) и Write(х) соответствует Write(Output,х).
Если при вызове одной из процедур или функций из этого раз-
дела вы задаете файл, этот файл должен быть связан с внешним фай-
лов с помощью процедуры Assign и открыт с помощью процедуры
Reset, Rewritе или Append. Если для ориентированной на вывод про-
цедуры или функции вы указываете файл, который был открыт с по-
мощью процедуры Reset, то выведется сообщение об ошибке. Анало-
гично, будет ошибкой задавать для ориентированной на ввод проце-
дуры или функции файл, открытый с помощью процедур Rewrite или
Append.
Нетипизированные файлы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Нетипизированные файлы представляют собой каналы ввода-выво-
да нижнего уровня, используемые в основном для прямого доступа к
любому файлу на диске, независимо от его типа и структуры. Любой
нетипизированный файл описывается словом file без атрибутов. Нап-
ример:
var
DataFile: file;
Для нетипизированных файлов в процедурах Reset и Rewrite до-
пускается указывать дополнительный параметр, чтобы задать размер
записи, использующийся при передаче файла.
По историческим причинам принимаемая по умолчанию длина за-
писи равна 128 байтам. Предпочтительной длиной записи является
длина записи, равная 1, поскольку это единственное значение, ко-
торое позволяет точно отразить размер любого файла (когда длина
записи равна 1, то в файле не могут присутствовать неполные запи-
си, то есть записи с меньшей длиной).
За исключением процедур Read и Write для всех нетипизирован-
ных файлов допускается использование любой стандартной процедуры,
которые допускается использовать с типизированными файлами. Вмес-
то процедур Read и Write здесь используются соответственно проце-
дуры Blockrеаd и BlockWrite позволяющие пересылать данные с высо-
кой скоростью.
Переменная FileMode
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Переменная FileMode, определенная в модуле System, задает
код доступа, передаваемый в DOS для типизированных и нетипизиро-
ванных файлов (не для текстовых файлов), когда они открываются с
помощью процедуры Reset.
По умолчанию значение FileMode = 2. При этом допускается
чтение и запись файла. Присваивание FileMode другого значения
приводит к использованию этого режима при всех последующих вызо-
вах Reset.
Примечание: Новые файлы, открываемые с помощью
Rewrite, всегда открываются в режиме чтения/записи, что со-
ответствует Filemode = 2.
Диапазон допустимых значений FileMode зависит от используе-
мой версии DOS. Однако во всех версиях определены следующие режи-
мы:
0: доступ только по чтению
1: Только запись
2: Чтение/запись
В DOS версии 3.х определены дополнительные режимы, которые
касаются в основном совместного использования файлов при работе в
сети (более подробно это описывается в "Руководстве программиста
по DOS").
Устройства в Borland Pascal
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В Borland Pascal и в операционной системе DOS внешняя аппа-
ратура, как, например, клавиатура, устройство печати, дисплей,
рассматривается, как устройства. С точки зрения программиста уст-
ройство можно рассматривать, как файл, и с ним можно работать с
помощью того же набора стандартных процедур и функций, что и с
файлом. В Турбо Паскале поддерживается два типа устройств - уст-
ройства DOS и устройства для текстовых файлов.
Устройства DOS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Устройства DOS реализованы с помощью зарезервированных имен
устройств, которые имеют специальный смысл. Устройства DOS пол-
ностью "прозрачны": в Турбо Паскале неизвестно даже, когда файло-
вая переменная связана с устройством, а когда с файлом на диске.
Например, программа:
var
Lst: Text;
begin
Assign(Lst,'LPT1');
Rewrite(Lst);
Writeln(Lst,'Привет...');
Close(Lst);
end;
выведет строку "Привет..." на устройство печати, хотя синтаксис
точно такой же, как если бы она выводилась в файл.
Устройства, реализованные в операционной системе DOS, ис-
пользуются для однозначного ввода или вывода. Таким образом, уст-
ройства в DOS используются обычно для текстовых файлов. В редких
случаях для работы с устройствами DOS может оказаться полезным
использование также нетипизированного файла.
Устройство CОN
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Устройство CОN означает консоль, посредством которой выводи-
мая информация пересылается на экран дисплея, а вводимая информа-
ция воспринимается с клавиатуры. Если не было изменено направле-
ние ввода или вывода, стандартные файлы Input и Оutput и все
файлы, которым присвоено пустое имя, ссылаются на устройство CОN.
Вводимая с устройства CОN информация является строчно-ориен-
тированной и используется средствами редактирования строки, кото-
рые описаны в руководстве по DOS. Символы считываются из буфера
строки, а когда буфер становится пустым, вводится новая строка.
При нажатии клавиш Ctrl+Z генерируется символ конца файла
(end-of-file), после которого функция Eоf возвращает значение
Truе.
Устройства LРT1, LРT2 и LРT3
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В качестве возможного устройства построчной печати допуска-
ется использование до трех устройств печати. Если присоединено
только одно устройство печати, на него обычно ссылаются, как на
устройство LРT1. Для этого устройства можно также использовать
синоним РRN.
Построчное устройство печати - это устройство, предназначен-
ное только для вывода. При любой попытке использовать процедуру
Reset для открытия файла, связанного с одним из этих устройств,
немедленно генерируется признак конца файла.
Стандартный модуль Рrinter описывает текстовую файловую пе-
ременную с именем Lst и устанавливает ее связь с устройством
LРT1. Чтобы облегчить вывод какой-либо информации из вашей прог-
раммы на устройство печати, включите в оператор uses вашей прог-
раммы модуль Рrinter, а для вывода используйте процедуры
Writе(Lst,...) и Writеln(Lst,...).
Примечание: О печати из программы Windows рассказыва-
ется ниже.
Устройства CОМ1 и CОМ2
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Коммуникационными портами (CОМ1 и CОМ2) являются устройства,
представляющие собой два последовательных коммуникационных порта.
Вместо CОМ1 можно использовать синоним AUХ.
Устройство NUL
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Нулевое устройство (NUL) игнорирует любую попытку записи на
него и немедленно генерирует признак конца файла при попытки счи-
тывания с этого устройства. Его следует использовать, если вы не
хотите создавать отдельный файл, а в программе требуется указать
имя входного или выходного файла.
В общем случае следует избегать использования устройств DOS
под Windows и применять функции ввода-вывода API Windows. Некото-
рые устройства, такие как CON, не будут правильно работать. Дру-
гие устройства могут работать, но результаты могут оказаться не
теми, что вы ожидаете. Например, если вы используете LPT1, ваша
распечатка может выводиться, прерывая другое задание печати. Поэ-
тому надежнее использовать функции API Windows.
Устройства, предназначенные для текстовых файлов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Устройства, предназначенные для текстовых файлов, использу-
ются для реализации устройств, не поддерживаемых в DOS, или для
того, чтобы сделать доступным набор средств, отличающийся от то-
го, который предусмотрен для аналогичного устройства DOS. Хорошим
примером устройства, предназначенного для текстового файла, явля-
ется окно CRT, реализованное с помощью стандартного модуля Crt.
Оно обеспечивает аналогичный терминалу текстовый экран и позволя-
ет вам создавать прикладные программы со "стандартным вводом-вы-
водом" с минимальными усилиями, используя такие средства, как
цвета и окна.
В отличие от устройств DOS, устройства, предназначенные для
вывода текстовых файлов, не имеют зарезервированных имен. Факти-
чески, у них вообще отсутствуют имена. Вместо этого файл связыва-
ется в устройством с помощью обычной процедуры Assign. Например,
стандартный модуль Crt реализует процедуру AssignCrt, которая
связывает текстовые файлы с устройством CRT.
Устройства, предназначенные для текстовых файлов, использу-
ются для реализации устройств, не поддерживаемых в DOS, или для
того, чтобы сделать доступным набор средств, отличающийся от то-
го, который предусмотрен для аналогичного устройства DOS. Хорошим
примером устройства, предназначенного для текстового файла, явля-
ется устройство CRT, реализованное с помощью стандартного модуля
Crt. Его основной функцией является обеспечение интерфейса с
дисплеем и клавиатурой, аналогично устройству CОN в модуле Dos.
В отличие от устройств DOS, устройства, предназначенные для
вывода текстовых файлов, не имеют зарезервированных имен. Факти-
чески, у них вообще отсутствуют имена. Вместо этого файл связыва-
ется с устройством с помощью обычной процедуры Assign. Например,
стандартный модуль Crt реализует процедуру AssignCrt, которая
связывает текстовые файлы с устройством CRT.
Ввод и вывод с помощью модуля Crt
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Примечание: Этот раздел относится только к программам
реального и защищенного режима DOS.
Модуль Crt позволяет использовать все возможности дисплея и
клавиатуры персонального компьютера РС, включая управление режи-
мом экрана, расширенные коды клавиатуры, цвет, окна и звуковые
сигналы.
Модуль Crt реализует ряд мощных программ, предоставляющих
вам полную возможность управления средствами компьютера РС, таки-
ми, как управление режимом экрана, расширенные коды клавиатуры,
цвета, окна, и звуковые сигналы. Модуль Crt может использоваться
только в программах, работающих на персональных компьютерах IBM
РС, РС AT, РS/2 фирмы IBM и полностью совместимых с ними.
Одним из основных преимуществ использования модуля Crt явля-
ется большая скорость и гибкость при выполнении операций работы с
экраном. Программы, не работающие с модулем Crt, выводят на экран
информацию с помощью средств операционной системы DOS, что связа-
но с дополнительными непроизводительными затратами. При использо-
вании модуля Crt выводимая информация посылается непосредственно
в базовую систему ввода-вывода (ВIОS), или, для еще более быстрых
операций, непосредственно в видеопамять.
Использование модуля CRT
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Чтобы использовать модуль Crt, его нужно указать в операторе
uses вашей программы:
uses Crt;
При инициализации модуля Crt для того, чтобы можно было об-
ращаться к CRТ, вместо стандартных файлов ввода и вывода DOS наз-
начаются стандартные входные и выходные текстовые файлы. Это со-
ответствует выполнению в начале программы следующих операторов:
AssignCrt(Input); Reset(Input);
AssignCrt(Output); Rewrite(Output);
Это означает, что переопределение входных и выходных файлов
далее не допускается до тех пор, пока для данных файлов не будет
выполнено обратного переназначения и не произойдет переход к
стандартному вводу и выводу с помощью выполнения операторов:
Assing(Input,''); Reset(Input);
Assing(Output,''); RewriteOutput);
Окна CRT
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Модуль Crt поддерживает простую, но, тем не менее, мощную
форму использования окон. Процедура Window позволяет вам опреде-
лить в каком-либо месте экрана окно. При записи в это окно оно
ведет себя точно также, как целый экран. При этом остальная часть
экрана остается нетронутой. Другими словами, доступ к экрану вне
окна отсутствует. Внутри окна можно добавлять и удалять строки,
при этом курсор возвращается к правому краю и при достижении кур-
сором нижней строки текст продвигается вверх.
Все координаты экрана, кроме тех, которые используются для
определения окна, относятся к текущему окну. Координата экрана
(1,1) соответствует левому верхнему углу экрана.
По умолчанию окном считается весь экран.
Специальные символы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При записи в выходной файл или в файл, который назначен для
модуля Crt, специальное значение имеют следующие управляющие сим-
волы:
ЪДДДДДДДВДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іСимвол і Название і Описание і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #7 і Звонок і Вызывает звуковой сигнал, издаваемый сі
і і BELL і помощью внутреннего динамика. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #8 іОбратный пробелі Возврат на одну позицию. Вызывает пе-і
і і BS і ремещение курсора влево на одну пози-і
і і і цию. Если курсор уже находится у лево-і
і і і го края текущего окна, то никакихі
і і і действий не производится. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #10 і Перевод строкиі Перемещает курсор на одну строку вниз.і
і і LF і Если курсор уже находится на нижнейі
і і і строке окна, то окно пролистываетсяі
і і і вверх на одну строку. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #13 іВозврат кареткиі Возвращает курсор с левому краю теку-і
і і BS і щего окна. і
АДДДДДДДБДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Ввод строк
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При чтении из входного файла (Input) или из текстового фай-
ла, который назначен для модуля Crt, текст вводится по одной
строке. Строка запоминается во внутреннем буфере текстового файла
и когда переменные считываются, то в качестве источника использу-
ется этот буфер. Каждый раз когда буфер становится пустым, вво-
дится новая строка. При вводе строк можно использовать следующие
клавиши редактирования:
ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іКлавиша редактированияі Описание і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Backsрасе і Удаляет последний введенный символ. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Esс і Удаляет всю вводимую строку. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Enter і Прекращает ввод строки и записываеті
і і метку конца строки (возврат каретки/пе-і
і і ревод строки) в буфере. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Ctrl+S і Действует также, как Backspace. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Ctrl+D і Извлекает один символ из последней вво-і
і і димой строки и выводит его на экран. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Ctrl+F і Восстанавливает на экране последнююі
і і вводимую строку. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Ctrl+Z і Завершает ввод строки и генерирует сим-і
і і вол конца файла. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Сtrl-Z і Генерирует символ конца файла и завер-і
і і шает строку ввода. і
АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Ctrl+Z будет генерировать конец файла в том случае, если пе-
ременная CheckEOF установлена в True (по умолчанию False).
Для проверки состояния клавиатуры и ввода отдельных символов
под управлением программы используйте функции KeyРressed и
RеаdKey.
Процедуры и функции модуля Crt
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іФункция/процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AssignCrt і Назначает текстовый файл для устройстваі
і і CRT. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ClrEоl і Очищает все символы, начиная от позицииі
і і курсора до конца строки, без перемещенияі
і і курсора. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ClrScr і Очищает экран и помещает курсор в верхнемі
і і левом углу. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Dеlау і Выполняет задержку на указанное число мил-і
і і лисекунд. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DelLine і Удаляет строку, на которой находится курсорі
і і и перемещает все следующие строки на однуі
і і строку вверх. Нижняя строка очищается. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GоtоХY і Выполняет позиционирование курсора. Х - этоі
і і горизонтальная позиция, Y - вертикальнаяі
і і позиция. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і НightVideo і Выбирает символы с подсветкой. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і InsLine і Вставляет пустую строку в месте расположе-і
і і ния курсора. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і KeyРrеssеd і Возвращает значение Truе, если клавиша наі
і і клавиатуре нажата и Falsе - в противномі
і і случае. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LowVidе і Выбирает символы с пониженной яркостью. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і NormVideo і Выбирает символы с нормальной яркостью. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і NoSound і Выключает внутренний динамик. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Sound і Включает внутренний динамик. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TextВаckground і Выбирает фоновый цвет. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TextColor і Выбирает цвет самого символа. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TextМоdе і Выбирает конкретный текстовый режим. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Window і Определяет на экране текстовое окно. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Rеаdкеу і Считывает символ с клавиатуры. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WherеХ і Возвращает координату Х для текущей позицииі
і і курсора, относящуюся к текущему окну. Хі
і і представляет собой горизонтальную позицию.і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WhereY і Возвращает координату Y для текущей позицииі
і і курсора, относящуюся к текущему окну. Yі
і і представляет собой вертикальную позицию. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Константы и переменные модуля Crt
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В модуле Crt содержится рад констант, облегчающих программи-
рование. Подробно они описываются в Главе 1 "Справочного руко-
водства программиста". Опишем группы этих констант:
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Группа констант і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Константы режима Crt і Графические константы, используе-і
і і мые в качестве параметров проце-і
і і дуры TextMode. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Константы цветов і Константы, используемые для уста-і
і і новки цветов с помощью процедурі
і і TextColor и TextBackGround. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Например, чтобы найти значение константы, которая позволит
вам выводить текст в программе красным цветом, просмотрите конс-
танты цветов текста и найдите константу Red со значением 4.
В модуле Crt содержатся следующие переменные:
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Переменная і Тип і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CheckBreak і boolean і Разрешает или запрещает про-і
і і і верку на Ctrl+Break. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CheckEof і boolean і Разрешает или запрещает сим-і
і і і вол конца файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CheckSnow і boolean і Разрешает или запрещает про-і
і і і верку на помехи. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DirectVideo і boolean і Разрешает или запрещает пря- і
і і і мой доступ к памяти для про- і
і і і цедур WriteLn и Write. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LastMode і word і При каждом вызове TextMode і
і і і сохраняет текущий видеоре- і
і і і жим. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TextAttr і byte і Содержит атрибуты текущего і
і і і выбранного текста. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WindMin і word і Содержит координаты верхнего і
і і і левого угла текущего окна. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WindMax і word і Содержит координаты нижнего і
і і і правого угла текущего окна. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Ввод и вывод с помощью модуля WinCrt
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Примечание: Этот раздел относится только к программам
Windows.
Модуль WinCrt реализует аналогичный терминалу текстовый эк-
ран в окне. С помощью модуля WinCrt вы можете легко создавать
программы, использующие стандартные процедуры Read. ReadLn, Write
и WriteLn для выполнения операций ввода и вывода (так же, как в
обычной прикладной программе, работающей в текстовом режиме). Мо-
дуль WinCrt содержит все алгоритмы, управляющие эмуляцией тексто-
вого экрана в программной среде Windows. Если ваша программа ис-
пользует модуль WinCrt, вам не потребуется писать "специфический
для Windows" исходный код.
Использование модуля WinCrt
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Чтобы использовать модуль WinCrt, нужно просто указать в ва-
шей программе оператор uses, как и при использовании любого дру-
гого модуля.
uses WinCrt;
По умолчанию стандартные текстовые файлы Input и Output, оп-
ределенные в модуле System, не присваиваются, и все обращения к
процедурам Read, Readln, Write или Writeln без указания файловой
переменной приводят к ошибке ввода-вывода. Однако, когда програм-
ма использует модуль WinCrt, код инициализации данного модуля
присваивает Input и Output стандартные текстовые файлы, чтобы
ссылаться на окно, эмулирующее текстовый экран. Это соответствует
выполнению в начале программы следующих операторов:
AssignWinCrt(Input); Reset(Input);
AssignWinCrt(Output); Rewrite(Output);
Когда в программе выполняются процедуры Readln, Read, Write
или Writeln, в оперативной области Windows открывается окно CRT.
По умолчанию заголовком окна CRT будет полное имя маршрута файла
.EXE программы. Когда программа завершает работу (управление дос-
тигает конечного зарезервированного слова end), заголовок окна
CRT изменяется на "(Inactive nnnnn)", где nnnnn - заголовок окна
в его активном состоянии.
Заметим, что хотя программа и завершила работу, окно остает-
ся на экране, благодаря чему пользователь может проверить вывод
программы. Аналогично другим прикладным программам Windows, прог-
рамма не завершается полностью, пока пользователь не закроет ок-
но.
Более полно управлять жизненным циклом окна CRT вам позволя-
ют подпрограммы InitWinCrt и DoneWinCrt. При обращении к первой
из них без ожидания первого вызова процедур Readln, Read, Write
или Writeln немедленно создается окно CRT. Аналогично, обращение
к DoneWinCrt немедленно уничтожает окно CRT, не ожидая, пока его
закроет пользователь.
Окно CRT представляет собой прокручиваемое "панорамное" окно
на виртуальном текстовом экране. По умолчанию виртуальный экран
имеет размеры 80 столбцов на 25 строк, но реальный размер окна
CRT может быть меньше. Если этот размер меньше, пользователь для
перемещения области окна по текстовому экрану большего размера
может использовать полосы прокрутки окна или клавиши управления
курсором. Это особенно полезно для "обратной прокрутки" и провер-
ки ранее написанного текста. По умолчанию панорамное окно отсле-
живает курсор текстового экрана. Другими словами, панорамное окно
автоматически прокручивается, чтобы обеспечить постоянную види-
мость курсора. Установив переменную AutoTracking в значение
False, вы можете запретить средство автоматической прокрутки.
Размеры виртуального экрана определяются переменной
ScreenSize. Присвоив этой переменной новые размерности перед тем,
как ваша программа создает окно CRT, вы можете изменить размеры
виртуального экрана. Когда окно создается, в динамически распре-
деляемой памяти выделяется буфер экрана. Размер этого буфера ра-
вен произведению ScreenSize.Y на ScreenSize.Y и не может превы-
шать 65520 байт. Ответственность за присваивания значений этим
переменным возлагается на вас (они не должны превышать указанную
границу). Если, например, вы присвоите ScreenSize.X значение 64,
то наибольшим допустимым значением для ScreenSize.Y будет 1023.
В любой момент в процессе выполнения программы, использующей
модуль WinCrt, пользователь может прервать выполнение, выбрав в
меню Control (Управление) окна CRT команду Close (Закрытие),
дважды щелкнув кнопкой "мыши" в рамке меню Control или нажав кла-
виши Alt+F4. Аналогично, в любой момент для прерывания прикладной
программы пользователь может нажать Ctrl+C или Ctrl+Break, при
этом окно переводится в неактивное состояние. Установив перемен-
ную CheckBreak в значение False, вы можете запретить эту возмож-
ность.
Специальные символы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При записи в выходной файл (Output) или в файл, который наз-
начен для окна CRT, специальное значение имеют следующие управля-
ющие символы:
ЪДДДДДДДВДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іСимвол і Название і Описание і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #7 і Звонок і Вызывает звуковой сигнал, издаваемый сі
і і BELL і помощью внутреннего динамика. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #8 іОбратный пробелі Возврат на одну позицию. Вызывает пе-і
і і BS і ремещение курсора влево на одну пози-і
і і і цию. Если курсор уже находится у лево-і
і і і го края текущего окна, то никакихі
і і і действий не производится. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #10 і Перевод строкиі Перемещает курсор на одну строку вниз.і
і і LF і Если курсор уже находится на нижнейі
і і і строке окна, то окно пролистываетсяі
і і і вверх на одну строку. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #13 іВозврат кареткиі Возвращает курсор с левому краю теку-і
і і CR і щего окна. і
АДДДДДДДБДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Ввод строк
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При чтении из входного файла (Input) или из текстового фай-
ла, который назначен для окна CRT, текст вводится по одной стро-
ке. Строка запоминается во внутреннем буфере текстового файла и
когда переменные считываются, то в качестве источника использует-
ся этот буфер. Каждый раз когда буфер становится пустым, вводится
новая строка.
При вводе строк в окне CRT можно использовать следующие кла-
виши редактирования: Вacksрасе - удаляет последний введенный сим-
вол, Esс - удаляет всю вводимую строку, Enter - прекращает ввод
строки и записывает метку конца строки (возврат каретки/перевод
строки) в буфере. Кроме того, можно использовать клавиши Сtrl+Z,
которые генерируют символ конца файла только в том случае, если
переменная CheckEof установлена в значение Truе (по умолчанию ей
присвоено значение Falsе). Нажатие Ctrl+Z также завершает строку
ввода и генерирует маркер конца строки.
Для проверки состояния клавиатуры и ввода отдельных символов
под управлением программы используйте функции KeyРressed и
Rеаdkey.
Процедуры и функции
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В следующих таблицах перечисляются процедуры и функции, ко-
торые можно найти в модуле WinCrt.
ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура/функция і Описание і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AssignCrt і Назначает текстовый файл для окна CRT. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ClrEоl і Очищает все символы, начиная от позицииі
і і курсора до конца строки, без перемещенияі
і і курсора. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ClrScr і Очищает экран и помещает курсор в верхнемі
і і левом углу. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CursorTo і Перемещает курсор в точку на виртуальномі
і і экране с заданными координатами. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DoneWinCrt і Уничтожает окна CRT. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GоtоХY і Выполняет позиционирование курсора. Х -і
і і это горизонтальная позиция, Y - вертикаль-і
і і ная позиция виртуального экрана. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і InitWinCrt і Инициализирует окно CRT. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і KeyРrеssеd і Возвращает значение Truе, если клавиша наі
і і клавиатуре нажата и Falsе - в противном і
і і случае. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ReadBuf і Считывает из окна CRT строку. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і RеаdKеу і Считывает символ с клавиатуры. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ScrollTo і Прокручивает окно CRT, чтобы видна былаі
і і точка с заданными координатами. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TrackCursor і Прокручивает окно CRT, чтобы курсор былі
і і видимым. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WherеХ і Возвращает координату Х для текущей позициі
і і курсора, относящуюся к текущему окну. Х і
і і представляет собой горизонтальную і
і і позицию. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WhereY і Возвращает координату Y для текущей пози-і
і і ции курсора, относящуюся к текущему окну.і
і і Y представляет собой вертикальную позицию.і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WriteBuf і Выводит в окно CRT блок символов. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WriteChar і Выводит в окно CRT отдельный символ. і
АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Переменные модуля WinCrt
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В модуле WinCrt описывается несколько переменных:
ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Переменная і Тип і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WindowOrg і Используемое по умолчанию размещение поз-і
і і воляет Windows выбирать подходящее распо-і
і і ложение окна CRT. Вы можете изменить на-і
і і чальное значение, присвоив перед созданиемі
і і окна CRT новые значения координатам X и Y.і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WindowSize і Используемый по умолчанию размер позволяеті
і і Windows выбирать подходящий размер окнаі
і і CRT. Вы можете изменить начальный размер,і
і і присвоив перед созданием окна CRT новыеі
і і значения координатам X и Y. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ScreenSize і По умолчанию экран имеет размер 80 столб-і
і і цов на 25 строк. Присвоив другие значенияі
і і координатам X и Y ScreenSize перед созда-і
і і нием окна CRT, вы можете изменить исполь-і
і і зуемый по умолчанию размер экрана CRT.і
і і Значение, получаемое при произведенииі
і і ScreenSize.X на ScreenSize.Y, не должноі
і і превышать 65520. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Cursor і Верхний левый угол соответствует координа-і
і і те (0,0). Cursor - это переменная, доступ-і
і і ная только по чтению. Присваивать ей зна-і
і і чения нельзя. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Origin і Содержит текущую позицию курсора на вирту-і
і і альном экране - координаты ячейки символа,і
і і выводимой в левом верхнем углу окна CRT.і
і і Отсчитывается с 0. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і InactiveTitle і Указывает на завершающуюся нулем строку,і
і і используемую для создания заголовка неак-і
і і тивного окна CRT. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AutoTracking і Разрешает или запрещает автоматическуюі
і і прокрутку окна для отслеживания видимогоі
і і курсора. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CheakBreak і Переменная ChеckEOF разрешает или запреща-і
і і ет символ конца файла. Если переменнаяі
і і ChеckEOF имеет значение Truе, то когдаі
і і чтение производится из файла, назначенногоі
і і окну CRT, при нажатии клавиш Ctrl+Z гене-і
і і рируется символ конца файла. Когда пере-і
і і менная ChеckEOF имеет значение False приі
і і нажатии клавиш Ctrl+Z никаких действий неі
і і выполняется. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CheckEof і Переменная CheckВrеak разрешает или запре-і
і і щает проверки ситуации Ctrl+Break. Когдаі
і і переменная ChеckВrеak принимает значениеі
і і Truе, нажатие пользователем клавиш Alt+F4,і
і і выбор пользователем команды Close в менюі
і і Control окна CRT или двойное нажатие кноп-і
і і ки "мыши" в управляющей рамке меню Controlі
і і этого окна приведет к принудительному за-і
і і вершению работы прикладной программы приі
і і следующей операции вывода на экран дисп-і
і і лея, которую выполнит эта программа. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і WindowTitle і Определяет заголовок окна CRT. По умолча-і
і і нию используется значение, равное полномуі
і і имени маршрута файла .EXE программы. і
АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Печать из программы Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Модуль WinPrn позволяет вам печатать текст из программы
Windows. Чтобы использовать WinPrn, укажите этот модуль в опера-
торе uses вашей программы;
uses WinPrn;
Перед началом печати вам нужно присвоить принтеру переменную
типа текстового файла. Сделать это можно двумя путями - назначив
используемый по умолчанию принтер или выбрав конкретный принтер,
драйвер и порт. Для вывода на используемый по умолчанию принтер
вызовите функцию AssignPrn. Любая запись в присвоенную файловую
переменную типа текстового файла приведет к выводу на принтер.
Изменение заголовков
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
По умолчанию администратор печати Windows будет выводить все
задания печати через WinPrn без заголовков. С помощью процедуры
TitlePrn (вызвав ее вслед за Rewrite) вы можете задать заголовок,
например:
AssignDefPrn(Prn);
TitlePrn(Prn, 'Конец годового отчета');
Rewrite(Prn);
задает для вывода используемый по умолчанию принтер и изменяет
заголовок на "Конец годового отчета", выводя его на этот принтер.
Если TitlePrn вызывается после Rewrite, то никакого эффекта это
не вызывает.
Изменение шрифтов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
WinPrn использует назначенный по умолчанию шрифт, который
возвращается драйвером устройства. Чтобы изменить шрифт, вызовите
функцию SetPrnFont, передав ей описатель используемого шрифта.
SetPrnFont возвращает текущий используемый шрифт. Возвращаемый
шрифт можно использовать для будущего вызова SetPrnFont или для
передачи его DeleteObject. Приведем пример программы, демонстри-
рующей изменение шрифта:;
program Test;
uses WinTypes, WinProcs, WinCrt, WinPrn;
var
Prn: Text;
OldFont: HFont;
begin
Writeln('Печать...');
AssingDefPrn(Prn);
Rewrite(Prn);
Rewrite(Prn, 'Некоторый текст');
OldFont := SetPrnFont(Prn, CreateFont(100,0,0,0,0,0,0,0,1,
Out_Default_Precis,Clip_Default_Precis,
Default_Quality,ff_Roman,nil);
Writeln(Prn,' Произвольный текст новым шрифтом');
DeleteObject(SetPrnFont(Prn, OldFont));
Writeln(Prn, ' Возврат к старому шрифту');
Close(Prn);
Writeln('Выполнено');
end.
Остановка задания печати
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Чтобы остановить задание печати, запущенное с помощью
WinPrn, вызовите процедуру AbortPrn. Это приведет к прекращению
печати, сбросу устройства и подготовки его к выводу нового зада-
ния печати.
Специальные символы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда ваша программа использует модуль WinPrn, следующие
символы будут иметь специальный смысл:
ЪДДДДДДДВДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іСимвол і Название і Описание і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #9 і Табуляция і Начинает печать символов со следующейі
і і TAB і позиции табуляции, которая отстоит оті
і і і предыдущей позиции табуляции на 8-і
і і і кратную среднюю ширину шрифта. і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #10 і Перевод строкиі Начинает печать с новой строки. і
і і LF і і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #12 іПеревод форматаі Принудительный перевод страницы. і
і і FF і і
ГДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і #13 іВозврат кареткиі Начинает печать с начала новой строки.і
і і CR і і
АДДДДДДДБДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры и функции модуля WinPrn
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Процедуры и функции модуля WinPrn перечислены в следующей
таблице:
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура/функция і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AbortPrn і Прекращает печать задания, отбрасы-і
і і вая все нераспечатанные данные. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AssignPrn і Присваивает принтеру файл. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AssingDefPrn і Присваивает файл используемому поі
і і умолчанию принтеру. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetPrnFont і Начинает печать файла с выбраннымі
і і шрифтом. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TitlePrn і Выводит заголовок печатаемого фай-і
і і ла. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Драйверы устройств для текстовых файлов
Borland Pascal позволяет вам определить ваши собственные
драйверы устройств для текстовых файлов. Драйвер устройства для
текстовых файлов представляет собой набор из четырех функций, ре-
ализующих полный интерфейс между файловой системой Borland Pascal
и каким-либо устройством.
Этими четырьмя функциями, с помощью которых определяется лю-
бой драйвер устройства, являются функции Open, InOut, Flush и
Close. Заголовок каждой функции имеет следующий вид:
function DeviceFunc(var F: TextRec) integer
где TехtRес (или TTextRec для Windows) - тип записи текстового
файла, который определяется в Главе 21. Чтобы в функции использо-
вался дальний тип вызова, каждая из них должна компилироваться с
директивой {$F+}. Значение, возвращаемое каждой функцией, предс-
тавляющей собой интерфейс с устройством, становится значением,
возвращаемым функцией IOResult. Возвращаемое значение 0 свиде-
тельствует об успешном завершении операции.
Для того, чтобы связать функцию, осуществляющую интерфейс с
устройством, с конкретным файлом, нужно написать специальную про-
цедуру Assign (аналогичную процедуре AssignCrt в модуле Crt или
WinCrt). Эта процедура должна присваивать адреса четырех функций,
осуществляющих интерфейс с устройствами, четырем указателям на
функции в переменной текстового файла. В придачу к этому вы долж-
ны сохранить системную константу fmClosed в поле Моdе, записать
размер буфера текстового файла в переменную BufSize, сохранить
указатель буфера текстового файла в переменной BufPtr и очистить
строку Nаме.
Предположим, например, что именами четырех функций, реализу-
ющих интерфейс с устройством, являются функции DevOpen, DevInOut,
DevFlush, DevClose и Assign.
Тогда процедура Assing может выглядеть следующим образом:
procedure AssignDev(var F: Text);
begin
with TextRec(F) do
begin
mode := fmClosed;
BufSize := SizeOf(Buffer);
BufPtr := @Buffer;
OpenFunc := @DevOpen;
InOutFunc := @DevInOut;
FlushFunc := @DevFlush;
CloseFunc := @DevClose;
Name[0] := #0;
end;
end;
Для хранения пользовательской информации в функции, реализу-
ющей интерфейс с устройством, может использоваться поле записи
UserData. Это поле не изменяется файловой системой Borland
Pascal.
Функция Open
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Функция Open вызывается стандартными процедурами Rеset,
Rеwritе и Appеnd для открытия текстового файла, связанного с уст-
ройством. Чтобы отметить была ли функция Open вызвана из процеду-
ры Rеset, Rеwritе или Appеnd, на входе поле Моdе содержит значе-
ние fmInput, fmOutput или fmInOut.
В соответствии со значением Моdе функция Open подготавливает
файл для ввода или вывода. Если в Моdе указывается FmInOut (ука-
зывая, что функция Оpеn была вызвана из Appеnd), то перед возвра-
том управления функцией Оpеn это значение должно быть изменено на
fmOutput.
Функция Opеn всегда вызывается перед любой другой функцией,
реализующей интерфейс с устройством. По этой причине функция
Assign инициализирует только поле OpеnFunc, откладывая инициали-
зацию оставшихся векторов до завершения выполнения функции Opеn.
Основываясь на значении поля Моdе функция Opеn может установить
указатели как для функций, ориентированных на ввод, так и для
функций, ориентированных на вывод. Это позволяет избежать опреде-
ления текущего режима в функциях InOut, Flush и Close.
Функция InOut
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Всякий раз, когда требуется ввод с устройства или вывод на
него, функциями Readln, Read, Write, Writeln, Page, Eof, SeekEof,
SeekEoln и Close вызывается функция InOut.
Когда в поле Моdе установлено значение fnInput, функция
InOut считывает символы (объем ввода задается переменной BufSize)
в BufPtr^ и возвращает число считанных символов в BufEnd, а также
записывает 0 в BufPos. Если функция InOut в результате запроса на
ввод возвращает в BufEnd значение 0, то переменная Eоf для файла
принимает значение Truе.
Когда в поле Моdе установлено значение fnOutput, функция
InOut записывает символы, количество которых определяется пере-
менной BufРоs, из BufPtr^ и возвращает в BufРоs значение 0.
Функция Flush
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Функция Flush вызывается в конце выполнения каждой функции
Rеаd, Write, Rеаdln или Writeln. Она может также сбрасывать буфер
текстового файла.
Если в поле Моdе находится fmInput, функция Flush для того,
чтобы отбросить оставшиеся (несчитанные) символы в буфере, может
записать 0 в BufPos и BufEnd. Это средство используется редко.
Если в поле Моdе находится fnOutput, то функция Flush может
записать содержимое буфера, в точности таким же образом, как
функция InOut. Этим обеспечивается, что выведенный на устройство
текст появится на устройстве немедленно. Если функция Flush не
выполняет никаких действий, текст не будет выведен на устройство,
пока буфер не станет полным, или файл не будет закрыт.
Функция Clоsе
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Функция Clоsе вызывается стандартной процедурой Clоsе для
закрытия связанного с устройством текстового файла. (Процедуры
Rеsеt, Rеwritе, Appеnd также вызывают функцию Clоsе, если файл,
который они открывают, уже был открыт.) Если в поле Моdе находит-
ся fmOut, то перед вызовом функции Clоsе файловая система Турбо
Паскаля обращается к функции InOut. Это гарантирует вывод на уст-
ройство всех символов.
Глава 15. Использование сопроцессора 80x87
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В Borland Pascal вы можете работать с двумя типами чисел -
целыми (короткими целыми - Shortint, целыми - Integer, длинными
целыми - Longint, целыми длиной в байт - Byte, целыми длиной в
слово - Word) и вещественными (вещественными - Real, вещественны-
ми одинарной точности - Single, вещественными двойной точности -
Double, повышенной точности - Extended, сложными - Comp). Вещест-
венные числа называют также числами с плавающей точкой (плавающей
запятой). Для облегчения работы с целыми числами создан процессор
8086, но для работы с вещественными числами на этом процессоре
затрачивается гораздо больше времени и усилий. Для семейства про-
цессоров 8086 предназначено соответствующее семейство вспомога-
тельных специализированных процессоров для математических вычис-
лений (сопроцессоров) 80x87.
Процессор 80x87 - это специальный сопроцессор для обработки
чисел, который может входить в состав вашего компьютера РС. С по-
мощью него операции с плавающей точкой выполняются очень быстро.
Поэтому если вы собираетесь использовать большой объем вычислений
с плавающей точкой, то вам, вероятно, понадобится сопроцессор.
Borland Pascal построен таким образом, что он обеспечивает
оптимальное выполнение операций с плавающей точкой независимо от
наличия сопроцессора 80x87.
* Для программ, работающих на компьютере РС, независимо от
того, оснащен он сопроцессором 80x87 или нет, в Borland
Pascal предусмотрено использование вещественных чисел и
соответствующая библиотека программ, которые предназначены
для выполнения операций с плавающей точкой. Числа вещест-
венного типа занимают 6 байт памяти. При этом обеспечива-
ется представление чисел в диапазоне от 2.9х10^-39 до
1.7х10^38 с 11-12 значащими цифрами. Программы в библиоте-
ке программ для работы с плавающей точкой оптимизированы
по скорости и по размеру и используют самые новейшие
средства процессора 80x87.
* Если вы пишете программы, использующиеся только на компь-
ютерах, оснащенных сопроцессором 80x87, то вы можете ука-
зать Borland Pascal на необходимость получения выполняемо-
го кода, в котором используется плата процессора 80x87.
Это даст вам возможность использования четырех дополни-
тельных типов вещественных чисел (одинарной и двойной точ-
ности, повышенной точности, сложного типа) и расширенный
диапазон представления чисел с плавающей точкой - от
1.9х10^-4951 до 1,1х10^4943 с 19-20 значащими цифрами.
С помощью директивы компилятора $N или параметра меню
OptionsіCоmpiler (ПараметрыіКомпилятор) 80x87/80287 можно перек-
лючаться между различными моделями генерации кода с плавающей
точкой. По умолчанию используется состояние {$N-}. В этом состоя-
нии компилятор использует 6-байтовую библиотеку с плавающей точ-
кой, что позволяет вам работать только с переменными типа Real. В
состоянии {$N+} компилятор генерирует код для сопроцессора 80x87,
что дает вам дополнительную точность и доступ к 4 дополнительным
вещественным типам.
В Windows при компиляции с режимом числовой обработки, то
есть с директивой {$N+}, убедитесь, что в вашей системе можно
найти библиотеку эмуляции Windows 8087 - WIN87EM.DLL. Эта библио-
тека обеспечивает необходимый интерфейс между сопроцессором
80х87, Windows и вашей прикладной программой. Если сопроцессор
80х87 в вашей системе отсутствует, то библиотека WIN87EM.DLL бу-
дет эмулировать его программно. Эмуляция существенно замедляет
работу по сравнению с реальным сопроцессором 80х87, но обеспечи-
вает выполнение вашей прикладной программы на любой машине.
В реальном или защищенном режиме DOS, даже если у вас нет
сопроцессора 8087, вы можете указать Borland Pascal, что нужно
включить библиотеку исполняющей системы, которая эмулирует ариф-
метический сопроцессор 8087. В случае наличия сопроцессора 8087
он используется. Если сопроцессор отсутствует, его работа эмули-
руется библиотекой исполняющей системы (за счет некоторой потери
скорости работы программы).
Для разрешения и запрещения эмуляции сопроцессора 8087 ис-
пользуются директива компилятора $E и параметр Emulation (Эмуля-
ция) меню OptionsіCompiler (ПараметрыіКомпилятор). По умолчанию
используется состояние {$E+}. В этом состоянии в программу авто-
матически включается полная эмуляция сопроцессора 8087. В состоя-
нии {$E-} используется существенно меньшая часть библиотеки с
плавающей точкой, а полученный в результате файл .EXE будет рабо-
тать только на машинах с сопроцессором 8087.
В приложении Windows директива компилятора $E не действует.
Не действует она также в модуле. Более того, если программа ком-
пилировалась с директивой {$N-}, а все модули программы компили-
ровались с директивой {$N+}, то библиотека исполняющей системы
для сопроцессора 8087 не требуется, и директива компилятора $E
игнорируется.
Прикладной программе Windows не требуется библиотека испол-
няющей системы 80x87. Вместо этого ей нужно поддерживающая библи-
отека WIN87EM.DLL, поставляемая с Windows, которая обеспечивает
необходимый интерфейс между вашей прикладной программой, Windows
и сопроцессором. Таким образом, в Windows даже при наличии в ва-
шей системе сопроцессора 80х87 для выполнения программ, скомпили-
рованных в состоянии {$N+}, должна присутствовать библиотека эму-
ляции WIN87EM.DLL (данная библиотека - это часть Windows, а не
Borland Pascal). При отсутствии сопроцессора WIN87EM.DLL будет
эмулировать его операции программным путем, что замедляет выпол-
нение программы и не гарантирует, что использующая сопроцессор
80x87 программа сможет работать на любой машине.
Когда вы запускаете прикладную программу Windows, cкомпили-
рованную в состоянии {$N+}, убедитесь, что она может найти в сис-
теме файл WIN87EM.DLL.
Когда вы выполняете компиляцию в режиме кода 80х87 (директи-
ва {$N+}), то возвращаемые подпрограммы модуля Systем (Sqrt, Рi,
Sin и т.д.) значения представляют собой не вещественные числа, а
числа типа Extended (с повышенной точностью).
{$N+}
begin
Writeln(Pi); { 3.14159265358979E+0000 }
end.
{$N-}
begin
Writeln(Pi); { 3.1415926536E+00 }
end.
В оставшейся части данной главы обсуждаются специальные воп-
росы, касающиеся использования процессора 80x87 в программах
Borland Pascal.
Типы данных процессора 80x87
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В дополнение к вещественному типу для программ, использующих
средства процессора 80x87, предусматривается четыре новых вещест-
венного типа:
1. Тип с одинарной точностью Single, представляющий собой
наименьший формат, который вы можете использовать для
чисел с плавающей точкой. Он занимает 4 байта памяти
обеспечивает диапазон представления чисел от 1.5х10^-45
до 3.4х10^48 с 7-8 значащими цифрами.
2. Тип с двойной точностью Double, занимающий 8 байт памяти
и обеспечивающий представление чисел в диапазоне от
5.0х10^-334 до 1.7х10^308 с 15-16 значащими цифрами.
3. Тип с повышенной точностью Extended представляет собой
наибольший формат представления чисел с плавающей запя-
той, обеспечиваемый процессором 8087. Он занимает 10
байт памяти и обеспечивает диапазон представления чисел
от 1.9х10^-4952 до 1.1х10^4932 с 19-20 значащими цифра-
ми. Любые арифметические операции, в которых участвуют
числа вещественного типа, выполняются с точностью и диа-
пазоном представления, соответствующими типу с повышен-
ной точностью.
4. Числа сложного типа Comp используются для предварительно
объединенных значений в 8 байтах памяти, обеспечивая при
этом диапазон представления от -2^63+1 до 2^63-1, что
составляет приблизительно от -9.2х10^18 до 9.2х10^18.
Сложный тип можно сравнить с длинным целым типом (двой-
ная точность), но он считается вещественным типом, пос-
кольку при операциях с числами этого типа используется
сопроцессор 8087. Сложный тип хорошо подходит для предс-
тавления значений денежных единиц, представляющих собой
сотни и тысячи, которые используются в прикладных ком-
мерческих программах.
Независимо от того, используете вы сопроцессор 80x87 или
нет, 6-битовый вещественный тип является допустимым. Таким обра-
зом, при переходе к использованию сопроцессора 80 x87 вам не пот-
ребуется изменять исходный текст программы, и вы можете использо-
вать файлы данных, созданные программами, которые работают с
программно обеспечиваемыми операциями с плавающей точкой.
Отметим, однако, что аппаратные вычисления с переменными ве-
щественного типа выполняются несколько медленнее, чем с перемен-
ными другого типа. Это связано с тем, что сопроцессор 80x87 не
может непосредственно обрабатывать вещественный формат. Вместо
этого, перед выполнением операций, для преобразования веществен-
ных значений в числа с повышенной точностью требуются обращения к
библиотечным программам. Если вы заинтересованы в максимальной
скорости выполнения и не собираетесь использовать свою программу
на системах без сопроцессора 80x87, то возможно вы захотите ис-
пользовать вещественный тип с одинарной точностью, вещественный
тип с двойной точностью, вещественный тип с повышенной точностью
и сложный типы явным образом.
Арифметические операции с повышенной точностью
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При использовании сопроцессора 80x87 тип с повышенной точ-
ностью Extended является основой всех операций с плавающей точ-
кой. В Турбо Паскале тип с повышенной точностью используется для
представления всех нецелых числовых констант, а также при вычис-
лении всех выражений нецелого типа. Например, в следующих опера-
циях присваивания все правые части выражений будут вычисляться,
как выражения с повышенной точностью, а затем их тип будет преоб-
разован к типу соответствующей левой части:
{$N+}
var
X, AA, B, C : real;
begin
X := (B + Sqrt(B*B - A*C))/A;
end;
Borland Pascal выполняет вычисления с точностью и диапазоном
представления чисел, соответствующими типу с повышенной точ-
ностью, без дополнительных усилий программиста. Дополнительная
точность приводит к меньшим ошибкам округления, а дополнительный
диапазон означает, что ситуации переполнения и потери значимости
будут встречаться в программах реже.
Вы можете обойтись и без дополнительных автоматических воз-
можностей вычислений с повышенной точностью Borland Pascal. Нап-
ример, описать переменные, использующиеся для промежуточных вы-
числений, как переменные с повышенной точностью. В следующем при-
мере вычисляется сумма произведений:
var
Sm : single;
X,Y array[1..100] of single;
I : integer;
T : extended; { для промежуточных результатов }
begin
T := 0.0;
for I := 1 to 100 do T := T + X[I] * Y[I]
Sum := T;
end;
Если бы переменная T была описана, как переменная с одинар-
ной точностью, то при каждом цикле операции присваивания для пе-
ременной T были бы выполнены с ошибкой округления и ограничения-
ми, соответствующими одинарной точности. Но, поскольку переменная
T является переменной с повышенной точностью, то все ошибки ок-
ругления (кроме операции, при которой значение переменной T прис-
ваивается переменной Suм) имеют ограничения, соответствующие по-
вышенной точности. Меньшие ошибки округления означают более точ-
ный результат.
Для значений формальных параметров и результата функции вы
также можете задать повышенную точность. Это поможет избежать не-
нужных преобразований типов чисел, приводящих к потере точности.
Например:
function Area(Radius: extended): extended;
begin
Area := Pi * Radius * Radius;
end;
Сравнение вещественных чисел
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Поскольку значения вещественного типа являются приблизитель-
ными, результат сравнения значений различного вещественного типа
не всегда можно предсказать. Например, если Х - переменная ве-
щественного типа с одинарной точностью, а Y - переменная вещест-
венного типа с двойной точностью, то результатом выполнения сле-
дующих операторов будет значение False:
X := 1/3;
Y := 1/3;
Writeln(X = Y);
Причина этого состоит в том, что Х имеет точность только до
7-8 цифр, а Y - точность до 15-16 цифр, и когда оба значения пре-
образуются к типу с повышенной точностью, то после первых 7-8
цифр остальные цифры будут различаться. Аналогично, результатом
выполнения операторов:
X := 1/3;
Writeln(X = 1/3);
будет значение False, результат 1/3 в операторе Writeln вычисля-
ется с точностью до 20 значащих цифр.
Стек вычислений сопроцессора 80x87
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
У сопроцессора 80x87 имеется внутренний стек вычислений, ко-
торый может быть глубиной до восьми уровней. Доступ к значению,
находящемуся в стеке сопроцессора 80x87 осуществляется намного
быстрее, чем доступ к переменной в памяти, поэтому для достижения
максимально возможной производительности в Borland Pascal внут-
ренний стек сопроцессора 80x87 используется для хранения времен-
ных результатов и для передачи параметров процедурам и функциям.
Теоретически, слишком сложные выражения вещественного типа
могут вызвать переполнение стека сопроцессора 80x87. Однако этого
не может случиться, поскольку для этого потребовалось бы, чтобы в
выражении получалось более восьми промежуточных результатов.
Более весомая опасность таится во вложенных вызовах функций.
Если такие конструкции составлены некорректно, то они, вполне ве-
роятно, могут привести к переполнению стека сопроцессора 80x87.
Рассмотрим, следующую функцию, в которой с помощью рекурсии
вычисляются числа Фибоначчи:
function Fib(N: integer): extended;
begin
if N = 0 then
Fib := 0.0
else
if N = 1 then
Fib := 1.0
else
Fib := Fib(N-1) + Fib(N-2);
end;
Обращение к данной версии процедуры Fib приведет к перепол-
нению стека сопроцессора 80x87, так как значений N больше, чем 8.
Причина заключается в том, что последний оператор присваивания
требует временного сохранения результата выполнения процедуры Fib
(N-1) в стеке сопроцессора 80x87. Каждое рекурсивное обращение
выделяется одна ячейка стека и на девятом обращении произойдет
переполнение стека. Корректной конструкцией в этом случае будет:
function Fib(N : integer) : extended;
var
F1,F2 : Extended;
begin
if N = 0 then
Fib := 0.0
else
if N = 1
then Fib := 1.0
else
begin
F1 := Fib(N-1); F2 := Fib(N-2);
Fib := F1 + F2;
end;
end;
Временные результаты теперь сохраняются в переменных, для
которых отводится стек процессора 8086. (Стек процессора 8086 ко-
нечно тоже может переполниться, но это обычно требует гораздо
большего числа рекурсивных вызовов).
Запись вещественных чисел
при использовании сопроцессора 80x87
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Если была указана директива {$N+}, то стандартные процедуры
Write и Writeln, чтобы обеспечить представление в расширенном ди-
апазоне, выводят в строке с десятичными числами с плавающей точ-
кой четыре цифры для показателя степени вместо двух. Аналогично,
стандартная процедура Str при выборе формата с плавающей точкой
возвращает значение показателя степени, состоящее из четырех
цифр.
Модули, в которых используется сопроцессор 80x87
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Модули, в которых используется сопроцессор 80x87, могут вы-
зываться другими модулями или программами только в том случае,
если эти модули или программы были скомпилированы с директивой
{$N+}. То, что модуль использует сопроцессор 80x87, определяется
наличием в нем инструкций сопроцессора 80x87, а не директивой $N
во время компиляции. Это позволяет компилятору быть более "снис-
ходительным", когда вы случайно компилируете модуль (в котором
используется сопроцессор 80x87), не указав директиву {$N+}.
Когда вы выполняете компиляцию в режиме кода 80х87 (директи-
ва {$N+}), то возвращаемые подпрограммами модуля Systем (Sqrt,
Рi, Sin и т.д.) значения представляют собой не вещественные чис-
ла, а числа типа Extended (с повышенной точностью).
Распознавание сопроцессора 80х87 в программах DOS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Исполняющая библиотека Borland Pascal, встроенная в вашу
программу (скомпилированную с директивой {$N+}) включает в себя
код инициализации, который автоматически распознает наличие в
системе микросхемы сопроцессора 8087. Если сопроцессор 8087 име-
ется, то программа будет его автоматически использовать. В случае
же его отсутствия программа будет использовать эмулирующую библи-
отеку исполняющей системы. Если программа компилировалась с ди-
рективой {$E-} и по время начала ее работы сопроцессор не обнару-
живается, то программа завершает работу с сообщением Numeric
coprocessor required ("Требуется сопроцессор арифметических вы-
числений").
Есть несколько случаев, когда вы возможно захотите изменить
такую принятую по умолчанию логику автоматического обнаружения
сопроцессора. Например, в вашей системе может присутствовать соп-
роцессор 8087, но вы захотите проверить, как будет работать прог-
рамма, предназначенная для функционирования на системах без соп-
роцессора. Или же потребуется запустить вашу программу на
системе, совместимой с компьютером РС, но на этой системе при ра-
боте алгоритма автообнаружения будет выводиться некорректная ин-
формация (например, будет сообщаться о наличие сопроцессора, ког-
да на самом деле его нет, или наоборот).
В Borland Pascal предусмотрена возможность отмены принятой
по умолчанию логики автоматического распознавания. Эта возмож-
ность задается переменной операционной среды 87.
Вы можете установить переменную операционной среды 87 в от-
вет на подсказку DOS с помощью команды SET, например, следующим
образом:
SET 87=Y
или
SET 87=N
Установка для переменной операционной среды 87 значения N
(Нет) указывает коду инициализации, что вы не хотите использовать
сопроцессор 8087, хотя он может и присутствовать в системе. И на-
оборот: установка для переменной 87 значения Y (Да) означает, что
сопроцессор имеется, и вы хотите, чтобы ваша программа его ис-
пользовала. Однако при этом нужно помнить о том, что установка
для переменной 87 значения Y при отсутствии в системе сопроцессо-
ра 8087 приведет к тому, что ваша программа аварийно завершит ра-
боту или "зависнет".
Если переменная операционной среды 87 определена, а вы хоти-
те, чтобы она стала неопределенной, то можно ввести в ответ на
подсказку DOS:
SET 87=
и нажать клавишу Enter.
Если в операционной среде DOS присутствует запись 87=Y, или
если код инициализации успешно распознает сопроцессор, то далее
код инициализации выполняет последующие проверки, чтобы опреде-
лить, какой это сопроцессор (8087, 80287 или 80387). Это необхо-
димо для того, чтобы Турбо Паскаль мог корректно работать с от-
дельными несовместимостями, которые имеются между сопроцессорами
различных типов.
Результат автоматического распознавания наличия сопроцессора
и его модели сохраняется в переменной Test8087 (которая описыва-
ется в модуле System). Для нее определены следующие значения:
ЪДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Значение і Определение і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і 0 і сопроцессор не обнаружен і
і 1 і обнаружен сопроцессор 8087 і
і 2 і обнаружен сопроцессор 80287 і
і 3 і обнаружен сопроцессор 80387 і
АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Чтобы определить характеристики системы, на которой работает
ваша программа, вы можете в программе проверить содержимое пере-
менной Test8087. В частности, эту переменную можно проанализиро-
вать для того, чтобы определить, эмулируются инструкции работы с
плавающей точкой, или они действительно выполняются.
Распознавание сопроцессора 80x87 в программе Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Операционная среда Windows и библиотека эмуляции WIN87EM.DLL
автоматически распознает наличие в системе платы сопроцессора
80x87. Если сопроцессор 80x87 имеется, то программа будет его ав-
томатически использовать. В случае же его отсутствия программа
будет использовать эмуляцию с помощью WIn87EM.DLL. Чтобы опреде-
лить наличие в системе сопроцессора 80х87, вы можете использовать
функцию GetWinFlags (которая определена в модуле WinProcs) и би-
товую маску wf_80x87 (определенную в модуле WinTypes). Например:
if GetWinFlags and wf_80x87 <> 0 then
Writeln('80x87 присутствует') else
Writeln('80x87 отсутствует');
Использование эмуляции
сопроцессора 80x87 на языке ассемблера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда компоновка объектных файлов выполняется с директивой
{$L имя_файла}, необходимо обеспечить, чтобы эти файлы компилиро-
вать с разрешением эмуляции сопроцессора 80x87. Например, если вы
используете инструкции сопроцессора 80x87 во внешних процедурах
на языке ассемблера, необходимо убедиться, что при ассемблирова-
нии файлов .ASM в файлы .OBJ эмуляция разрешена. В противном слу-
чае инструкции сопроцессора 80x87 не могут эмулироваться на маши-
нах без сопроцессора 80x87. Для разрешения эмуляции используйте
параметр командной строки Турбо Ассемблера /E.
Глава 16. Модуль Dоs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
С помощью модулей Dos и WinDos реализуется целый ряд прог-
рамм операционной системы и программ обработки файлов. Ни одна из
программ модуля Dos не определена в стандартном Паскале, поэтому
они помещаются в отдельный модуль.
Более полное описание операций DOS приведено в руководствах
по DOS фирмы IBM.
Основное различие модулей Dos и WinDos состоит в том, что
процедуры и функции модуля Dos используют стандартные строки Пас-
каля, а процедуры и функции модуля WinDos - строки с завершающим
нулем. Стандартная строка Паскаля - это байт длины, за которым
следует последовательность символов. Строка с завершающим нулем -
это последовательность ненулевых символов с завершающим символом
NULL (#0).
Примечание: Подробнее о различии этих строк рассказы-
вается в Главе 18.
Если вы разрабатываете только программы Windows, используйте
модуль WinDos.
Если вы разрабатываете только программы DOS, то желательно
пользоваться в программах модулем Dos, так как большинство прог-
рамм Паскаля традиционно работают со строками Паскаля. Однако,
если вы разрабатываете приложения для среды Windows, то можете
написать программу, используемую в обеих платформах - DOS и
Windows, применяя для этого модули WinDos и Strings. Windows тре-
бует использования строк с завершающим нулем. Вы можете также
воспользоваться данными модулями, если у вас есть файл данных Си,
и вы хотите его конвертировать. В языке Си используются строки с
завершающим нулем.
Процедуры и функции модуля Dos
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Ниже перечислены процедуры и функции модуля Dos. Чтобы ис-
пользовать их, вы должны ссылаться на модуль Dos с помощью опера-
тора программы uses. См. также Главу 1 ("Справочник по библиоте-
ке") в "Руководстве программиста".
Процедуры для работы с датой и временем
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetDate і Возвращает текущую дату, установленную ві
і і операционной системе. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetFTime і Возвращает дату и время последней записиі
і і файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetTiме і Возвращает текущее время, установленное ві
і і операционной системе. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і РackTiме і Преобразует запись DateTiме в четырехбайто-і
і і вое упакованное символьное представлениеі
і і даты и времени длинного целого типа, кото-і
і і рое используется в процедуре SetTiме. Поляі
і і записи DateTiме не проверяются на допусти-і
і і мость границ. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetDate і Устанавливает для операционной системы те-і
і і кущую дату. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetFTiме і Устанавливает время и дату последней записиі
і і файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetTiме і Устанавливает в операционной системе теку-і
і і щее время. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і UnpackTiме і Преобразует четырехбайтовое упакованнойі
і і символьное представление даты и времениі
і і длинного целого типа, возвращаемого проце-і
і і дурами GetFTiме, FindFirst, FindNext в рас-і
і і пакованную запись DateTiме. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры и функции обслуживания прерываний
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetIntVес і Возвращает адрес, сохраненный в заданномі
і і векторе прерываний. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Intr і Выполняет заданное программное прерывание.і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і МsDos і Выполняет вызов функции DOS. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetIntVес і Устанавливает по заданному адресу заданныйі
і і вектор прерывания. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Функции, проверяющие состояние диска
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Фуннкция і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DiskFrее і Возвращает число свободных байт на диске ві
і і заданном дисководе. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DiskSize і Возвращает полный объем в байтах заданногоі
і і диска. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры обработки файлов
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FExpand і Воспринимает имя файла и возвращает полноеі
і і уточненное имя (диск, каталог, расширение).і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FSearch і Ищет файл в списке каталогов. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FindFirst і Производит поиск в заданном (или текущем)і
і і каталоге записи, содержимое которой совпа-і
і і дает с заданным именем файла и атрибутами.і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FindNext і Возвращает следующую запись, имя файла иі
і і атрибуты в которой совпадают с теми, кото-і
і і рые были заданы при предыдущем обращении кі
і і процедуре FindFirst. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetFAttr і Возвращает атрибуты файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetFAttr і Устанавливает атрибуты файла. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Функции управления операционной средой
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і EnvCount і Возвращает число строк, содержащихся в опе-і
і і рационной среде DOS. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і EnvStr і Возвращает заданную строку операционнойі
і і среды. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetEnv і Возвращает значение заданной переменнойі
і і операционной среды. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры управления процессами
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Eхесutе і Выполняет заданную программу с указаннойі
і і командной строкой. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Keep і Сохраняет (прекращает выполнение и сохраня-і
і і ет в памяти) прекратившую работу программу,і
і і оставляя ее резидентной в памяти. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SwapVectors і Меняет местами содержимое сохраненных век-і
і і торов прерываний и текущих векторов. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Прочие процедуры и функции
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іПроцедура/функция і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DosVersion і Возвращает номер версии операционной систе-і
і і мы DOS. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetCBreak і Возвращает проверяемое DOS состояниеі
і і Ctrl+Break. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetCBreak і Устанавливает проверяемое DOS состояниеі
і і Ctrl+Break. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetVerify і Возвращает состояние флага проверки в DOS. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetVerify і Устанавливает состояние флага проверки ві
і і DOS. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Константы, типы и переменные модуля Dos
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В данном разделе кратко обсуждаются константы, типы и пере-
менные, определяемые в модуле Dos. Более детальная информация со-
держится в разделе "Константы флагов" (значение FParity) в Главе
1 ("Справочник по библиотеке") "Справочного руководства програм-
миста".
Группы констант
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Группа констант і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Флаги і Используются для проверки отдель-і
і і ных флагов после вызова функцийі
і і Intr или MsDos. Это флаги:і
і і FParity, FAuxiliary, FZero,і
і і FSign, FOverflow, fCarry. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і fmXXXX і Определяет допустимые значенияі
і і поля Mode записи TextRec тексто-і
і і вого файла: fmClosed, fmInput,і
і і fmOutput, fmInOut. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Атрибуты файла і Используются для построения ат-і
і і рибутов, применяемых в FindFirst,і
і і GetFAttr и SetFAttr. Это флагиі
і і ReadOnly, Hidden, SysFile,і
і і VolumeID, Directory, Archive,і
і і AnyFile. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Типы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В модуле Dos определяются следующие типы:
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Тип і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Тип записи файла і Определения записей, использующие-і
і і ся в Borland Pascal для внутреннихі
і і целей, описываются также в модулеі
і і Dos. Тип FilеRес используется какі
і і для типизованных, так и для нетипи-і
і і зованных файлов, в то время, какі
і і TехtRес представляет собой внутрен-і
і і ний формат переменной текстовогоі
і і типа. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Registers і Переменные регистрового типа приме-і
і і няются в процедурах Intr и МsDosі
і і для задания содержимого входногоі
і і регистра и проверки содержимого вы-і
і і ходного регистра при прерываниях,і
і і использующихся в программном обес-і
і і печении. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DateTime і Переменные типа DateTiме (даты иі
і і времени) используются в процедурахі
і і UnраскТiме и РаскТiме для анализа,і
і і упаковки и построения четырехбайто-і
і і вого значения, содержащего дату иі
і і время. Это четырехбайтовое значениеі
і і используется затем в процедурахі
і і GetFTiме, SetTiме, FindFirst иі
і і FindNехt. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SearchRec і Переменные типа SearchRес использу-і
і і ются в процедурах FindFirst иі
і і Findnext для просмотра каталогові
і і файлов. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Строковые типы і Эти строковые типы определены в мо-і
і работы с файлами і дуле Dos и используются для работыі
і і с именами файлов и маршрутов приі
і і вызове строковой процедуры FSplit.і
і і Это типы ComStr, PathStr, DirStr,і
і і NameStr, ExtStr. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Переменные модуля Dos
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Многими подпрограммами модуля Dos для сообщения об ошибке
используется переменная DosError.
Процедуры и функции модуля WinDos
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Ниже перечислены процедуры и функции модуля WinDos. Чтобы
использовать их, вы должны ссылаться на модуль WinDos с помощью
оператора программы uses.
Процедуры для работы с датой и временем модуля WinDos
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetDate і Возвращает текущую дату, установленную ві
і і операционной системе. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetFTime і Возвращает дату и время последней записиі
і і файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetTiме і Возвращает текущее время, установленное ві
і і операционной системе. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і РackTiме і Преобразует запись DateTiме в четырехбайто-і
і і вое упакованное символьное представлениеі
і і даты и времени длинного целого типа, кото-і
і і рое используется в процедуре SetTiме. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetDate і Устанавливает для операционной системы те-і
і і кущую дату. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetFTiме і Устанавливает время и дату последней записиі
і і файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetTiме і Устанавливает в операционной системе теку-і
і і щее время. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і UnpackTiме і Преобразует четырехбайтовое упакованнойі
і і символьное представление даты и времениі
і і длинного целого типа, возвращаемого проце-і
і і дурами GetFTiме, FindFirst, FindNext в рас-і
і і пакованную запись DateTiме. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры обслуживания прерываний модуля WinDos
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetIntVес і Возвращает адрес, сохраненный в заданномі
і і векторе прерываний. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Intr і Выполняет заданное программное прерывание.і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і МsDos і Выполняет вызов функции DOS. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetIntVес і Устанавливает по заданному адресу заданныйі
і і вектор прерывания. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Функции модуля WinDos, проверяющие состояние диска
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Фуннкция і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DiskFrее і Возвращает число свободных байт на диске ві
і і заданном дисководе. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DiskSize і Возвращает полный объем в байтах заданногоі
і і диска. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры работы с файлами модуля WinDos
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FileExpand і Воспринимает имя файла и возвращает полноеі
і і уточненное имя (диск, каталог, расширение).і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FileSearch і Ищет файл в списке каталогов. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FileSplit і Разбивает полное имя файла на три компонен-і
і і та (диск, каталог, имя и расширение). і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FindFirst і Производит поиск в заданном (или текущем)і
і і каталоге записи, содержимое которой совпа-і
і і дает с заданным именем файла и атрибутами.і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FindNext і Возвращает следующую запись, имя файла иі
і і атрибуты в которой совпадают с теми, кото-і
і і рые были заданы при предыдущем обращении кі
і і процедуре FindFirst. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetFAttr і Возвращает атрибуты файла. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetFAttr і Устанавливает атрибуты файла. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры и функции для работы с каталогами
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура/функцияі Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CreateDir і Создает новый подкаталог. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetCurDir і Возвращает текущий каталог на заданном дис-і
і і ке. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і RemoveDir і Удаляет подкаталог. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetCurDir і Изменяет текущий каталог. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Процедуры и функции обслуживания прерываний модуля WinDos
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Процедура і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetArgCount і Возвращает число параметров, переданныхі
і і программе в командной строке. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetArgStr і Возвращает заданный аргумент команднойі
і і строки. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetEnvVar і Возвращает указатель на значение заданнойі
і і переменной операционной среды. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Прочие процедуры и функции модуля WinDos
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іПроцедура/функция і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DosVersion і Возвращает номер версии операционной систе-і
і і мы DOS. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetCBreak і Возвращает проверяемое DOS состояниеі
і і Ctrl+Break. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetCBreak і Устанавливает проверяемое DOS состояниеі
і і Ctrl+Break. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetVerify і Устанавливает состояние флага проверки ві
і і DOS. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Константы, типы и переменные модуля WinDos
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В данном разделе кратко обсуждаются константы, типы и пере-
менные, определяемые в модуле WinDos. Более детальная информация
содержится в разделе "Константы флагов" (значение FParity) в Гла-
ве 1 ("Справочник по библиотеке") "Справочного руководства прог-
раммиста".
Группы констант
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Группа констант і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Флаги і Используются для проверки отдель-і
і і ных флагов после вызова функцийі
і і Intr или MsDos. Это флаги:і
і і FParity, FAuxiliary, FZero,і
і і FSign, FOverflow, fCarry. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і fmXXXX і Определяет допустимые значенияі
і і поля Mode записи TextRec тексто-і
і і вого файла: fmClosed, fmInput,і
і і fmOutput, fmInOut. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і faXXXX і Используются для построения ат-і
і і рибутов, их проверки и измененияі
і і в процедурах и функциях работы сі
і і файлами. Это константы faHidden,і
і і faSysFile, faVolumeID, faDirecto-і
і і ry, faArchive, faAnyFile. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і fsXXXX і Максимальные длины компонентові
і і имени файла, используемых в под-і
і і программах FileSearch и File-і
і і Expand. Это константы: fsPathNa-і
і і me, fsDirectory, fsFileName,і
і і fsExtension. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і fcXXXX і Флаги, возвращаемые функциейі
і і FileSplit: fcExtension, fcFile-і
і і Name, fcDirectory, fcWildcards. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Типы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В модуле WinDos определяются следующие типы:
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Тип і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Тип записи файла і Определения записей, использующие-і
і і ся в Borland Pascal для внутреннихі
і і целей, описываются также в модулеі
і і Dos. Тип TFilеRес используется какі
і і для типизованных, так и для нетипи-і
і і зированных файлов, в то время, какі
і і TTехtRес представляет собой внут-і
і і ренний формат переменной текстовогоі
і і типа. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TRegisters і Переменные регистрового типа приме-і
і і няются в процедурах Intr и МsDosі
і і для задания содержимого входногоі
і і регистра и проверки содержимого вы-і
і і ходного регистра при прерываниях,і
і і использующихся в программном обес-і
і і печении. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TDateTime і Переменные типа TDateTiме (даты иі
і і времени) используются в процедурахі
і і UnраскТiме и PаскТiме для анализа,і
і і упаковки и построения четырехбайто-і
і і вого значения, содержащего дату иі
і і время. Это четырехбайтовое значениеі
і і используется затем в процедурахі
і і GetFTiме, SetTiме, FindFirst иі
і і FindNехt. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і TSearchRec і Переменные типа TSearchRес исполь-і
і і зуются в процедурах FindFirst иі
і і Findnext для просмотра каталогові
і і файлов. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Переменные модуля WinDos
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Многими подпрограммами модуля WinDos для сообщения об ошибке
используется переменная DosError.
Глава 17. Программирование в защищенном режиме DOS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Микропроцессор 80286 дает новый способ адресации к памяти:
защищенный режим виртуальной адресации или просто защищенный ре-
жим. Этот новый режим адресации дает три основных преимущества:
* Адресация к памяти объемом до 16 мегабайт.
* Логическое адресное пространство, превышающее пространство
физических адресов.
* Способ изоляции программ друг от друга, так что одна прог-
рамма не может нарушать другой выполняющейся одновременно
с ней программы.
С помощью Borland Pascal вы легко можете писать работающие в
защищенном режиме прикладные программы DOS без необходимости при-
менения дополнительного "расширителя" DOS. Вы обнаружите, что
многие программы реального режима прекрасно работают в защищенном
режиме. Данная глава поможет вам модифицировать те программы, ко-
торые этого не делают, и прояснит некоторые основные моменты за-
щищенного режима и его отличия от реального режима.
Что такое защищенный режим?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Процессор 80286 и более поздние процессоры поддерживают два
режима операций: защищенный режим и реальный режим. Реальный ре-
жим совместим с работой процессора 8086 и позволяет прикладной
программе адресоваться к памяти объемом до одного мегабайта. За-
щищенный режим расширяет диапазон адресации до 16 мегабайт. Ос-
новное отличие между реальным и защищенным режимом заключается в
способе преобразования процессором логических адресов в физичес-
кие. Логические адреса - это адреса, используемые в прикладной
программе. Как в реальном, также и в защищенном режиме логический
адрес - это 32-разрядное значение, состоящее из 16-битового се-
лектора (адреса сегмента) и 16-битового смещения. Физические ад-
реса - это адреса, которые процессор использует для обмена данны-
ми с компонентами системной памяти. В реальном режиме физический
адрес представляет собой 20-битовое значение, а в защищенном ре-
жиме - 24-битовое.
Когда процессор обращается к памяти (для выборки инструкции
или записи переменной), он генерирует из логического адреса физи-
ческий адрес. В реальном режиме генерация физического адреса сос-
тоит из сдвига селектора (адреса сегмента) на 4 бита влево (это
означает умножение на 16) и прибавления смещения. Полученный в
результате 20-разрядный адрес используется затем для доступа к
памяти.
16МбЪДДДДДДДДДДДДДДДДї
і і
ЪДДДДДДДДї і і
іСмещениеГДї і і
АДДДДДДДДЩ і і і
і ГДДДДДДДДДДДДДДДДґї
АДДЕДДДДД>±±±±±±±±±±іГ сегмент 64К
ЪД>ГДДДДДДДДДДДДДДДДґЩ
і і і
і і Пространство і
ЪДДДДДДДДї ЪДДДДДДї і і адресов і
іСелекторГДґ x 16 ГДДДДДЩ і і
АДДДДДДДДЩ АДДДДДДЩ і і
0АДДДДДДДДДДДДДДДДЩ
Рис. 17.1 Генерация физического адреса в реальном режиме.
Чтобы получить физический адрес в защищенном режиме, селек-
торная часть логического адреса используется в качестве индекса
таблицы дескрипторов. Запись в таблице дескрипторов содержит
24-битовый базовый адрес, к которому затем для образования физи-
ческого адреса прибавляется смещение логического адреса.
16МбЪДДДДДДДДДДДДДДДДї
і і
ЪДДДДДДДДї і і
іСмещениеГДї і і
АДДДДДДДДЩ і і і
і ГДДДДДДДДДДДДДДДДґї
Таблица дескрипторов АДДЕДДДДД>±±±±±±±±±±іГ сегмент 64К
ЪДДДДДДї ЪД>ГДДДДДДДДДДДДДДДДґЩ
ГДДДДДДґ і і і
ГДДДДДДґ і і Пространство і
ГДДДДДДґ і і адресов і
ЪД>ГДДДДДДґДДДЩ і і
і ГДДДДДДґ і і
і ГДДДДДДґ 0АДДДДДДДДДДДДДДДДЩ
і ГДДДДДДґ
і ГДДДДДДґ
і ГДДДДДДґ
і ГДДДДДДґ
і ГДДДДДДґ
і ГДДДДДДґ
і ГДДДДДДґ
і ГДДДДДДґ
ЪДДДДДДДДї і ГДДДДДДґ
іСелекторГДЩ АДДДДДДЩ
АДДДДДДДДЩ
Рис. 17.2 Генерация физического адреса в защищенном режиме.
Каждая запись в таблице дескрипторов называется дескриптором
и определяет сегмент в памяти. Запись таблицы дескрипторов зани-
мает 8 байт, а записанная в дескрипторе информация включает в се-
бя базовый адрес, предельное значение и флаги полномочий доступа
к сегменту.
Записи предельного значения сегмента и полномочий доступа в
дескрипторе определяют размер и тип сегмента. Сегменты могут
иметь размер от 1 до 65536 байт и могут быть сегментами кода или
сегментами данных. Сегменты кода могут содержать выполняемые ма-
шинные инструкции и доступные только по чтению данные. Сегменты
данных могут содержать данные, доступные по чтению и записи. За-
писывать данные в сегменты кода или выполнять инструкции в сег-
ментах данных невозможно. Любая попытка сделать это или попытка
доступа к данным вне границ сегмента вызывает общий сбой по на-
рушению защиты (сокращенно сбой GP). Поэтому режим и называется
защищенным.
По данному адресу в реальном режиме прикладная программа мо-
жет определить физический адрес. В защищенном режиме это обычно
не так, поскольку селекторная часть логического адреса является
индексом в таблице дескрипторов, и сам селектор не имеет прямого
отношения к вычислению физического адреса. Это дает то преиму-
щество, что управление виртуальной памятью можно реализовать, не
влияя на прикладную программу. Например, путем простого обновле-
ния поля базового адреса дескриптора сегмента, операционная сис-
тема может перемещать сегмент в физической памяти без влияния на
использующую сегмент прикладную программу. Прикладная программа
ссылается только на селектор сегмента, и на селектор не влияют
изменения в дескрипторе.
Прикладная программа редко имеет дело с дескрипторами. При
необходимости дескрипторы создаются и уничтожаются операционной
системой и администратором памяти, а прикладная программа знает о
соответствующих селекторах. Селекторы аналогичны описателям фай-
лов - с точки зрения прикладной программы это то, что обслужива-
ется операционной системой, но в операционной системе они работа-
ют как индексы содержащих дополнительную информацию таблиц.
Расширения Borland защищенного режима DOS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Расширения защищенного режима Borland Pascal реализованы че-
рез два компонента: DPMI-сервер (файл DPMI16BI.OVL) и администра-
тор этапа выполнения (файл RTM.EXE).
DPMI-сервер
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Интерфейс защищенного режима DOS (DPMI) - это отраслевой
стандарт, позволяющий программам DOS аппаратно-независимым путем
получить доступ к развитым средствам персональных компьютеров,
реализованных на процессорах 80286, 80386 и 80486. Определены
функции DPMI для обслуживания таблиц дескрипторов, переключения
режима, распределения расширенной памяти, выделения памяти DOS,
управления подсистемой прерываний и взаимодействия с программами
реального режима.
Расширения защищенного режима Borland Pascal основаны на
спецификации DPMI 0.9. Хотя спецификация DPMI не поддерживает вы-
зовы DOS из прикладных программ защищенного режима, DPMI-сервер
Borland и серверы многих других фирм, включая улучшенный режим
Windows 3.x, поддерживают прерывание INT 21H и другие стандартные
прерывания DOS и BIOS, используемые обычно в приложениях DOS за-
щищенного режима.
Администратор этапа выполнения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Администратор этапа выполнения (RTM.EXE) является надстрой-
кой DPMI-сервера и обеспечивать для прикладных программ защищен-
ного режима несколько служебных функций. Администратор этапа вы-
полнения содержит загрузчик защищенного режима и администратор
памяти защищенного режима и позволяет под DPMI сосуществовать
нескольким клиентам защищенного режима.
Приложения защищенного режима Borland используют те же фор-
маты выполняемых файлов, что и Windows 3.x и OS/2 1.x. Программ-
ный загрузчик администратора этапа выполнения может загружать как
выполняемые файлы (.EXE), так и динамически компонуемые библиоте-
ки (.DLL).
Администратор памяти защищенного режима позволяет прикладным
программам защищенного режима распределять блоки динамической па-
мяти. Администратор памяти поддерживает фиксированные, перемещае-
мые и выгружаемые блоки, а также обслуживает код и сегменты дан-
ных прикладной программы. Используя уникальные для защищенного
режима средства, администратор памяти функционирует также в ка-
честве администратора оверлеев, автоматически загружая и выгружая
сегменты кода (по этой причине прикладной программе защищенного
режима не требуется модуль Overlay).
Прикладные программы могут получить доступ к программам за-
щищенного режима через модуль WinAPI. Модуль WinAPI, описанный в
следующем разделе, реализует подмножество функций API (прикладно-
го программного интерфейса) Windows, обеспечивая управление па-
мятью, обслуживание программных модулей, управление ресурсами,
загрузку динамически компонуемых библиотек и доступ к селекторам
на нижнем уровне. Поскольку администратор этапа выполнения API
является подмножеством API Windows, вы можете написать совмести-
мые на уровне двоичного кода динамически компонуемые библиотеки,
которые можно использовать и в защищенном режиме DOS, и в
Windows.
Разработка прикладных программ DOS защищенного режима
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Написание прикладной программы защищенного режима не предс-
тавляет собой сложной задачи. Вам не нужно беспокоиться о селек-
торах и адресах памяти. Операционная система с расширениями
Borland все делает за вас. Фактически, большинство ваших программ
реального режима может прекрасно работать в защищенном режиме. В
следующих разделах описывается некоторая разница между реальным и
защищенным режимом, о которых вы должны знать при разработке
прикладной программы защищенного режима.
Надежное программирование в защищенном режиме
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Существует несколько приемов, используемых обычно в програм-
мах реального режима, которые в программах защищенного режима бу-
дут приводить к общему нарушению защиты (сбой GP). Borland Pascal
при сбое GP выводит ошибку этапа выполнения 216. Сбой GP происхо-
дит, когда вы пытаетесь получить доступ к памяти, к которой ваша
прикладная программа обращаться не может. Операционная система
останавливает прикладную программу, но сбоя системы не происхо-
дит. Хотя сбои GP и прекращают работу вашей программы, система
"защищена" от сбоя. К сбою GP приводит следующее:
* загрузка в сегментные регистры недопустимых значений;
* обращение к памяти вне границы сегмента;
* запись в сегмент кода;
* разыменование указателей nil.
Примечание: Сбои по нарушению защиты предохраняют вашу
систему от плохой практики программирования.
Загрузка в сегментные
регистры недопустимых значений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда процессор работает в защищенном режиме, сегментные ре-
гистры (CS, DS, ES и SS) могут содержать только селекторы. Пос-
кольку селекторы являются индексами в таблице дескрипторов, они
не имеют физического отношения к памяти, на которую ссылается.
Если вы пытаетесь загрузить в сегментный регистр произвольное
значение, то возможно получите сбой GP, поскольку это значение
может не представлять допустимого дескриптора.
Функция Ptr и массивы Mem
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При разыменовании указателей компилятор генерирует код для
загрузки сегментного регистра. Если вы строите указатели с по-
мощью стандартной функции Ptr, то нужно обеспечить, чтобы сег-
ментная часть указателя была допустимым селектором. Аналогично,
при работе с массивами Mem, MemW и MemL вы вместо физических ад-
ресов должны использоваться селекторы. Например, при доступе к
рабочей области ROM BIOS (сегмент $0040) или к областям видеопа-
мяти (сегменты $A000, $B000 и $B800) следует использовать вместо
абсолютных значений переменные SegXXXX. (Переменные SegXXXX опи-
сываются ниже.)
Абсолютные переменные
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В защищенном режиме вы не можете задавать абсолютный адрес
переменной. Любой исходных код, где сегмент и смещение задаются в
операторе absolute, нужно переписать. Например, вам может потре-
боваться построить указатель, используя переменные SegXXXX.
Операции с сегментами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Добавление или вычитание значений из селекторной части ука-
зателя обычно не допускается. Например, добавление к селекторной
части указателя $1000 в реальном режиме увеличивает указатель на
64К, но в защищенном режиме результирующий указатель будет недо-
пустимым. Вместо этого для выделения и управления блоками памяти
следует использовать функцию GlobalXXXX модуля WinAPI.
В Borland Pascal существует способ выполнения арифметических
операций с селекторами с помощью переменной SelectorInc (см. ни-
же).
Использование сегментных
регистров в качестве временных переменных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В реальном режиме некоторые старые программы на ассемблере
используют сегментные регистры для хранения временных переменных.
В защищенном режиме это работать не будет, так как обычно сохра-
няемые в сегментных регистрах временные значения не являются до-
пустимыми селекторами.
Доступ к памяти вне границ сегмента
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В реальном режиме каждый сегмент имеет размер 64К. В защи-
щенном режиме дескриптор сегмента содержит поле, специфицирующее
предельный размер сегмента, и если вы пытаетесь обратиться к дан-
ным вне границ сегмента, по получите сбой GP. При загрузке прик-
ладной программы администратор этапа выполнения устанавливает со-
ответствующие предельные значения для сегментов кода, данных и
стека. Кроме того, блок памяти, распределяемый с помощью функции
GlobalAlloc модуля WinAPI, имеет предельное значение сегмента,
соответствующее размеру блока памяти.
Запись в сегмент кода
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В реальном режиме можно записывать переменные в сегмент ко-
да, поскольку реальные режим не определяет, что может и что не
может существовать в сегменте. В защищенном режиме это не так.
Селектор защищенного режима имеет флаг чтения/записи или доступа
только по чтению, а селекторы кода всегда отмечены как доступные
только по чтению. Если вы пытаетесь записывать в селектор сегмен-
та кода, происходит сбой GP. Однако вы можете использовать псев-
доним и написать самомодифицирующийся код (см. ниже).
Разыменование указателей nil
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При преобразовании прикладной программы реального режима в
защищенный режим, в программе, которая уже годы работала без оши-
бок, возможно внезапное появление определенных ошибок. Например,
вы можете случайно разыменовывать указатель nil, или обнаружите,
что ваша программа содержит "потерянные" указатели, которые разы-
меновываются после их освобождения. В реальном режиме такие ошиб-
ки не обязательно проявляются, но в защищенном режиме они обычно
приводят к сбою GP. Согласно своему названию, защищенный режим
значительно лучше предохраняет вас от ошибок, связанных с указа-
телями.
Сегменты кода и данных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Аналогично программе Borland Pascal реального режима, прог-
рамма защищенного режима содержит несколько сегментов кода, сег-
мент данных и сегмент стека. При загрузке программы защищенного
режима администратор этапа выполнения автоматически выделяет се-
лекторы для сегментов кода, данных и стека. Для сегментов кода
с помощью директивы компилятора $C можно управлять отдельными ат-
рибутами. В частности, сегменты кода можно сделать перемещаемыми
или фиксированными в физической памяти, они могут загружаться
предварительно или по запросу, а также могут быть выгружаемыми
или постоянными.
Примечание: Подробнее о директиве компилятора $C расс-
казывается в Главе 21 данного руководства и в Главе 2 ("Ди-
рективы компилятора") "Справочного руководства программис-
та".
Атрибуты сегмента кода позволяют вам обозначать сегмент как
статический (перемещаемый, предварительно загружаемый, постоян-
ный) или динамический (перемещаемый, загружаемый по запросу, выг-
ружаемый). Таким образом, в защищенном режиме вам не нужно ис-
пользовать модуль Overlay и директиву компилятора $O, и в версии
модуля System для защищенного режима переменные OvrXXXXXX отсутс-
твуют.
Управление динамически распределяемой памятью
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Администратор динамически распределяемой области памяти
Borland Pascal защищенного режима довольно существенно отличается
от администратора динамически распределяемой памяти Borland
Pascal реального режима. В частности, переменные HeapOrg,
HeapEnd, HeapPtr и FreeList в версии модуля System для защищенно-
го режима не определены. Администратор этапа выполнения динами-
чески распределяемой области памяти Borland Pascal защищенного
режима (который идентичен администратору этапа выполнения динами-
чески распределяемой области памяти Borland Pascal для Windows)
для выполнения основных операций по выделению и освобождению па-
мяти использует администратор этапа выполнения, а для оптимизации
распределения небольших блоков памяти включает в себя подсистему
вторичного распределения сегмента. Подробнее об администраторе
динамически распределяемой области памяти этапа выполнения расс-
казывается в Главе 21.
Предопределенные селекторы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В модуле System для обычно используемых адресов реального
режима предусмотрено несколько предопределенных селекторов. Они
именуются по физическому сегменту, которому данные селекторы
присвоены, и используются для совместимости между реальным и за-
щищенным режимом DOS.
Предопределенные селекторы Таблица 17.1
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Селектор і Описание і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Seg0040 і Используется для доступа к области данныхі
і і BIOS $40 в младших адресах. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SegA000 і Используется для доступа к графической па-і
і і мяти EGA и VGA по адресу сегмента $A000. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SegB000 і Используется для доступа к видеопамяти мо-і
і і нохромного адаптера по адресу сегментаі
і і $A000. і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SegB800 і Используется для доступа к видеопамятиі
і і цветного графического адаптера по адресуі
і і сегмента $A000. і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
В реальном режиме переменные SegXXXX всегда содержат значе-
ния $0040, $A000, $B000 и $B800 соответственно. В защищенном ре-
жиме код запуска библиотеки исполняющей системы создает четыре
селектора, ссылающихся на конкретные области памяти реального ре-
жима. При ссылке на эти области памяти вам следует использовать
переменные SegXXXX. Например, если у вас был код следующего вида:
CtrMode := Mem[$40: $49];
то вместо него следует записать:
CtrMode := Mem[Seg0040: $49];
Используя переменные SegXXXX, вы можете гарантировать, что
ваша программа без изменений будет работать в реальном и защищен-
ном режимах.
Переменная SelectorInc
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Переменная SelectorInc модуля System содержит значение, ко-
торое должно прибавляться к селектору или вычитаться из него для
получения следующего или предыдущего селектора в таблице дескрип-
торов. SelectorInc полезно использовать при работе с большими
блоками памяти (превышающими 64К) и при доступе к псевдонимам
сегментов.
Для выделения блоков, превышающих 64К (такие блоки называют
также большими блоками памяти), можно использовать функции
GlobalAlloc и GlobalAllocPrt в модуле WinAPI. Большие блоки неп-
рерывны в физической памяти, но из-за 16-разрядной архитектуры
процессора прикладная программа не может получить к ним доступ
целиком. Для большого блока памяти администратор памяти выделяет
несколько непрерывных (следующих подряд) селекторов, каждый из
которых (кроме последнего) ссылается на часть большого блока па-
мяти размером 64К. Например, чтобы выделить блока памяти размером
в 220К, администратор памяти создает четыре селектора, при этом
первые три селектора ссылаются на блоки по 64К, а последний се-
лектор - на блок размером 28К. Прибавляя SelectorInc к селектору,
принадлежащему большому блоку, вы можете получить селектор для
следующего сегмента, а вычитая SelectorInc - для предыдущего.
При распределении большого блока функция GlobalAlloc всегда
возвращает описатель первого сегмента, а GlobalAllocPtr - указа-
тель на первый сегмент.
Приведенная ниже функция GetPtr воспринимает указатель боль-
шого блока (возвращаемый функцией GlobalAllocPtr) и 32-разрядное
смещение и возвращает указатель на заданное внутри блока смеще-
ние.
function GetPtr(P: Pointer; Offset: Longint): Pointer;
type
Long = record
Lo, Hi: Word;
end;
begin
GetPtr := Ptr(
Long(P).Hi + Long(Offset).Hi * SelectorInc,
Long(P).Lo + Long(Offset).Lo);
end;
Заметим, что старшее слово параметра Offset используется для
определения того, сколько раз нужно увеличить селекторную часть P
для получения корректного сегмента. Например, если Offset равно
$24000, то селекторная часть P будет увеличена на 2 *
SelectorInc, а смещение P - на $4000.
Следующая функция LoadFile загружает в блок памяти весь файл
и возвращает указатель на блок. Если файл превышает 64К, то выде-
ляется большой блок памяти.
function LoadFile(const FileName: string): Pointer;
var
Buffer: Pointer;
Size, Offset, Count: Longint;
F: file;
begin
Buffer := nil;
Assign(F, FileName);
Reset(F, 1);
Size := FileSize(F);
Buffer := GlobalAllocPtr(gmem_Moveable, Size);
if Buffer <> nil then
begin
Offset := 0;
while Offset < Size do
begin
Count := Size - Offset;
if Count > $8000 then Count := $8000;
BlockRead(F, GetPtr(Buffer, Offset)^, Count);
Inc(Offset, Count);
end;
end;
LoadFile := Buffer;
end;
Переменная SelectorInc определена также в версии модуля
System для реального режима. В реальном режиме она всегда содер-
жит значение $1000, которое при сложении его с сегментной частью
указателя реального режима увеличивает указатель на 64К.
Другим образом вы можете использовать переменную SelectorInс
только в программах DOS защищенного режима. Используйте перемен-
ную SelectorInc для доступа к псевдонимам сегментов, выделяемых
администратором этапа выполнения при загрузке прикладной програм-
мы. Для каждого сегмента кода прикладной программы администратор
этапа выполнения создает селектор-псевдоним, ссылающийся на тот
же сегмент, но имеющий полномочия селектора данных. Для сегментов
стека и данных селекторы-псевдонимы не создаются.
Чтобы получить доступ к селектору-псевдониму для конкретного
сегмента, добавьте к селектору сегмента SelectorInc. Предположим,
например, что P - это переменная типа Pointer, а Foo - процедура
или функция. Тогда присваивание вида:
P := Addr(Foo)
приводит к тому, что P будет указывать на выполняемую доступную
только по чтению точку входа Foo, а после оператора:
P := Ptr(Seg(Foo) + SelectorInc, Ofs(Foo));
P будет ссылаться на тот же адрес, но с полномочиями на чте-
ние/запись.
Модуль WinAPI
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Модуль WinAPI дает вам непосредственный доступ к расширениям
Borland защищенного режима DOS. Чтобы облегчить написание перено-
симых прикладных программ и совместимых на уровне двоичного кода
DLL, разработан интерфейс WinAPI, являющийся подмножеством интер-
фейса API Windows.
Модуль WinAPI позволяет вам использовать функции управления
памятью, управления ресурсами, модулями, селекторами и многие
другие функции API. Ниже приведено их краткое описание. Полное
описание констант, типов, процедур и функций модуля WinAPI вы мо-
жете найти в "Справочном руководстве программиста".
При работе под Windows подпрограммы API, поддерживаемые с
помощью модуля WinAPI, находятся в динамически компонуемых библи-
отеках KERNEL.DLL и USER.DLL. В защищенном режиме DOS эти DLL не
требуются, так как администратор этапа выполнения защищенного ре-
жима содержит реализацию подпрограмм KERNEL и USER, автоматичес-
ки перенаправляя их вызовы администратору.
Управление памятью
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При разработке программ, работающих с динамической памятью,
обычно используются стандартные процедуры New, Dispose, GetMem и
FreeMem. Однако получить доступ к администратору памяти защищен-
ного режима Borland вы можете с помощью функций GlobalXXXX в мо-
дуле WinAPI.
Заметим, что функции GlobalXXXXPtr комбинируют в одной подп-
рограмме общие последовательности вызовов функций, такие как
GlobalAlloc, за которыми следуют вызовы GlobalLock, GlobalUnlock
или GlobalFree.
Подпрограммы управления памятью API
Таблица 17.2
ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetFreeSpace і Определяет объем свободной памяти в ди-і
і і намически распределяемой области. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalAlloc і Выделяет блок памяти в динамически расп-і
і і ределяемой области. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalAllocPtr і Выделяет и блокирует блок памяти (с по-і
і і мощью вызовов GlobalAlloc и GlobalLock).і
і і і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalCompact і Переупорядочивает память, распределен-і
і і ную в динамической области, так что ос-і
і і вобождается заданный объем памяти. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalDiscard і Выгружает заданный объект памяти. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalDosAlloc і Распределяет память, к которой можно по-і
і і лучить доступ в реальном режиме DOS. Этаі
і і память будет существовать в первом мега-і
і і байте линейного адресного пространства. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalDosFree і Освобождает память, выделенную ранее сі
і і помощью GlobalDosAlloc. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalFlags і Получает информацию о блоке памяти. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalFree і Освобождает разблокированный блок памятиі
і і и делает его описатель недействительным.і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalFreePtr і Разблокирует и освобождает блок памятиі
і і с помощью GlobalUnlock и GlobalFree. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalHandle і Получает описатель объекта в памяти поі
і і заданному адресу сегмента. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalLock і Увеличивает счетчик ссылки блока памятиі
і і и возвращает указатель на него. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalLockPtr і То же, что и GlobalLock, но вместо опи-і
і і сателя воспринимает указатель. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalLRUNewest і Перемещает объект в памяти на новую не-і
і і давно используемую позицию, минимизируя,і
і і таким образом, вероятность выгрузкиі
і і объекта. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalLRUOldest і Перемещает объект в памяти на самуюі
і і "старую" недавно используемую позицию,і
і і максимизирую вероятность выгрузки объ-і
і і екта. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalNorify і Вызывает адрес экземпляра процедуры уве-і
і і домления, передавая описатель блока, ко-і
і і торый нужно выгрузить. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalPageLock і Увеличивает значение счетчика блокиров-і
і і ки для памяти, связанной с данным селек-і
і і тором. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalPageUnlock і Уменьшает значение счетчика блокировкиі
і і для памяти, связанной с данным селекто-і
і і ром. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalPtrHandle і По заданному указателю на блок памятиі
і і возвращает описатель этого блока. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalReAlloc і Перераспределяет блок памяти. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalReAllocPtr і Разблокирует, перераспределяет и блоки-і
і і рует блок памяти (используя функцииі
і і GlobalUnlock, GlobalReAlloc иі
і і GlobalLock). і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalSize і Определяет текущий размер блока памяти. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalUnfix і Разблокирует блок памяти, блокированныйі
і і ранее с помощью GlobalLock. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GlobalUnockPtr і То же, что и GlobalUnlock, но вместоі
і і описателя воспринимает указатель. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LockSegment і Блокирует заданный выгружаемый сегмент. і
ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і UnlockSegment і Разблокирует сегмент. і
АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Функция GlobalAlloc используется для распределения блоков
памяти. Для их освобождения применяется функция GlobalFree. Адми-
нистратор памяти поддерживает три типа блоков памяти: фиксирован-
ный, перемещаемый и выгружаемый. Фиксированный блок остается в
одних и тех же адресах физической памяти. Перемещаемый блок может
перемещаться в физической памяти и освобождать место для других
запросов на выделение памяти, а выгружаемые блоки могут выгру-
жаться из памяти, освобождая место для других блоков. С помощью
передаваемых GlobalAlloc флагов вы можете выбрать один из этих
трех типов:
* gmem_Fixed (фиксированный)
* gmem_Moveable (перемещаемый)
* gmem_Moveable + gmem_Discardable (выгружаемый)
Прикладная программа обычно выделяет только перемещаемые
блоки памяти, которые представляются типом THandle в модуле
WinAPI. Описатель памяти - это значение размером в слово, которое
идентифицирует блок памяти аналогично тому, как описатель файла -
это значение размером в слово, идентифицирующее открытый файл.
Перед тем как вы сможете получить доступ к памяти, его нужно
заблокировать с помощью функции GlobalAlloc, а когда вы закончите
к нему обращаться, его нужно разблокировать с помощью функции
GlobalUnlock. GlobalLock возвращает полный 32-разрядный указатель
на первый байт блока. Смещение указателя всегда равно 0. В защи-
щенном режиме DOS селектор указателя - это тоже самое, что описа-
тель блока, но в Windows это не всегда так.
Правильная последовательность вызовов для выделения, блоки-
ровки, разблокировки или освобождения блока показана в приведен-
ном ниже примере. В данном примере H - это переменная типа
THandle, а P - указатель:
H := GlobalAlloc(gmem_Moveable, 8192); { выделение блока }
if H <> then { если память выделена }
begin
P := GlobalLock(H); { блокировка блока }
.
. { доступ к блоку через P }
.
GlobalUnlock(H); { разблокировать блок }
GlobalFree(H); { освободить блок }
end;
Блокировка и разблокировка блока при каждом обращении к нему
достаточно утомительна и ведет к ошибкам, и реально она необходи-
ма только для выгружаемых блоков и в прикладных программах
Windows, работающих в реальном режиме. Во всех других ситуациях
лучшим решением является блокировка блока сразу после его выделе-
ния и сохранение этого состояния до освобождения блока. С этой
целью модуль WinAPI включает в себя семейство подпрограмм-"оболо-
чек" GlobalXXXXPtr. Особый интерес представляет функция
GlobalAllocPtr, которая выделяет и блокирует блок памяти, и функ-
ция GlobalFreePtr, разблокирующая и освобождающая блок памяти. С
помощью этих подпрограмм приведенный выше пример можно упростить:
H := GlobalAlloc(gmem_Moveable, 8192); { выделение блока }
if H <> then { если память выделена }
begin
.
. { доступ к блоку }
.
GlobalFreePtr(P); { освободить блок }
end;
Вызвав функцию GlobalReAlloc, вы можете изменить размер или
атрибуты блока памяти, сохранив его содержимое. Функция
GlobalReAlloc возвращает новый описатель блока, который может от-
личаться от передаваемого функции описателя, если старый размер
или новый размер блок превышает 64К. Заметим, что в тех случаях,
когда старый размер блока и новый его размер меньше 64К,
GlobalReAlloc всегда может изменить размер блока, не изменяя его
описателя.
Функция GlobalReAlloc можно также использоваться для измене-
ния атрибутов блока. Это можно сделать, задав наряду с
gmem_Moveable или gmem_Discardable флаг gmem_Modify.
Функция GlobalReAlloc выполняет те же действия, что и
GlobalReAlloc, но обе они вместо описателей использует указатели.
Имеется также ряд других, менее часто используемых
GlobalXXXX. Все они подробно описаны в Главе 1 ("Справочник по
библиотеке") "Справочного руководства программиста".
Управление модулем
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Администратор этапа выполнения поддерживает следующие подп-
рограммы обслуживания модулей:
Подпрограммы API обслуживания модулей Таблица 17.3
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Подпрограмма і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FreeLibrary і Делает недействительным загружен-і
і і ный модуль библиотеки, и освобож-і
і і дает соответствующую память, еслиі
і і ссылок на модуль больше нет. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetModuleFileName і Дает полный маршрут и имя выполня-і
і і емого файла, задающий, откуда заг-і
і і ружен модуль. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetModuleHandle і Определяет описатель заданного мо-і
і і дуля. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetModuleUsage і Определяет счетчик ссылок на мо-і
і і дуль. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetProcAddress і Определяет адрес экспортируемойі
і і библиотечной функции. і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LoadLibrary і Загружает указанный библиотечныйі
і і модуль. і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Некоторые из этих подпрограмм воспринимают в качестве пара-
метра описатель модуля. Описатель модуля самой прикладной прог-
раммы хранится в переменной HInstance, описанной в модуле System.
Управление ресурсами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Администратор этапа выполнения поддерживает следующие подп-
рограммы управления ресурсами:
Функции API управления ресурсами Таблица 17.4
ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AccessResource і Открывает заданный выполняемый файл иі
і і перемещает указатель файла на началоі
і і заданного ресурса. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FindResource і Определяет адрес ресурса в заданномі
і і файле ресурса. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FreeResource і Уменьшает счетчик ссылок для загружен-і
і і ного ресурса. Когда значение этогоі
і і счетчика становится равным нулю, то ис-і
і і пользуемая ресурсом память освобождает-і
і і ся. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LoadResource і Загружает заданный ресурс в память. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LoadString і Загружает заданную строку ресурса. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і LockResource і Блокирует заданный ресурс в памяти иі
і і увеличивает его счетчик ссылок. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SizeOfResource і Возвращает размер (в байтах) заданногоі
і і ресурса. і
ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і UnlockResource і Разблокирует заданный ресурс и уменьша-і
і і ет на 1 счетчик ссылок на ресурс. і
АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Ресурсы могут компоноваться с прикладной программой с по-
мощью директив компилятора {$R имя_файла}. Указанные файлы должны
быть файлами ресурсов Windows (.RES). Обычно с прикладными прог-
раммами защищенного режима DOS компонуются только строковые ре-
сурсы и ресурсы, определенные пользователем. Другие типы ресурсов
Windows к прикладной программе DOS обычно неприменимы.
Примечание: Ресурсы Turbo Vision не следуют тем же
соглашениям, что ресурсы Windows, и к ним нельзя обращаться
с помощью подпрограмм API.
Некоторые подпрограммы API управления ресурсами требуют ука-
зания описателя экземпляра, которым обычно является указатель эк-
земпляра прикладной программы (который содержится в переменной
HInstance модуля System).
Управление селектором
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Прикладной программе обычно не требуется манипулировать се-
лекторами, но в отдельных ситуациях полезно использовать следую-
щие подпрограммы обслуживания селектора:
Подпрограммы API управления селектором Таблица 17.5
ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AllocDStoCSAlias і Отображает селектор сегмента данных наі
і і селектор сегмента кода. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і AllocSelector і Выделяет новый селектор. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і ChangeSelector і Генерирует селектор кода, соответству-і
і і щий заданному селектору данных, илиі
і і генерирует заданный селектор, соот-і
і і ветствующий селектору кода. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FreeSelector і Освобождает селектор, первоначальноі
і і выделенный функциями AllocDStoCSAliasі
і і или AllocSelector. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetSelectorBase і Дает базовый адрес селектора. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetSelectorLimit і Возвращает предельное значение для за-і
і і данного селектора. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і PrestoChangoSelectorі Генерирует селектор кода, соответству-і
і і ющий заданному селектору данных, либоі
і і генерирует селектор данных, соответс-і
і і твующий селектору кода. і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetSelectorBase і Устанавливает базовый адрес селектора.і
ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і SetSelectorLomit і Устанавливает предельное значение се-і
і і лектора. і
АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Другие подпрограммы API
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Администратор этапа выполнения поддерживает следующие допол-
нительные подпрограммы API:
Прочие подпрограммы API Таблица 17.6
ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і DOS3Call і Вызывает функцию прерывания DOS 21h; вызы-і
і і вается только из подпрограмм ассемблера. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і FatalExit і Передает отладчику текущее состояние опе-і
і і рационной среды защищенного режима и вы-і
і і выводит подсказку для ввода инструкций оі
і і продолжении работы. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetDOSEnviromentі Определяет текущую строку операционнойі
і і среды задачи. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetVersion і Дает текущую версию операционной средыі
і і Windows или операционной системы DOS. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і GetWinFlags і Дает используемые Windows флаги конфигура-і
і і ции памяти. і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і MessageBox і Создает, выводит на экран и обслуживаеті
і і окно сообщений. і
АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Совместно используемая DLL, чтобы определить, выполняется ли
она в защищенном режиме DOS или под Windows, может использовать
функцию GetWinFlags, например:
if GetWinFlags and wf_DPMI <> 0 then
Message('Работа в защищенном режиме DOS')
else
Message('Работа в среде Windows');
Прямой доступ к DPMI-серверу
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Прямой доступ к DPMI-серверу вы можете получить через преры-
вание $31, которое непосредственно вызывает DPMI-сервер в обход
администратора этапа выполнения. Однако это опасный прием. DPMI
не поддерживает очистку ресурсов, таких как векторы прерываний
памяти; корректно с этими проблемами работает администратор этапа
выполнения. Вы должны глубоко понимать концепции защищенного ре-
жима и знать о существенном риске, с которым связано использова-
ние данного метода доступа защищенного режима.
Компиляция прикладной программы защищенного режима
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В большинстве случаев для получения прикладной программы за-
щищенного режима вам не нужно делать ничего особенного. Просто
скомпилируйте свою программу, задав в качестве целевой работы за-
щищенный режим одним из следующих способов:
* В IDE выберите команду CompileіTarget и в диалоговом окне
Target Platform (Целевая платформа) выберите
Protected-mode Application.
* При использовании компилятора, работающего в режиме ко-
мандной строки, укажите для выбора в качестве целевой
платформы защищенного режима параметр /CP.
Выполнение программы защищенного режима DOS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда вы выполняете программу DOS защищенного режима, нужно
обеспечить наличие в текущем каталоге или по маршруту DOS файлов
DPMI16BI.OVL (сервер DPMI), RTM.EXE (администратор этапа выполне-
ния) и всех DLL, с которыми работает ваша программа.
Примечание: Лицензионное соглашение позволяет вам
распространять файлы DPMI16BI.OVL и RTM.EXE вместе с вашей
программой.
В выполняемом файле .EXE защищенного режима DOS используется
тот же формат файла, что и в Windows 3.x и OS/2 1.x. Этот формат
файла является надмножеством обычного формата .EXE DOS и состоит
из обычного образа файла .EXE, называемого фиктивным модулем, за
которым следует расширенный заголовок и код, данные и ресурсы за-
щищенного режима. Ниже показана последовательность событий при
выполнении программы защищенного режима DOS.
1. DOS загружает фиктивный модуль реального режима и переда-
ет ему управление.
2. Если средства DPMI отсутствуют, то фиктивный модуль заг-
ружает DPMI-сервер из файла DPMI16BI.OVL. Некоторые новые
администраторы памяти поддерживают средства DPMI (как,
например, это делается в окне DOS улучшенного режима
Windows 3.х). В таких конфигурациях фиктивный модуль не
загружает DPMI-сервер, но использует уже имеющийся.
3. Далее, если администратор этапа выполнения еще не загру-
жен в память, фиктивный модуль загружает его из файла
RTM.EXE. Если прикладная программа защищенного режима вы-
полняет другую программу защищенного режима, обе исполь-
зуют одну копию администратора этапа выполнения.
4. Если средства DPMI и администратор этапа выполнения при-
сутствуют, фиктивный модуль переключается из реального в
защищенный режим и передает управление расширенному заг-
рузчику .EXE в администратора этапа выполнения.
5. Загрузчик сначала загружает используемую прикладной прог-
раммой DLL (если она имеется), затем загружает сегменты
кода и данных прикладной программы. Наконец, загрузчик
передает управление на точку входа прикладной программы.
При выполнении вашей прикладной программы защищенного режима
DOS всегда возможно ситуация, когда уже присутствует DMPI-сервер,
отличный от сервера Borland. Поскольку между серверами могут быть
небольшие различия, особенно в плане обработки прерываний DOS, вы
должны проверить программу и убедиться, что она работает со всеми
возможными серверами, которые могут ей встретиться.
Когда прикладная программа защищенного режима DOS выполняет-
ся в окне DOS улучшенного режима Windows, вы можете управлять
объемом расширенной памяти, которую выделяет администратор этапа
выполнения, задав в файле .PIF прикладной программы предельное
значение памяти XMS.
Управление объемом используемой RTM памяти
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
По умолчанию администратор этапа выполнения использует при
загрузке всю доступную память. Затем по запросам он выделяет па-
мять своим клиентам (через подпрограммы API администратора памя-
ти).
В защищенном режиме нет разницы между обычной памятью (ниже
1 мегабайта) и расширенной памятью (с адресами выше 1 мегабайта);
для программ защищенного режима доступны оба типа памяти. Однако
администратор этапа выполнение отдает предпочтение расширенной
памяти. Только после того как вся расширенная память будет выде-
лена, или когда прикладная программа специально запрашивает
обычную память (например, с помощью функции GlobalDosAlloc), ад-
министратор этапа выполнения выделяет обычную память.
Причина, по которой администратор этапа выполнения предпочи-
тает расширенную память, заключается в том, что прикладная прог-
рамма может с помощью вызова подпрограммы Exec в модуле Dos по-
рождать другие прикладные программы. Порожденные прикладные прог-
раммы не обязательно являются программами защищенного режима; та-
ким образом, им может потребоваться обычная память. Фактически,
порожденные программы защищенного режима запускаются как програм-
мы реального режима и переключаются в защищенный режим только
после успешной загрузки фиктивным модулем средств DPMI и адми-
нистратора этапа выполнения.
Администратор этапа выполнения перед порождением прикладной
программы пытается освободить максимальный объем обычной памяти
(например, перенеся перемещаемые блоки в расширенную память). Од-
нако попытки освобождения расширенной памяти не предпринимаются.
Таким образом, если должны порождаться прикладные программы защи-
щенного режима, не использующие администратор этапа выполнения,
то необходим споcоб управления распределением памяти администра-
тором этапа выполнения.
Чтобы управлять тем, сколько памяти может использовать адми-
нистратор этапа выполнения, в командной строке DOS добавьте к
строке операционной среды DOS переменную среды RTM:
SET RTM={параметр nnnn}
Возможные параметры перечислены в следующей таблице. Значе-
ние nnnn может быть десятичным или шестнадцатиричным числом в ви-
де xAB54 или xab54.
Параметры переменной операционной
среды RTM, используемые для управления памятью Таблица 17.7
ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Параметр і Описание і
ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і EXTLEAVE nnnn і Всегда оставляет не менее nnnn килобайті
і і доступной расширенной памяти. По умолча-і
і і нию это значение равно 640К. і
ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і EXTMAX nnnn і Не выделяет более nnnn килобайт расширен-і
і і ной памяти. По умолчанию используетсяі
і і значение 4 гигабайта. В Windows использу-і
і і емое по умолчанию значение равно половинеі
і і доступной памяти. і
ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і EXTMIN nnnn і Если после применения EXTMAX или EXTLEAVEі
і і доступно менее nnnn килобайт, то програм-і
і і ма завершается с сообщением о нехваткеі
і і памяти (Out of memory). По умолчанию этоі
і і значение равно 0. і
ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і REALLEAVE nnnn і Всегда оставляет не менее nnnn параграфові
і і доступной реальной памяти. По умолчаниюі
і і это значение равно 64К или 4096 парагра-і
і і фов. і
ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і REALMAX nnnn і Не выделяет более nnnn параграфов реаль-і
і і ной памяти. По умолчанию это значениеі
і і равно 1 мегабайту или 65535 параграфов. і
ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і REALMIN nnnn і Если после применения REALMAX и REALLEAVEі
і і доступно менее nnnn параграфов, то прог-і
і і рамма завершается с сообщением о нехваткеі
і і памяти (Out of memory). По умолчанию этоі
і і значение равно 0. і
АДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Следующая команда DOS ограничивает RTM 2 мегабайтами расши-
ренной памяти и обеспечивает, что нераспределенными останутся
128К реальной памяти.
SET RTM=EXTMAX 2048 REALLEAVE 8192
Глава 18. Строки с завершающим нулем
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В Borland Pascal поддерживается класс символьных строк, ко-
торые называются строками, завершающимися нулем. Благодаря расши-
ренному синтаксису Borland Pascal и модулю Strings ваши программы
(как для DOS, так и для Windows) могут использовать строки с за-
вершающим нулем путем задания в операторе uses модуля Strings.
Что такое строка с завершающим нулем?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В Borland Pascal строки обычного типа (String) хранятся как
байт длины, за которым следует последовательность символов. Мак-
симальная длина строки в Паскале равна 255 символам. Таким обра-
зом, строка Паскаля занимает от 1 до 256 байт памяти.
Строки с завершающим нулем не содержат байта длины. Вместо
этого они состоят из последовательности ненулевых символов, за
которыми следует символ NULL (#0). Никаких ограничений на длину
строк с завершающим нулем не накладывается, но 16-разрядная архи-
тектура DOS и Windows ограничивает их размер 65535 символами.
Функции модуля Strings
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Borland Pascal не имеет встроенных подпрограмм, предназна-
ченных специально для работы со строками с завершающим нулем. Эти
функции вы можете найти в модуле Strings. Среди них вы найдете
функцию StrPCopy, которую можно использовать для копирования
строки Паскаля в строку с завершающим нулем, и StrPos, используе-
мую для преобразования строки с завершающим нулем в строку Паска-
ля. Приведем краткое описание каждой функции:
Функции модуля Strings
ЪДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Функция і Описание і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrCat і Добавляет исходную строку к концу целевой стро-і
і і ки и возвращает указатель на целевую строку. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrComp і Сравнивает две строки S1 и S2. Возвращаеті
і і значение < 0, если S1 < S2, равное 0, если S1 =і
і і S2 и > 0, если S1 > S2. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrCopy і Копирует исходную строку в целевую строку иі
і і возвращает указатель на целевую строку. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrECopy і Копирует исходную строку в целевую строку иі
і і возвращает указатель на конец целевой строки. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrIComp і Сравнивает две строки без различия регистраі
і і символов. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrLCat і Присоединяет исходную строку к концу целевойі
і і строки. При этом обеспечивается, что длина ре-і
і і зультирующей строки не превышает заданного мак-і
і і симума. Возвращается указатель на строку-ре-і
і і зультат. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrLComp і Сравнивает две строки с заданной максимальнойі
і і длиной. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrLCopy і Копирует заданное число символов из исходнойі
і і строки в целевую строку и возвращает указательі
і і на целевую строку. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrEnd і Возвращает указатель на конец строки, то естьі
і і указатель на завершающий строку нулевой символ.і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrDispose і Уничтожает ранее выделенную строку. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrLen і Возвращает длину строки. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrLIComp і Сравнивает две строки с заданной максимальнойі
і і длиной без различия регистра символов. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrLower і Преобразует строку в нижний регистр и возвраща-і
і і ет указатель на нее. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrMove і Перемещает блок символов из исходной строки ві
і і целевую строку и возвращает указатель на целе-і
і і вую строку. Два блока могут перекрываться. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrNew і Выделяет для строки память в динамически рас-і
і і пределяемой области. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrPas і Преобразует строку с завершающим нулем в строкуі
і і Паскаля. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrPCopy і Копирует строку Паскаля в строку с завершающимі
і і нулем и возвращает указатель на строку с завер-і
і і шающим нулем. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrPos і Возвращает указатель на первое вхождение задан-і
і і ной подстроки в строке, или nil, если подстрокаі
і і в строке не содержится. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrRScan і Возвращает указатель на последнее вхождениеі
і і указанного символа в строку, или nil, если сим-і
і і вол в строке отсутствует. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrScan і Возвращает указатель на первое вхождение ука-і
і і занного символа в строку, или nil, если символі
і і в строке отсутствует. і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і StrUpper і Преобразует строку в верхний регистр и возвра-і
і і щает указатель на нее. і
АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Использование строк с завершающим нулем
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Строки с завершающим нулем хранятся в виде символьных масси-
вов с нулевой базой (начинающихся с 0) с индексом целого типа, то
есть в виде массива:
array[0..X] of Char;
где X - положительное ненулевое целое число. Такие массивы назы-
ваются символьными массивами с нулевой базой. Приведем некоторые
примеры описаний символьных массивов с нулевой базой, которые мо-
гут использоваться для хранения завершающихся нулем строк.
type
TIdentifier = array[0..15] of Char;
TFileName = array[0..79] of Char;
TMemoText = array[0..1023] of Char;
Более всего строки Паскаля и строки с завершающим нулем от-
личаются интенсивностью использования указателей. Borland Pascal
выполняет операции с этими указателями, используя набор правил
расширенного синтаксиса. Кроме того, в Borland Pascal имеется
встроенный тип PChar, который представляет собой указатель на
строку с завершающим нулем. В модуле System тип PChar определяет-
ся следующим образом:
type PChar = ^Char;
Правилами расширенного синтаксиса управляет директива компи-
лятора $X. В состоянии {$X+} (по умолчанию) расширенный синтаксис
разрешен. Правила расширенного синтаксиса описываются в следующих
разделах.
Символьные указатели и строковые литералы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При разрешении расширенного синтаксиса строковый литерал
совместим по присваиванию с типом PChar. Это означает, что пере-
менной типа PChar можно присвоить строковый литерал. Например:
var
P: PChar;
.
.
begin
P := 'Привет...';
end;
В результате такого присваивания указатель указывает на об-
ласть памяти, содержащую строку с завершающим нулем, являющуюся
копией строкового литерала. Компилятор записывает строковые лите-
ралы в сегмент данных, аналогично описанию "скрытых" типизирован-
ных констант:
const
TempString: array[0..14] of Char = 'Привет...'#0;
var
P: PChar;
.
.
begin
P := @TempString;
end;
Когда соответствующие формальные параметры имеют тип Char,
строковые литералы вы можете использовать как фактические пара-
метры при вызовах процедур и функций. Например, если имеется про-
цедура с описанием:
procedure PrintStr(Str: PChar);
то допустимы следующие вызовы процедуры:
procedure PrintStr('Строка для проверки');
PrintStr(#10#13);
Аналогично тому, как это происходит при присваивании, компи-
лятор генерирует строку с завершающим нулем, представляющую собой
копию литеральной строки в сегменте данных, и передает указатель
на эту область памяти в параметре Str процедуры PrintStr.
Наконец, типизированная константа типа PChar может инициали-
зироваться строковой константой. Это справедливо также для струк-
турных типов, таких как массивы PChar и записи, а также объекты
PChar.
const
Message: PChar = 'Program terminated';
Prompt: PChar = 'Enter values: ';
Digits; array [0..9] of PChar = {
'Zero', 'One', 'Two', 'Three', 'Four', 'Five',
'Six', 'Seven', Eight', 'Nine'};
Строковая выражение-константа всегда вычисляется как строка
Паскаля, даже если она инициализируется как типизированная конс-
танта типа PChar. Таким образом, строковое выражение-константа
всегда ограничено длиной в 255 символов.
Символьные указатели и символьные массивы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Если вы с помощью директивы $X разрешаете расширенный син-
таксис, то символьный массив с нулевой базой совместим с типом
PChar. Это означает, что там, где предполагается использование
типа PChar, может использоваться символьный массив с нулевой ба-
зой. Когда символьный массив используется вместо значения PChar,
компилятор преобразует символьный массив в указатель-константу,
значение которой соответствует адресу первого элемента массива.
Например:
var
A: array[0..63] of Char;
P: PChar;
.
.
.
begin
P := A;
PrintStr(A);
PrintStr(P);
end;
Благодаря оператору присваивания P теперь указывает на пер-
вый элемент массива A, поэтому PrintStr вызывается дважды с одним
и тем же значением.
Вы можете инициализировать типизованную константу, имеющую
тип символьного массива с нулевой базой, с помощью строкового ли-
терала, имеющего меньшую длину, чем размер массива. Оставшиеся
символы устанавливаются в значение NULL (#0), и массив будет со-
держать строку с завершающим нулем.
type
TFileName = array[0..79] of Char;
const
FileNameBuf: TfileName = 'TEST.PAS';
FileNamePtr: PCahr = FileNameBuf;
Индексирование символьного указателя
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Так как символьный массив с нулевой базой совместим с сим-
вольным указателем, символьный указатель можно индексировать ана-
логично символьному массиву с нулевой базой.
var
A: array[0..63] of Char;
P: PChar;
Ch: Char;
.
.
.
begin
P := A;
Ch := A[5];
Ch := P[5];
end;
Оба последних присваивания присваивают Ch значение, содержа-
щееся в шестом символе-элементе A.
При индексировании символьного указателя индекс задает безз-
наковое смещение, которое добавляется к указателю перед его разы-
менованием. Таким образом, P[0] эквивалентно P^ и задает символ,
на который указывает P. P[1] задает символ справа от того, на ко-
торый указывает P, P[2] задает следующий символ и т.д. Для целей
индексирования PChar ведет себя таким образом, как если бы он
описывался:
type
TCharArray = array[0..65535] of Char;
Pchar = ^TCharArray;
Компилятор при индексировании символьного указателя не вы-
полняет проверку диапазона, так как у него нет информации о типе,
по которой можно определить максимальную длину строки с завершаю-
щим нулем, на которую указывает символьный указатель.
Показанная ниже функция StrUpper иллюстрирует использование
символьного указателя для преобразования строки с завершающим ну-
лем в верхний регистр.
function StrUpper(Srt: Pchar): Pchar;
var
I: Word;
begin
I := 0;
while Str[I] <> #0 do
begin
Str[I] := UpCase(Str[I]);
Inc(I);
end;
StrUpper := Str;
end;
Обратите внимание, что StrUppper - это функция, а не проце-
дура, и что она всегда возвращает значение, которое передавалось
ей в качестве параметра. Так как расширенный синтаксис допускает
игнорирование результата функции, StrUpper может интерпретиро-
ваться, как процедура:
StrUpper(A);
PrintStr(A);
Однако, StrUpper всегда возвращает передаваемое ей значение,
приведенные выше операторы можно скомбинировать в один:
PrintStr(StrUpper(A));
Вложенные вызовы функций работы со строками с завершающим
нулем могут оказаться очень удобными, когда вы хотите указать оп-
ределенную взаимосвязь между последовательными операциями со
строками.
Операции с символьными указателями
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Расширенный синтаксис Borland Pascal позволяет использовать
для работы с символьными указателями отдельные операции. Для уве-
личения или уменьшения смещения в значении указателя можно ис-
пользовать операции плюс (+) и минус (-). Операцию минус (-) мож-
но использовать для вычисления расстояния (разности смещений)
между двумя символьными указателями. Предположим, что P и Q
представляют собой значения тип PChar, а I - значение типа Word.
Тогда допустимы следующие конструкции:
P + I I прибавляется к смещению P
I + P I прибавляется к смещению P
P - I I вычитается из смещения P
P - Q Смещение Q вычитается из смещения P
В операциях P + I и I + P I прибавляется к адресу, задавае-
мому P. При этом получается указатель, который указывает на I
символов после P. В операции P - I I вычитается из адреса, зада-
ваемого P, и получается указатель, указывающий на I символов до
P.
Операция P - Q вычисляет расстояние между Q (младший адрес)
и P (старший адрес). При этом возвращается результат типа Word,
показывающий число символов между Q и P. Эта операция предполага-
ет, что P и Q указывают на один и тот же массив символов. Если
эти два указателя указывают на разные символьные массивы, то ре-
зультат непредсказуем.
Стандартный синтаксис Borland Pascal позволяет при сравнении
указателей определять только их равенство или неравенство. Расши-
ренный синтаксис (разрешенный по директиве компилятора {$X+})
позволяет применять операции <, >, <= и <= к значениям PChar. За-
метим, однако, что при таких проверках предполагается, что два
сравниваемых указателя указывают на один и тот же массив симво-
лов. По этой причине сравниваются только смещения указателей. Ес-
ли два указателя указывают на различные символьные массивы, то
результат не определен.
var
A, B: array[0..79] of Char;
P, Q: PChar;
begin
P := A; { P указывает на A[0] }
Q := A + 5; { Q указывает на A[5] }
if P < Q then ...; { допустимая проверка,
результат - True }
Q := B; { Q указывает на B[0] }
if P < Q then ...; { результат не определен }
end;
Подробнее об операциях с PChar рассказывается в Главе 6.
Строки с завершающим нулем и стандартные процедуры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Расширенный синтаксис Borland Pascal позволяет применять к
символьным массивам с нулевой базой стандартные процедуры Read,
ReadLn и Val, а к символьным массива с нулевой базой и символьным
указателям - стандартные процедуры Write, WriteLn, Val, Assign и
Rename. Более подробные описания этих процедур можно найти в Гла-
ве 1 ("Справочник по библиотеке") "Справочного руководства прог-
раммиста".
Пример использования функций с завершающим нулем
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Приведем пример исходного кода, показывающий, как можно ис-
пользовать некоторые функции обработки строк. Этот пример исполь-
зован при разработке функции FileSplit в модуле WinDos.
{ максимальные размеры компонентов имени файла }
const
fsPathName = 79; { имя маршрута }
fsDirectory = 67; { имя каталога }
fsFileName = 8; { имя файла }
fsExtension = 4; { расширение имени файла }
{ флаги, возвращаемые FileSplit }
const
fcWildcards = $0008 { трафаретные символы }
fcDirectory = $0004 { имя каталога }
fcFileName = $0002 { имя файла }
fcExtension = $0001 { расширение имени файла }
{ FileSplit разбивает имя файла, заданное маршрутом, на три }
{ компонента. Dir принимает значение диска и каталога с }
{ предшествующей и завершающей обратной косой чертой, Name }
{ принимает значение имени файла, а Ext - расширения с }
{ предшествующей точкой. Если компонент строки-параметра }
{ равен NIL, то соответствующая часть маршрута не }
{ записывается. Если маршрут не содержит данного компонента, }
{ то возвращаемая строка компонента будет пустой. }
{ Максимальные длины строк, возвращаемых в Dir, Name и Ext, }
{ определяются битовыми масками fsDirectory, fsFileName, }
{ fsExtension. Возвращаемое значение представляет собой }
{ комбинацию битовых масок fсDirectory, fсFileName и }
{ fсExtension, показывающую, какие компоненты присутствуют в }
{ маршруте. Если имя и расширение содержат трафаретные }
{ символы (* и ?), то в возвращаемом значении устанавливается }
{ флаг fcWildcards. }
function FileSplit(Path, Dir, Name, Ext: PChar): Word;
var
DirLen, NameLEn, Flags: Word;
NamePtr, ExtPtr: PChar;
begin
NamePtr := StrRScan(Path, '/');
if NamePtr = nil then NamePtr := StrRScan(Path, ':');
if NamePtr = nil then NamePtr := Path else Inc(NamePtr);
ExtPtr := StrScan(NamePtr, '.');
if ExtPtr = nil then ExtPtr := StrEnd(NamePtr);
DirLen := NamePtr - Path;
if DirLen > fsDirectory then DirLen := fsDirectory;
NameLen := ExtPtr - NamePtr;
if NameLen > fsFilename then NameLen := fsFileName;
Flags := 0;
if (StrScan(NamePtr, '?') <> nil) or
(StrScan(NamePtr, '*') <> nil) then
Falgs := fcWildcards;
if DirLen <> 0 then Flags := Flags or fcDirectory;
if NameLen <> 0 then Flags := Flags or fcFilename;
if ExtPtr[0] <> #0 then Flags := Flags or fcExtension;
if Dir <> nil then StrLCopy(Dir, Path, DirLen);
if Name <> nil then StrLCopy(Name, NamePtr, NameLen);
if Ext <> nil then StrLCopy(Ext, ExtPtr, fsExtension);
FileSplit := Flags:
end;
Глава 19. Использование графического интерфейса Borland
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Модуль Graph реализует полную библиотеку из более чем 50
графических программ - от вызовов процедур и функций высокого
уровня, как, например, SetViewPort, Bаr3D, DrаwPoly, до программ,
ориентированных на работу с битами, таких, как GetImage или
РutImage. Поддерживается несколько видов закрашивания и типов ли-
ний, и имеется несколько шрифтов, которые можно изменять по вели-
чине, выравнивать и ориентировать горизонтально или вертикально.
Для компиляции программы, использующей модуль Grаph, вам не
потребуется никаких внешних файлов (кроме, конечно, исходного
текста вашей программы, компилятора и доступа к стандартным моду-
лям в библиотеке исполняющей системы).
Имена библиотек и модуля Graph Таблица 19.1
ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДї
і Тип программы і Библиотека і Имя модуля Graph і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДґ
і Реальный режим і TURBO.TPL і GRAPH.TPU і
і Защищенный режим і TPP.TPL і GRAPH.TPP і
АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДЩ
Для запуска программы, использующей модуль Grарh, кроме ва-
шей программы с расширением .EXE вам потребуются один или более
графических драйверов (см. далее файлы .BGI). Кроме того вам пот-
ребуется также один или более файлов шрифтов (.CНR), если в вашей
программе используются какие-либо шрифты.
Примечание: В соответствии с лицензионными условиями
вы можете распространять файлы .CHR и .BGI наряду со своими
программами.
Драйверы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Для перечисленных ниже графических адаптеров и полностью
совместимых с ними предусмотрены следующие графические драйверы:
CGA Неrcules
МСGA AT&T 400
EGA 3270 PC
VGA IBM 8514
Каждый драйвер содержит выполняемый код и данные и хранится
в отдельном файле на диске. Во время работы процедура InitGraph
идентифицирует графическую аппаратуру и производит загрузку и
инициализацию соответствующего графического драйвера, переводит
систему в графический режим, а затем возвращает управление вызы-
вающей программе. Процедура CloseGraph выгружает драйвер из памя-
ти и восстанавливает предыдущий видеорежим. С помощью программ
RеstoreCrtMode и SetGraphMode вы можете переключаться между текс-
товым и графическим режимом. См. Главу 1 в "Справочном руководс-
тве программиста".
Модуль Grаph может также работать на компьютерах с двумя мо-
ниторами. При инициализации модуля Graph с помощью процедуры
InitGraph для графического драйвера и требуемого режима будет
выбран нужный монитор. При завершении работы графической програм-
мы предыдущий видеорежим будет восстановлен. Если для графической
аппаратуры с двумя мониторами требуется автоматическое распозна-
вание, то процедура InitGraph выберет монитор и графическую пла-
ту, при которой будет получаться наилучшее качество выводимой
графической информации.
ЪДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Драйвер і Аппаратура і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і CGA.BGI і Драйвер для адаптеров CGA, MCGA фирмы IBM. і
і EGAVGA.BGI і Драйвер для адаптеров EGA, VGA фирмы IBM. і
і HERC.BGI і Драйвер для монохромного адаптера Hercules фир-і
і і мы IBM. і
і ATT.BGI і Драйвер для AT&T 6300 (400 строк). і
і PC3270.BGI і Драйвер для IBM 3270 РС. і
і IBM8514.BGI і Драйвер для IBM 8514. і
АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Поддержка устройства IBM 8514
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Borland Pascal поддерживает графическую плату IBM 8514, ко-
торая представляет собой новую графическую плату с высоким разре-
шением, позволяющую получить разрешающую способность до 1024х768
точек и палитру, содержащую 256 оттенков из 256 цветов. Файл
драйвера для этой графической платы называется IBM8514.BGI.
Графическая плата IBM 8514 не может правильно распознаваться
Borland Pascal при автоматическом обнаружении (она будет распоз-
наваться алгоритмами автообнаружения, как плата VGA). Таким обра-
зом, чтобы использовать плату IBM 8514, переменной GraphDriver
при вызове InitGraph нужно присвоить значение IBM8514 (которое
определено в модуле Graph). При работе с платой IBM 8514 не сле-
дует использовать с InitGraph DetectGraph или DETECT (если только
вы не хотите эмулировать режим VGA).
Для платы IBM 8514 поддерживаются следующие режимы: IBM8514LO
(640х480 элементов изображения) и IBM8514HI (1024х768 элементов
изображения). Обе константы режима определены в интерфейсной час-
ти GRAPH.TPU.
Для определения цветов в плате IBM 8514 используются три
6-битовых значения. Для каждого определяемого цвета имеются 6-би-
товые компоненты Red (красный), Green (зеленый) и Blue (голубой).
Для того, чтобы при работе с графической платой IBM 8514 пользо-
ватель мог задавать цвета, в библиотеку BGI добавлена новая прог-
рамма. Эта программа определяется в модуле GRAPH.TPU следующим
образом:
procedure SetRGBPalette(ColorNum, Red, Green, Blue: Word);
Аргумент ColorNum задает запись палитры, которую нужно загру-
зить. Этот аргумент представляет собой целое значение в диапазоне
от 0 до 255 (дес.). Аргументы Red, Green и Blue определяют компо-
ненты цветов в записи палитры. Используется только младший байт
этих значений и только 6 старших битов этого байта загружаются в
палитру.
Другие программы, модифицирующие палитру (SetAllPalette,
SetPalette, GetPalette), при работе с графической платой IBM 8514
использовать не следует.
Для совместимости с графическими адаптерами фирмы IBM драйве-
ры формата BGI определяют для первых 16 цветов палитры IBM 8514
значения цветов, принятые по умолчанию для адаптеров EGA/VGA. Эти
значения могут использоваться в неизмененном виде или модифициро-
ваться с помощью процедуры SetGRBPalette.
Система координат
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
По соглашению верхний левый угол экрана имеет координату
(0,0). У более правого столбца координата х больше, у более ниж-
ней строки больше координата y. То есть координата х увеличивает-
ся при перемещении вправо, а координата y - при перемещении вниз.
Таким образом координаты каждого из четырех углов и конкретной
точки (середины экрана) будут выглядеть следующим образом:
(0,0) (319,0)
ЪДДДДДДДДДДДДДДДДДДДДДДДї
і і
і (159,99) і
і . і
і і
і і
і і
АДДДДДДДДДДДДДДДДДДДДДДДЩ
(0,199) (319,199)
Рис. 19.1 Экран с координатами xy.
Текущий указатель
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Понятие текущего указателя используется во многих графичес-
ких системах. Понятие текущего указателя аналогично понятию кур-
сора для текстового режима, за исключением того, что текущий ука-
затель невидим.
Write('ABC');
В текстовом режиме предшествующий оператор Write оставит
курсор в колонке, непосредственно следующим за буквой C. Если
буква C была введена в колонке 80, то курсор перейдет на колонку
1 следующей строки. Если буква c была введена в позиции 80 строки
25, то произойдет пролистывание (прокрутка) экрана вверх на 1
строку и курсор будет находится в 1 позиции 25 строки.
MoveTo(0,0);
LineTo(20,20)
В графическом режиме данный оператор LinеТо оставит текущий
указатель в последней заданной точке (20,20). Если действует ре-
жим отсечения, то реально выводимая прямая будет отсечена до те-
кущей точки. Заметим, что текущий указатель никогда не отсекает-
ся.
Команда МоvеТо является эквивалентом команды GotoXY. Единс-
твенное ее назначение - это перемещение текущего указателя. Пере-
мещение текущего указателя может использоваться только в следую-
щих командах, использующих текущий указатель: MoveTo, InitGraph,
MoveRel, LineTo, LineRel, OutText, SetGraphMode, ClearDevice,
SetViewPort и ClearViewPort. Последние 5 из них перемещают теку-
щий указатель в точку (0,0).
Текст
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В графическом режиме для вывода текста используется шрифт с
растром 8х8 и несколько векторных шрифтов. Растровый символ зада-
ется с помощью матрицы элементов изображения. Векторный шрифт за-
дается рядом векторов, которые указывают графической системе, как
рисовать шрифт.
Преимущество использования векторных шрифтов становится оче-
видным, когда вы начинаете рисовать большие символы. Поскольку
штриховой шрифт задается векторами, то при увеличении шрифта ка-
чество и разрешение остаются, тем не менее, хорошими.
Когда увеличивается растровый шрифт, то матрица умножается
на масштабный коэффициент, а когда этот масштабный коэффициент
увеличивается, разрешение у символов становится более грубым. Для
маленьких шрифтов растровый шрифт должен быть достаточно приемле-
мым, но для больших шрифтов вы, вероятно, захотите выбрать век-
торный шрифт.
Выравнивание графического текста управляется процедурой
SetTextJustify. Масштабирование и выбор шрифта осуществляется с
помощью процедуры SetTextStyle. Графический текст выводится с по-
мощью процедур ОutText или ОutTextХY. Запрос о текущих установ-
ленных для текста параметрах выполняется с помощью обращения к
процедуре GetTextSettings. Векторные шрифты хранятся каждый в от-
дельном файле на диске и должны присутствовать там во время рабо-
ты (при вызове процедуры SetTextStyle). Размер векторного шрифта
можно настроить с помощью процедуры SetUserCharSize. Файлы шриф-
тов (которые имеют расширение .CHR) могут загружаться с диска ав-
томатически модулем Graph, или их можно компоновать с программой
пользователя или загружать и "регистрировать" с помощью модуля
Graph.
Для преобразования файла шрифта (или любого другого предназ-
наченного для этой цели двоичного файла данных) в файл .OBJ, ко-
торый можно компоновать с модулем или программой с помощью дирек-
тивы компилятора $L в Borland Pascal предусмотрена специальная
утилита BINOBJ.EXE. При этом становится возможным поместить все
файлы шрифтов в выполняемый файл .EXE (см. комментарии в начале
примера программы BGILINK.PAS на дистрибутивном диске).
Графические изображения и их виды
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Для вычерчивания и закрашивания графических изображения,
включая точки, прямые, окружности, дуги, эллипсы, прямоугольники,
многоугольники, штриховку, трехмерную штриховку и секторы, имеет-
ся целый ряд обеспечивающих программ. Для управления видом линии
- будет она тонкой или толстой, непрерывной или состоящей из то-
чек, или же построенной по вашему собственному образцу - можно
использовать процедуру SetLineStyle.
Для закрашивания области или многоугольника пересекающейся
штриховкой или чем-либо более сложным можно использовать процеду-
ры SetFillStyle, SetFloodPattern, FillPoly и FloodFill.
Области просмотра и двоичные образы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Процедура ViewPoint позволяет всем командам вывода работать
в прямоугольной области экрана. Графики, прямые и другие графи-
ческие изображения (весь графический вывод) связывается с об-
ластью просмотра, пока эта область не изменяется. Предусмотрены
программы для очистки области просмотра и считывания ее текущих
определений. Если задан режим отсечения, то весь графический вы-
вод отсечется до текущей точки. Заметим, что текущий указатель
никогда не отсекается.
Для считывания и вывода элементов изображения предусмотрены
процедуры GetPixel и Putpixel. Чтобы сохранить и восстановить на
экране прямоугольную область, можно использовать процедуры
GetImage и PutImage. Они обеспечивают полное выполнение операций
процедуры ВitВlt (нормальное, хоr, оr, аnd, nоt).
Поддержка страниц и цветов
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Имеется много других поддерживающих программ, включая под-
держку для нескольких графических страниц (только для адаптеров
EGA, VGA и Неrcules; это особенно полезно при использовании в
мультипликации), палитры, цвета и так далее.
Обработка ошибок
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Внутренние ошибки модуля Graph возвращаются функцией
GraphResult. Эта функция возвращает код ошибки, показывающий сос-
тояние последней графической операции. Коды возврата приведены
в разделе по GraphResult в Главе 1 ("Справочник по библиотеки")
"Справочного руководства программиста".
Значение кода возврата для функции GraphResult устанавлива-
ется следующими процедурами:
DetectGraph SetTextStile SetAllPalette
InitGraph SetGraphMode SetFillPattern
FloodFill CloseGraph SetFillStyle
FillPoly GetGraphMode SetGraphBufSize
DrawPoly ImageSize SetGraphMode
Bar InstallUserDriver SetLineStyle
Bаr3D InstallUserFont SetPalette
PieSlice RegisterBGIDriver SetTextJustify
ClearViewPort RegisterGBIFont
Заметим, что функция GraphResult после обращения к ней сбра-
сывает код ошибки в 0. Таким образом, пользователь должен сохра-
нить значение кода ошибки во временной переменной и затем прове-
рить его.
Начало работы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Приведем пример простой графической программы:
1 program GraphTest;
2 uses
3 Graph;
4 var
5 GraphDriver : integer;
6 GraphMode : integer;
7 ErrorCode : integer;
8 begin
9 GraphDriver := Detect; { Установить флаг: выполнить
распознавание }
10 InitGraph(GraphDriver, GraphMode, 'C:\DRIVERS');
11 ErrorCode := GraphResult;
12 if ErrorCode <> grOk then { ошибка? }
13 begin
14 Writeln('Ошибка графики: ',GraphErrorMsg(ErrorCode);
15 Writeln('Программа аварийно завершила работу...');
16 Halt(1);
17 end;
18 Rectangle(0, 0, GetMaxX, GetMaxY); { нарисовать рамку
размером в экран }
19 SetTextJustify(CenterText, CenterText); { центрирова-
ние текста }
20 SetTextStyle(DefaultFont, HorizDir, 3);
21 OutTextXY(GetMaxX div 2, GetMaxY div 2, { центр экрана }
22 'Графический интерфейс фирмы Borland (BGI)');
23 Readln;
24 CloseGraph;
25 end. { GraphTest }
Программа начинается с обращения к процедуре InitGraph, ко-
торая автоматически проверяет наличие аппаратуры и загружает со-
ответствующий графический драйвер (находящийся в каталоге C:
DRIVERS). Если графическая аппаратура не распознана или в процес-
се инициализации произошла ошибка, то на экран выводится сообще-
ние об ошибке и программа прекращает работу. В противном случае
вдоль краев экрана рисуется прямоугольник и в центре экрана выво-
дится текст.
Плата AT&T 400 или IBM 8514 не распознается автоматически.
Тем не менее, вы можете пользоваться драйвером графики AT&T путем
отмены автоматической проверки, пересылки исполняемого кода драй-
вера AT&T процедуре InitGraph и установки допустимого графическо-
го режима. Замените 8 и 9 строку в предыдущем примере следующими
тремя строками:
GraphDriver := ATT400;
GraphMode := ATT400Hi;
InitGraph(GraphDriver, GraphMode, 'C:\BP\BGI');
Это укажет графической системе на необходимость загрузки
драйвера устройства AT&T400, расположенного в каталоге C:\BP\BGI,
и установит графический режим 640 на 400.
Приведем еще один пример, который показывает, как можно пе-
реключаться между графическим и текстовым режимами:
1 program GraphTest;
2 uses
3 Graph;
4 var
5 GraphDriver : integer;
6 GraphMode : integer;
7 ErrorCode : integer;
8 begin
9 GraphDriver := Detect; { Установить флаг: выполнить
распознавание }
10 InitGraph(GraphDriver, GraphMode, 'C:\DRIVERS');
11 ErrorCode := GraphResult;
12 if ErrorCode <> grOk then { ошибка? }
13 begin
14 Writeln('Ошибка графики: ',GraphErrorMsg(ErrorCode);
15 Writeln('Программа аварийно завершила работу...');
16 Helt(1);
17 end;
18 OutText('Графический режим. Нажмите
|