ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 28 *- ГЛАВА 15. Редактор и текстовые отображаемые элементы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для работы с текстом в вашем приложении Turbo Vision предус- матривает два вида объектов. Текстовые отображаемые элементы до- пускают гибкий вывод текста, в то время как объекты редактора позволяют пользователю вводить и модифицировать текст. Данная глава охватывает следующие вопросы использование текстовых отоб- ражаемых элементов: - базовый текстовый отображаемый элемент; - "немой" терминальный отображаемый элемент; - базовый текстовый редактор; - редактор примечаний; - файловый редактор; - буфер вырезанного текста редактора; - окно редактирования. *- Что такое текстовый отображаемый элемент? ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Текстовые отображаемые элементы - это простые потомки TScroller, связывающие устройство текстового файла с прокручивае- мым отображаемым элементом. Turbo Vision определяет абстрактное текстовое устройство в типе TTextDevice, который добавляет вирту- альные методы для считывания строк из текстового файла и записи строк в этот файл. Тип TTextDevice сам по себе не представляет ничего полезного, и создавать его экземпляры не требуется, но он обеспечивает основу для более полезных текстовых отображаемых элементов, например, терминального отображаемого элемента TTterminal. *- Использование терминального отображаемого элемента ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Терминальный отображаемый элемент определен типом TTerminal и является единственным типом текстового отображаемого элемента, предусмотренным в Turbo Vision. Он обеспечивает для устройства текстового файла прокручиваемый отображаемый элемент с доступом типа "только запись". Возможно, вы найдете терминальные отобража- емые элементы наиболее полезными для целей отладки или отслежива- ния содержимого файла. Большая часть поведения терминального отображаемого элемента реализуется автоматически. Если вы знакомы с работой с устройс- твами текстовых файлов, то иметь дело с TTerminal вам будет нет- рудно. Использование терминального отображаемого элемента предус- матривает три шага: - построение терминального отображаемого элемента; - присваивание текстового устройства; - запись в терминальный отображаемый элемент. Заметим, что хотя вы можете выполнять чтение из терминально- го отображаемого элемента, он всегда возвращает пустую строку. *- Построение терминального отображаемого элемента ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Построение терминального отображаемого элемента лишь слегка отличается от построения других прокручиваемых отображаемых эле- ментов. Кроме ограничивающего прямоугольника и параметров полосы прокрутки, конструктор воспринимает параметр типа Word, задающий размер терминального буфера. *- Управление буфером ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Фактическое управление текстовым буфером выполняет для вас TTerminal. Когда вы задаете размер буфера, TTerminal выделяет за- данное число байт в виде массива символов с завершающим нулем ти- па TTerminalBuffer. Все записываемые в терминальный отображаемый элемент символы помещаются в этот буфер. При достижении конца бу- фера терминальный отображаемый элемент автоматически снова пере- ходит к началу буфера, отслеживая точку начала выводимого на эк- ран текста. TTerminal содержит несколько методов, которые вы можете ис- пользовать для определения статуса буфера. Булевская функция CanInsert указывает, приведет ли вставка заданного числа символов к выбрасыванию из буфера верхней строки. QueEmpty показывает, со- держит ли буфер какие-либо символы. CalcWidth возвращает длину самой длинной строки в буфере. *- Присваивание текстового устройства ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Перед тем как терминальный отображаемый элемент сможет взаи- модействовать с текстовым устройством, вам нужно присвоить отоб- ражаемому элементу текстовое устройство. Turbo Vision предусмат- ривает процедуру AssignDevice, которая делает для вашего тексто- вого отображаемого элемента то же, что делает процедура Assign для текстового файла. Она связывает заданный файл с терминальным отображаемым элементом. Это означает, что все последующие опера- ции ввода или вывода с текстовым файлом приведут к чтению из тер- минального отображаемого элемента или записи в него. Например, имея терминальный отображаемый элемент Terminal и текстовый файл TermText, вы присваиваете текстовому устройству терминальный отображаемый элемент: AssignDevice(TermText, Terminal); *- Запись в терминальный отображаемый элемент ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Запись в терминальный отображаемый элемент аналогична записи на любое устройство текстового файла. Вы можете использовать стандартные процедуры Write и Writeln. После вызова для связи устройства текстового файла с терминальный отображаемым элементом процедуры AssignDevice весь вывод на устройство текстового файла появляется в терминальном отображаемом элементе. Заметим, что как и в случае любого устройства текстового файла для открытия файла вам нужно вызывать процедуру Rewrite или Reset. После этого вы можете вызывать процедуры Write или Writeln, задавая идентификатор текстового устройства, например: AssignDevice(TermText, Terminal); Rewrite(TermText); Writeln(TermText, 'Это выводится в отображаемом элементе'); Простая программа следующего примера перехватывает события "мыши" и записывает координаты щелчков "мыши" в терминальном отображаемом элементе в окно. Ту же программу вы найдете в файле TERMTEST.PAS на ваших дистрибутивных дисках. program TermTest; uses Objects, Views, App, Drives, TextView; type PTermWin = ^TTermWin; TTermWin = object(TWindow) TermText: Text; Terminal: PTerminal; constructor Init; procedure HandleEvent(var Event: TEvent); virtual; end; TTermApp = object(TApplication) constructor Init; end; constructor TTermWin.Init; var R: TRect; HScrollBar, VScrollBar: PScrollBar; begin Desktop^.GetExtent(R); inherited Init(R, 'Terminal test window', wmNoNumber); R.Grow(-1, -1); HScrollBar := StandardScrollBar(sbHorizontal or sbHandleKeyboard); Insert(HScrollBar); VScrollBar := StandardScrollBar(sbVertical or sbHandleKeyboard); Invert(VScrollbar); New(Terminal, Init(R, HScrollBar, VScrollBar, 8192)); if Application^.ValidView(Terminal) <> nil then begin AssignDevice(TermText, Terminal); Rewrite(TermText); Invert(Terminal); end; end; procedure TTermWin.HandleEvent(var Event: TEvent); begin if Event.What and evMouseDown <> 0 then begin if Event.Buttons and mbLeftButton <> 0 then Write(TermText', 'Left ') { левая } else Write(TermText', 'Right ') { правая } Writeln(TermText, '(', Event.Where.X, ',', Event.Where.Y, ')',); end; inherited HandleEvent(Event); end; constructor TTermApp.Init; var TextWin: PTermWin; begin inherited Init; New(TextWin, Init); if ValidView(TextWin) <> nil then InsertWindow(TextWin); end; var TermApp: TTermApp; begin TermApp.Init; TermApp.Run; TermApp.Done; end. *- Использование объекта редактора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Turbo Vision определяет объектный тип редактора TEditor, ре- ализующий небольшой и быстрый 64-килобайтовый редактор с поддерж- кой "мыши", операций с буфером вырезанного текста, отменой, авто- отступом и режимами замены, привязкой клавиш WordStar и функциями поиска/замены. В данном разделе поясняется следующее: - как работает редактор; - использование меню Edit; - привязка клавиш WordStar; - параметры редактора; - поиск и замена; - использование индикаторов и полос прокрутки. *- Как работает редактор ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Вникать во внутреннюю работу объекта редактора вам обычно не требуется. В наиболее общих случаях, таких как файловый редактор и поле примечания в окне, используются два типа-потомка TFileEditor и TMemo. Оба они описываются в данной главе. TEditor реализует редактор с "буферным промежутком". Это оз- начает, что он записывает свой текст двумя частями с разрывом между ними. Текст перед курсором записывается в начало буфера, а текст после курсора - в конец. Пробел между ними называется про- межутком. Вставляемые в редакторе символы попадают в начало промежут- ка. Удаляемые символы остаются в буфере, но в конце промежутка. Редактор поддерживает отмену вставки и удаления, отслеживая число удаляемых и вставляемых символов. При запросе на отмену редактор удаляет вставленные символы, перемещает удаленные символы в нача- ло промежутка и позиционирует курсор после ранее удаленного текс- та. *- Работа буфера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы увидеть, как работает буфер, посмотрите на Рис. 15.1, где показан буфер редактора с вновь набранным текстом 'abcdefghijkxxxopqrstuvwxyz' CurPtr v і<ДДGapLenД>і ЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДї іaіbіcіdіeіfіgіhіiіjіkіxіxіxіoіpіqіrіsіtіuіvіwіxіyіzі і і і і і і АДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДЩ і<ДДДДДДДДДДДДДДДДДДДДДBufLenДДДДДДДДДДДДДДДДДДДДДД>і і і<ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДBufSizeДДДДДДДДДДДДДДДДДДДДДДДД>і Рис. 15.1 Буфер со вставленным текстом. BufSize - это размер буфера, который задается при построении объекта редактора. CurPtr указывает позицию курсора, GapLen - это длина промежутка, а BufLen - общее число символов в буфере. Сумма GapLen и BufLen всегда равна BufSize. Если вы поместите курсор непосредственно после символов 'xxx', то буфер будет выглядеть следующим образом: CurPtr v і<ДДGapLenД>і ЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДї іaіbіcіdіeіfіgіhіiіjіkіxіxіxі і і і і і іoіpіqіrіsіtіuіvіwіxіyіzі АДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДЩ і<ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДBufSizeДДДДДДДДДДДДДДДДДДДДДДДД>і і<ДДДДДДДДДДДДДДДДДДДДДДДДД>і + і<ДДДДДДДДДДДДДДДДДДДДД>і = BufLen Рис. 15.2 Буфер после перемещения курсора. Заметим, что промежуток перед курсором сохраняется, давая возможность быстро вставлять символы без перемещения текста. *- Удаление текста ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Пользователь может удалять текст, нажимая перед ним клавишу Backspace, удалять символы перед курсором с помощью клавиши Del, либо выделять блок текста и нажимать Del. Ваша программа может удалить выделенный блок с помощью вызова метода DeleteSelect. Если вы удаляете 'xxx' с помощью клавиши Backspace, редактор перемещает символы к концу промежутка, и курсор перемещается в обратном направлении. В поле delCount записывается число удален- ных символов. Состояние буфера после удаления 'xxx' показано на Рис. 15.3. CurPtr v і<ДДДДДGapLenДДДД>і ЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДї іaіbіcіdіeіfіgіhіiіjіkі і і і і і іxіxіxіoіpіqіrіsіtіuіvіwіxіyіzі АДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДЩ і<ДДД>і DelCount і<ДДДДДДДДДДДДДДДДДДДДДДДДBufSizeДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД>і і<ДДДДДДДДДДДДДДДДДДДДДДДДД>і + і<ДДДДДДДДДДДДДДДДДДДДД>і = BufLen Рис. 15.3 Буфер после удаления 'xxx'. *- Вставка текста ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Вставка текста обычно является результатом нажатий клавиш или вставки текста из буфера вырезанного текста. Редактор имеет два управляющих вставкой метода - InsertText и InsertFrom. InsertText воспринимает заданное число символов и включает их в буфер. InsertFrom вставляет выделенный текст из заданного буфера объекта редактора. Оба метода вставки вызывают метод вставки ниж- него уровня InsertBuffer, но вы не должны вызывать его непосредс- твенно. Когда вы вставляете символы, для определения числа удаляемых с помощью отмены символов редактор увеличивает значение счетчика вставки InsCount. Если вы наберете 'lmn', то буфер выглядит как показано на Рис. 15.4. CurPtr v і<ДДGapLenД>і ЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДї іaіbіcіdіeіfіgіhіiіjіkіlіmіnі і і іxіxіxіoіpіqіrіsіtіuіvіwіxіyіzі АДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДЩ InsCount і<ДДД>і і<ДДД>і DelCount і<ДДДДДДДДДДДДДДДДДДДДДДДBufSizeДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД>і і<ДДДДДДДДДДДДДДДДДДДДДДДДД>і + і<ДДДДДДДДДДДДДДДДДДДДД>і = BufLen Рис. 15.4 Буфер после вставки 'lmn'. Число вставленных символов записывается в InsCount. *- Отмена редактирования ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Объекты редактирования имеют ограниченную функцию отмены, обратиться к которой пользователь обычно может через меню Edit, которое вызывает метод Undo объекта редактирования. Если вы запрашиваете отмену, редактор удаляет 'lmn' и пере- мещает символы 'xxx' на то место, где они находились, восстанав- ливая тот вид буфера, который представлен на Рис. 15.5. CurPtr v і<ДДGapLenД>і ЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДї іaіbіcіdіeіfіgіhіiіjіkіxіxіxі і і і і і іoіpіqіrіsіtіuіvіwіxіyіzі АДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДЩ і<ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДBufSizeДДДДДДДДДДДДДДДДДДДДДДДД>і і<ДДДДДДДДДДДДДДДДДДДДДДДДД>і + і<ДДДДДДДДДДДДДДДДДДДДД>і = BufLen Рис. 15.5 Буфер после отмены. Метод Undo может отменять операции между перемещениями кур- сора. После перемещения программой или пользователем курсора все изменения редактирования будут восприняты. Из-за перемещения про- межутка вся информация отмены теряется. Заметим, что информация отмены занимает место в буфере, что может помешать вставке текста пользователем. Перемещение курсора освобождает это место. *- Работа с блоками ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Выделение или отметка блока текста всегда происходит перед курсором или после него. Поля SelStart и SelEnd указывают начало и конец выделения. Обычно пользователи выделяют текст с помощью "мыши" или клавиатуры, но ваша программа может устанавливать вы- деление с помощью SelSelection, что также перемещает курсор. Вставка текста в редактор с помощью нажатия клавиши или с помощью InsertText заменяет выделенный текст включаемым текстом. При отсутствии выделения текст просто вставляется в позиции кур- сора. *- Использование меню Edit ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Все объекты редактирования знают как отвечать на несколько стандартных команд меню редактирования Edit: cmCopy, cmCut, cmClear, cmPaste и cmUndo. Команды вырезания, копирования и очистки работают с выделенным в редакторе текстом. Команда встав- ки вставляет в позиции курсора содержимое буфера вырезанного текста. Команда отмены отменяет все изменения редактирования с момента последнего перемещения курсора. Другие команды редактирования, такие как поиск и замена, об- рабатываются окном-владельцем объекта редактора, которое выводит на экран диалоговое окно редактирования, выводящее пользователю подсказки и запросы для ввода текста для поиска и замены и пара- метров. Затем владелец вызывает с соответствующими параметрами метод Search редактора. *- Обновление активных команд ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В каждый момент времени допустимы не все команды редактиро- вания. Например, бессмысленно посылать команду cmCut при отсутс- твии выделенных для вырезания символов. Объекты редактирования содержат метод UpdateCommands, который разрешает и запрещает ко- манды на основе текущего состояния редактора и буфера вырезанного текста. Он вызывается при изменении состояния редактора. Команды поиска, замены и повторного поиска активны всегда, хотя команды вырезания, копирования и вставки зависят от того, выделил ли пользователь текст. Команда Undo активна только в том случае, если пользователь имеет вставленный или удаленный после последнего перемещения курсора текст. *- Привязка клавиш редактора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД По умолчанию объекты редактора связывают команды со многими знакомыми вам по IDE последовательностями клавиш, аналогичных ис- пользуемым в редакторе WordSrtar, включая перемещение курсора и удаление текста. Основным исключением являются команды работы с блоками. Вы можете изменить эту привязку клавиш, переопределив метод ConvertEvent, которые транслируют определенные события клавиатуры в командные события. *- Работа с блоками ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Так как TEditor не использует постоянные блоки, он моделиру- ет блочные команды, копируя текст в буфер вырезанного текста и из него. Например, команды Ctrl+K Ctrl+C начинают выделение текста. Ctrl+K Ctrl+K копирует текст в буфер вырезанного изображения. Это достаточно близко моделирует команды WordStar. Вы можете также выделить блок текста, нажав клавишу Shift и одну из клавиш пере- мещения курсора. *- Параметры редактора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Объекты редактора предусматривают несколько параметров, ко- торые можно выбирать с помощью булевских полей: * CanUndo указывает, будет ли редактор записывать информацию отмены. Так как информация отмены временно "отбирает" мес- то у вставки, вы можете посчитать, что ее запрет даст не- которые преимущества. Для редакторов буфера вырезанного текста CanUndo всегда устанавливается в значение False. * Overwrite указывает, будет ли редактор находится в режиме вставки или замены. * AutoIndent определяет, будет ли нажатие клавиши Enter при- водить к тому, что редактор переходит на новой строке на позицию первого непробельного символа предыдущей строки или в самую левую позицию. Это удобно использовать для ре- дактирования исходного кода. Для определения отдельных параметров, которые применяются ко всем редакторам в приложении объекты редактора также использую битовую переменную модуля Editors с именем EditorFlags. EditorFlags управляет созданием файлов резервных копий и парамет- рами замены. Биты переменной EditorFlags показаны на Рис. 15.6. msb lsb ЙНСНСНСНСНСНСНСНСНСНСНСНСНСНСНСН» ИНПНПНПНПНПНПНПСПНПНПНПСПСПСПСПСј і і і і і АДДД efCaseSensitive = $0001 і і і і АДДДДД efWhoWordsOnly = $0002 і і і АДДДДДДД efPromptOnReplace = $0004 і і АДДДДДДДДД efReplaceAll = $0008 і АДДДДДДДДДДД efDoReplace = $0010 АДДДДДДДДДДДДДДДДДДД efBackupFiles = $0100 Рис. 15.6 Битовые флаги редактора. Биты редактора говорят сами за себя. Если вам нужны подроб- ности, см. Главу 19 "Справочник по Turbo Vision". *- Поиск и замена ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Операции поиска и замены обрабатываются при реакции на ко- манду. Например, вместо непосредственного вызова метода поиска текста пользователь генерирует команду cmFind, на которую объект редактора реагирует выводом соответствующего диалогового окна с подсказкой для ввода параметров поиска и замены. Аналогично, команда cmReplace вызывает вывод редактором подсказки для ввода текста для поиска и замены, а также парамет- ров. Используемыми в этих операциях диалоговыми блоками управляет функция EditorDialogs. *- Использование полей примечаний ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Объект примечания - это специальное расширение объекта ре- дактора, предназначенное для использование в качестве управляюще- го элемента диалогового окна. Оно не имеет специальных возможнос- тей редактирования, но добавляет определенные средства, необходи- мые для использования в качестве управляющего элемента: - палитры, которые отображаются в диалоговое окно; - методы GetData, SetData и DataSize. *- Цвета примечания ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Большинство объектов редактора используют стандартную палит- ру элемента прокрутки - желтые символы на белом фоне. Поскольку объекты примечания обычно существуют только в диалоговых окнах, они отображаются в более естественную цветовую комбинацию черного на бирюзовом. *- Действие по типу управляющего элемента ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы действовать как управляющий элемент, объекты редактора должны делать две вещи, которые другие редакторы делать не могут: - перемещения между полями по табуляции; - считывание значений из записи данных и их запись. *- Обработка табуляции ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Обычно объект редактора обрабатывает символы Tab, вставляя в текст табуляцию. Поскольку примечания действуют как управляющий элемент в диалоговом окне, они перехватывают клавиатурные события с кодом символа kbTab и обеспечивают для окна нормальное поведе- ние при табуляции, перемещая фокус на следующее поле. Все другие события объекты примечания передают обработчику событий, наследу- емому из TEditor. *- Установка и считывание значений ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Управляющие элементы должны устанавливать свои значения из записи данных и считывать их обратно в эту запись. Объект TMemo определяет три метода, необходимых для обработки такой передачи: DataSize, GetData и SetData. DataSize возвращает размер буфера редактирования, плюс раз- мер слова длины. GetData и SetData интерпретируют запись данных аналогично длинной строке, рассматривая первые два байта как дли- ну текста, а остальные байты как текст примечания. Запись данных для поля примечания должна иметь две записи. В следующем примере показано простое диалоговое окно с единственным управляющим элементом - полем примечания. { заметим, что ABufSize - это та же передаваемая конструкто- ру редактора команда, что и максимальный размер буфера } type TDialogData = record MemoLength: Word; MemoText: array[0..ABufSize] of Char; end; *- Использование редакторов файлов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Редактор файлов - это объект редактора, связанный с конкрет- ным текстовым файлом. Он не имеет дополнительных функций редакти- рования, но добавляет следующие средства: - загрузку и сохранения файлов; - гибкие буферы. Использование файлового редактора требует только одного из- менения в конструкторе редактора, но для лучшего использование объектов редакторов файлов вы должны понимать некоторые концеп- ции. Эта глава охватывает следующие темы: - построение редактора файла; - работа с файлами; - работа с буферами. *- Построение редактора файлов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Конструктор файлового редактора почти идентичен конструктору обычного редактора, но вместо задания в качестве последнего пара- метра размера буфера вы передаете имя файла, который хотите ре- дактировать. Редактор файлов будет устанавливать свой собственный буфер (как описывается ниже в разделе "Работа с буферами"). Файловый редактор сохраняет имя текущего файла в поле с име- нем FileName. Если вы передаете в качестве имени файла пустую строку, то редактор файлов предполагает, что вы создаете новый файл. Если в глобальной переменной EditorFlags установлен бит efBackupFiles, редактор файлов автоматически сохраняет копию пос- ледней сохраненной версии редактируемого файла (с расширением, измененным на .BAK). *- Работа с файлами ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Очевидным различием файлового редактора и стандартного ре- дактора является тот факт, что редактор файлов должен обслуживать соответствующий файл. В основном при построении и уничтожении объекта это происходит прозрачно, но если вы хотите настроить по- ведение объекта, вам потребуется некоторое знание деталей по сле- дующим темам: - загрузка файла; - сохранение файла; - обеспечение сохранения изменений. *- Загрузка файла ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы передаете конструктору файлового редактора имя фай- ла, объект проверяет, представляет ли это имя допустимый файл, а затем вызывает метод LoadFile для назначения буфера и считывания содержимого этого файла в буфер редактора. Если файл для редакто- ра слишком велик, или редактор не может выделить буфер достаточ- ного размера, то редактор файлов выводит диалоговое окно "Out of memory" ("Нет памяти"), а LoadFile возвращает значение False. В общем случае в любой другой момент вызывать LoadFile не следует. Если вы хотите загрузить в редактор файлов другой файл, то уничтожить существующий редактор и построить вместо него но- вый. Этим обеспечивается допустимость связи между именами файлов и буферами редакторов и правильное управление буферной памятью. *- Сохранение файла ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Кроме команд редактирования, понятных всем объектам редакто- ра, файловые редакторы реагируют две дополнительные команды: cmSave и cmSaveAs. В ответ на эти команды обработчик событий TFileEditor вызывает методы Save и SaveAs соответственно. Метод UpdateCommands объекта TFileEditor вызывает наследуемый метод UpdateCommands, а затем разрешает cmSave и cmSaveAs. Основное отличие между Save и SaveAs в том, что Save предпо- лагает сохранение текущего буфера редактирование в файле под име- нем FileName, а SaveAs подразумевает, что вы хотите назначить но- вый файл. Если FileName - это пустая строка, то Save вызывает SaveAs для присваивания файлу нового имени. Фактическое сохранение текста файла выполняется методом SaveFile SaveFile никогда не следует вызывать непосредственно. Пользуйтесь вместо этого методами Save и SaveAs. Если в EditorFlags установлен бит efBackupFile, SaveFile берет на себя сохранение копий файлов, а затем записывает содержимое буфера ре- дактора в файл с именем FileName. *- Обеспечение сохранения изменений ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если пользователь или другой объект пытаются закрыть редак- тор файла, в котором еще не сохранены изменения (то есть поле Modified) имеет значение True), то метод Valid файлового редакто- ра выводит пользователю диалоговое окно с предупреждением, что модификации нуждаются в изменении или игнорировании. Затем поль- зователь может либо сохранить изменения, либо отменить закрытие редактора (возвращая в методе Valid False). *- Работа с буферами ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Файловым редакторам требуется в их работе с буферами что-то более гибкое, чем большинству редакторов, поэтому вместо выделе- ния памяти для буферов файлового редактора в динамически распре- деляемой области Turbo Vision пространство буфера редактирования файла над динамически распределяемой областью памяти. Это позво- ляет увеличивать размер буферов редактирования файлов, сокращать и перемещать их. Большая часть работы с буферами происходит авто- матически, но вы должны задать, сколько памяти вы хотите зарезер- вировать в своем приложении. Заметим, что то что вы задаете - это размер обычно динами- чески распределяемой области памяти Паскаля, и для ваших файловых редакторов вся остальная память остается доступной. Этим обеспе- чивается то, что ваше приложение всегда получает необходимый объ- ем памяти, а файловые редакторы совместно используют остальное. *- Задание памяти для буфера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В модуле Editor описана глобальная переменная с именем MaxHeapSize, которую вы можете установить, если ваше приложение использует файловые редакторы. По умолчанию MAxHeapSize имеет значение 640К. Это означает, что динамически распределяемая об- ласть памяти вашего приложения получает всю доступную память, и для буферов редактора файла доступной памяти не остается. Если вы используете редактор файла, не зарезервировав память для буфера, это приведет к сбою программы и, возможно, зависанию системы. При работе с переменной MaxHeapSize вы должны учитывать два момента: * Она задает размер динамически распределяемой области памя- ти вашего приложения в 16-байтовых параграфах. Память все этого объема недоступна в остальной части вашего приложе- ния, поэтому убедитесь в выделении достаточного объема. Например, установка MaxHeapSize в значение 4096 резервиру- ет для динамически распределяемой области памяти приложе- ния 64К, а все остальное остается для буферов файлового редактора. * Вы должны установить значение MaxHeapSize перед распреде- лением какой-либо памяти в динамически распределяемой об- ласти. Надежнее всего сделать это в первом оператор конс- труктора объекта приложения перед вызовом наследуемого конструктора: consctuctor TMyApp.Init; begin MaxHeapSize := 4096; { должно следовать первым } inherited Init; { это распределяет память } end; *- Обслуживание буферов редактора файла ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД У вас никогда не должно возникать необходимости в самостоя- тельной работе с буфером файлового редактора. TFileEditor переоп- ределяет виртуальные методы DoneBuffer, InitBuffer и SetBufSize для обеспечения того, что редактор использует вместо пространства динамически распределяемой области пространство файлового буфера. Буферы файлового редактора выделяются с 4-килобайтовых при- ращением. То есть, когда LoadFile запрашивает для своего файла буфер, он передает в SetBufSize размер буфера, и производится попытка выделить именно это число байта с округлением до ближай- шей 4-килобайтовой границы. Если размер промежутка редактора сок- ращается до нуля, то буфер файла наращивается при наличии дос- тупной памяти по 4К. *- Использование буфера вырезанного текста ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Все объекты редакторов Turbo Vision поддерживают вырезание, копирование и вставку из буфера вырезанного изображения (текста), но для использования данных средств вы должны создать объект бу- фера вырезанного текста. В качестве редактора буфера вырезанного текста можно использовать любой редактор, но чаще всего это неи- менованный файловый редактор в окне редактирования, так что вы можете легко выводить и редактировать буфер вырезанного текста. Использование буфера вырезанного текста требует в вашем при- ложении только двух дополнительных шагов: - построения редактора буфера вырезанного текста; - присваивания редактора переменной Clipboard. *- Построение редактора буфера вырезанного текста ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В качестве буфера вырезанного текста приложения вы можете использовать любой объект редактора Turbo Vision, но нужно обес- печить доступность буфера вырезанного текста в любой момент. В общем случае это означает наличие отдельного редактора, выделен- ного для буфера вырезанного текста. Использование для буфера вы- резанного текста файлового редактора дает вам преимущество гибко- го размера и позволяет избежать необходимости постоянного выделе- ния большой части динамически распределяемой области памяти ваше- го приложения. *- Присваивание переменной Clipboard ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Модуль Editors описывает глобальную переменную с именем Clipboard типа PEditor, которой ваше приложение должно присваи- вать редактор буфера вырезанного текста, если вы собираетесь ис- пользовать операции с буфером вырезанного текста. Если они знают, что работают с буфером вырезанного текста, файловые редакторы ве- дут себя несколько по-другому, и операции вырезания, копирования и вставки допустимому объекту редактора не присваиваются. Следующий пример показывает типичное создание буфера выре- занного текста и присваивание его редактора переменной Clipboard. type TMyApp = object(TApplication) ClipWindow: PEditWindow; constructor Init; . . . end; constructor TMyApp.Init; begin MaxHeapSize := 4096; { допускает для файловых редакторов использование 64К } inherited Init; { построение приложения } New(ClipWindow, Init(R, '', wmNoNumber)); { построить окно } if ValidView(CLipWindow) <> nil then { если это допустимое окно } Clipboard := ClipWindow^.Editor; { создать редактор буфера вырезанного текста } end; *- Использование окна редактора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно редактора (типа TEditWindow) - это оконный объект, спроектированный для размещения файлового редактора. Оно изменяет свой заголовок для вывода имени редактируемого файла и устанавли- вает для редактора полосы прокрутки и индикатор прокрутки. Окно редактора сохраняет указатель на соответствующий редактор в поле Editor. *- Построение окна редактора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Построение окна редактора в точности аналогично построению любого другого окна, за исключением того, что второй передавае- мый конструктору параметр - это имя редактируемого файла. Заголо- вок окна отражает редактируемый файл: это 'Clipboard', если ре- дактором является редактор буфера вырезанного текста приложения, или 'Untitled', если имя файла представляет собой пустую строку. В противном случае это полное имя маршрута файла. *- Другие соглашения по окну редактора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Имеется только два других момента, когда окно редактора ве- дет себя отлично от простого окна. Это его поведение при закрытии и реакция на команду оповещения. При указании на закрытие окно редактора будет закрываться аналогично любому другому окну (включая вызов метода Valid для всех своих отображаемых подэлементов), если только окно не содер- жит буфер вырезанного текста. В последнем случае оно не закрыва- ется, а становится скрытым. Это позволяет вам редактировать буфер вырезанного текста в окне, не теряя его каждый раз, когда вы зак- рываете окно. Окна редактора реагируют на командное событие оповещения, которое обычным окнам обрабатывать не нужно. Когда имя файла в редакторе изменяется (обычно после операции Save As), окно полу- чает событие оповещения с командой UpdateTitle, которая предуп- реждает окно, что оно нуждается в новом отображении и включении в рамку нового имени файла. *- ГЛАВА 16. Наборы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Программисты, работающие на языке Паскаль, обычно тратят очень много времени на создание кода по манипулированию и обеспе- чению структур данных, таких как связанные списки и массивы с ди- намической установкой размеров. И очень часто один и тот же код имеет тенденцию к повторному переписыванию и отладке. Что касается традиционного языка Паскаль, он лишь предостав- ляет вам встроенные типы записи и массива. Все другие структуры остаются на ваше усмотрение. Например, если вы собираетесь хранить данные в массиве, то обычно вам нужно написать код для создания массива, импорта дан- ных в массив, получение данных массива для обработки, и, возмож- но, вывода данных на устройство ввода-вывода. Позднее, когда пот- ребуется новый тип элемента массива, вы начинаете все сначала. Было бы замечательно, если бы тип массива поставлялся вместе с кодом, обрабатывающего бы многие из тех операций, которые обыч- но выполняются с массивом. Это был бы тип массива, который можно было бы расширять без нарушения первоначального кода. Все это яв- ляется целью создания типа Turbo Vision TCollection. Это объект, который хранит наборы указателей и обладает набором методов по манипулированию ими. *- Объекты наборов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Будучи объектами и тем самым имея встроенные методы, наборы обладают двумя дополнительными чертами, которые имеют отношение к обычным массивам языка Паскаль - это динамическое установка раз- меров и полиморфизм. *- Динамическая установка размеров наборов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Размер стандартного массива в стандартном Паскале фиксирует- ся во время компиляции. Хорошо, если вы точно знаете, какой раз- мер должен иметь ваш массив, но это может быть не столь хорошо к тому моменту, когда кто-нибудь будет запускать на вашу программу. Изменение размера массива требует изменения исходного кода и пе- рекомпиляции. Однако, для наборов вы устанавливаете только их начальный размер, который динамически увеличивается в процессе работы прог- раммы, для размещения в нем всех нужных данных. Это делает ваше приложение в его скомпилированном виде значительно более гибким. Тем не менее, следует иметь в виду, что набор не может сжиматься, поэтому следует быть аккуратным и не делать его неоправданно большим. *- Полиморфизм наборов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Второй аспект, по которому массивы могут ограничивать ваше приложение, состоит в том, что каждый элемент массива должен иметь один и тот же тип, и этот тип должен быть определен при компиляции кода. Наборы обходят это ограничение использованием нетипизирован- ных указателей. Это сказывается не только на быстроте и эффектив- ности, но наборы могут состоять из объектов (и даже не из объек- тов) разного типа и размера. Набору не нужно знать что-либо об объектах, которые он обрабатывает. Он просто организует связь с ними в случае необходимости. *- Проверка типа и наборы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Наборы ограничивают традиционную мощную проверку типа языка Паскаль. Это означает, что можете поместить нечто в набор и когда запрашиваете это назад, компилятор уже не может проверить ваших предположений относительно объекта. Вы можете поместить нечто как PHedgehog (еж), а прочитать назад как PSheep (овца), и набор ни- как не сможет насторожить вас. Как программист, работающий на языке Паскаль, вы вполне оп- равданно будете нервничать по поводу результатов. Проверка типов языка Паскаль в конце концов сберегает несколько часов при поиске некоторых достаточно иллюзорных ошибок. Поэтому вы должны принять во внимание следующее предупреждение. Вы даже представить себе не можете насколько трудно бывает искать ошибки несоответствия типа, поскольку обычно эту работу за вас выполнял компилятор! Однако, если вы обнаружите, что ваша программа сбивается или зацикливает- ся, тщательно проверьте хранимые типы объектов и считываемые из наборов. *- Объединение в набор элементов, не являющихся объектами ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Вы даже можете добавить в набор нечто, что вообще не являет- ся объектом, но это также может явиться серьезным предметом оза- боченности. Наборы ожидают получения нетипизированных указателей незаданного типа на нечто. Но некоторые методы TCollection пред- назначены специально для работы с наборами элементов, производных от TObject. Это касается методов доступа к потоку PutItem и GetItem, и стандартной процедуры FreeItem. Например, это означает, что вы можете хранить PChar в набо- ре, но при попытке послать этот набор в поток, результаты будут не столь успешными, если вы не перепишете стандартные методы на- бора GetItem и PutItem. Аналогично, при попытке освобождения на- бора будет сделана попытка удаления каждого элемента с помощью FreeItem. Например, это делает TStrCollection. Если вам удастся преодолеть все эти трудности, вы обнаружи- те, что наборы (и построенные вами производные наборов) являются быстрыми, гибкими и надежными структурами данных. *- Создание набора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Создание набора столь же просто, как и создание типа данных, которые вы хотите в нем хранить. Предположим, что вы - консуль- тант, и вам нужно хранить и искать номер счета, фамилию и номер телефона каждого из ваших клиентов. Сначала определим тип объекта клиента (TClient), который будет хранится в наборе (не забудьте определить тип указателя для каждого нового типа объекта): type PClient=^TClient; TClient=object(TObject) Account, Name, Phone: PChar; constructor Init(NewAccount, NewName, NewPhone: PChar); destructor Done; virtual; procedure Print; virtual; end; Затем реализуем методы Init и Done для размещения и удаления данных о клиенте и метод Print для отображения данных о клиенте в виде таблицы. Обратите внимание, что поля объекта имеют тип PChar, поэтому память выделяется только для той части строки, ко- торая действительно используется. Функции StrNew и StrDispose очень эффективно обрабатывают динамические строки. constructor TClient.Init(NewAccount, NewName, NewPhone: PChar); begin Account := StrNew(NewAccount); Name := StrNew(NewName); Phone := StrNew(NewPhone); end; destructor TClientDone; begin StrDispose(Account); StrDispose(Name); StrDispose(Phone); end; procedure TClient.Print; begin Writeln( ' ', Account, '':10 - StrLen(Account), Name, '':20 - StrLen(Name), Phone, '':16 - StrLen(Phone)); end; TClient.Done будет автоматически вызываться для каждого кли- ента при удалении всего набора. Сейчас вы просто инициируете на- бор для хранения ваших клиентов и вставляете в него записи о кли- ентах. Основное тело программы (COLLECT1.PAS) будет выглядеть следующим образом: var ClientList: PCollection; begin ClientList:=New(PCollection, Init(10,5)); with ClientList^ do begin Insert(New(PClient, Init('91-100', 'Anders, Smitty', '(406) 111-2222'))); Insert(New(PClient, Init('90-167', 'Smith, Zelda', '(800) 555-1212'))); Insert(New(PClient, Init('90-177', 'Smitty, John', '(406) 987-4321'))); Insert(New(PClient, Init('90-160', 'Johnson, Agatha', '(302) 139-8913'))); end; PrintAll(ClientList); SearchPhone(ClientList, '(406)'); Dispose(ClientList, Done); end. Примечание: Процедуры PrintAll и SearchPhone будут рассмотрены позднее. Обратите внимание, насколько просто было построить набор. Первый оператор размещает новый экземпляр TCollection с именем ClientList с начальным размером на 10 клиентов. В случае необхо- димости размещения более 10 клиентов в ClientList, его размер бу- дет увеличиваться каждый раз на 5 клиентов. Следующие два опера- тора создают новый объект клиента и вставляют его в набор. Вызов Dispose в конце операции освобождает весь набор клиентов. Нигде не нужно было сообщать набору, какой вид данных пред- полагается хранить - для этого просто используется указатель. *- Методы итератора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Вставка и удаление элемента не являются единственными общими операторами набора. Очень часто вы будете писать циклы for для просмотра всех объектов набора с целью отображения данных или вы- полнения некоторых вычислений. В других случаях вы будете искать первый или последний элемент набора, который удовлетворяет неко- торому критерию поиска. Для этих целей у наборов имеется три ме- тода итератора: ForEach, FirstThat и LastThat. Каждый из них воспринимает указатель на процедуру или функцию в качестве своего единственного параметра. *- Итератор ForEach ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД ForEach воспринимает указатель на процедуру. Процедура имеет один параметр, который является указателем на хранимый в наборе элемент. Для каждого элемента набора ForEach вызывает процедуру один раз, в той последовательности, в которой элементы появляются в наборе. Процедура PrintAll в Collect1 показывает пример итера- тора FoeEach. procedure PrintAll(C: PCollection); { печать информации по всем клиентам } procedure CallPrint(P: PClient); far; { локальная процедура } begin with P^ do Writeln(Account^, '':20-Length(Account^), { вывод инфор- мации о клиенте } Name^, '':20-Lenght(Name^), Phone^, '':20-Lenght(Name^)), end; { конец локальной процедуры } begin {Print} Writeln; Writeln; Writeln('Client list:'); C^.ForEach(@CallPrint); { распечатка PrintClient для каждого элемента в C } end; Для каждого элемента набора, переданного в качестве парамет- ра в PrintAll, вызывается вложенная процедура CallPrint. CallPrint просто распечатывает информацию об объекте клиента в отформатированных колонках. Примечание: Итераторы должны вызывать локальные проце- дуры far. Вам нужно быть аккуратным с сортировкой процедур, которые вы вызываете итераторами. Для того, чтобы быть вызванной итератором, процедура (в данном примере, CallPrint) должна быть локальной процедурой (вложенной в тот же блок) и не может быть функцией или методом объекта, хотя данный пример показывает, что процедура мо- жет вызвать метод. Она также должна описываться как дальняя про- цедура директивой far или директивой компилятора {$F+}. Наконец, процедура должна воспринимать в качестве единственного параметра указатель на элемент набора в качестве своего единственного пара- метра. *- Итераторы FirstThat и LastThat ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Кроме возможности приложения процедуры к каждому элементу набора, часто бывает очень нужно найти конкретный элемент набора на основании некоторого критерия. Это является предназначением итераторов FirstThat и LastThat. Как это следует из их имен, они просматривают набор в противоположных направлениях до момента на- хождения первого элемента набора, который удовлетворяет критерию булевской функции, переданной в качестве элемента. FirstThat и LastThat возвращают указатель на первый (или последний) элемент, который удовлетворяет условию поиска. Предпо- ложим, что в приведенном ранее примере списка клиентов, вы не мо- жете вспомнить номер счета клиента или не помните точно написание имени клиента. К счастью, вы точно помните, что это был ваш пер- вый клиент из штата Монтана. Следовательно, вы можете организо- вать поиск первого клиента с кодом штата 406 (поскольку ваш спи- сок клиентов ведется хронологически). Данная процедура использует метод FirstThat, который и сделает всю работу: procedure SearchPhone(C: PCollection; PhoneToFind: PChar); function PhoneMatch(Client: PClient: PClient): Boolean; far; begin PhoneMatch := Pos(PhoneToFind, Client^.Phone^) <> 0; end; var FoundClient: PClient; begin FoundClient := C^.FirstThat(@PhoneMatch); if FoundClient = nil then Writeln('Такому требованию не отвечает ни один клиент') else with FoundClient^ do Writeln('Найден клиент:', Account^, ' ', Name^, ' ', Phone^); end; Снова обратите внимание на то, что PhoneMatch вложена и ис- пользует удаленную модель вызова. В этом случае эта функция возв- ращает True только при совпадении номера телефона клиента и за- данного образца поиска. Если в наборе нет объекта, который соот- ветствовал бы критерию поиска, FirstThat возвращает указатель nil. Запомните: ForEach вызывает определенную пользователем про- цедуру, а FirstThat и LastThat каждая вызывает определенную поль- зователем булевскую функцию. В любом случае определенная пользо- вателем процедура или функция передают указатель на объект набо- ра. *- Отсортированные наборы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Иногда вам бывает нужно, чтобы ваши данные были определенным образом отсортированы. Turbo Vision имеет специальный тип набо- ра, который позволяет вам упорядочить свои данные произвольным образом. Это тип TSortedCollection. TSortedCollection является производным от TCollection и ав- томатически сортирует задаваемые ему объекты. При добавлении но- вого элемента он автоматически проверяет набор на дублирование ключей. Булевское поле Duplicates контролирует разрешение дубли- рования ключей. Если для поля Duplicates установлено значение False (по умолчанию), то новый элемент добавляется к набору, за- меняя существующий член с тем же самым ключом. Если Duplicates имеет значение True, то новый член просто вставляется в набор. TSortedCollection - это набор абстрактного типа. Для его ис- пользования вы должны сначала решить, какой тип данных вы собира- етесь собирать и определить два метода, отвечающих вашим конкрет- ным требованиям сортировки. Для этого вам нужно создать новый тип, производный от TSortedCollection. В данном случае назовем его TClientCollection. Ваш TClientCollection уже знает, как делать всю реальную ра- боту с набором. Он может вставить (Insert) запись о новом клиенте и удалять (Delete) существующие записи - он унаследовал эти ос- новные черты поведения от TCollection. Все что нужно сделать - это научить TClientCollection, какое поле использовать в качестве ключа сортировки и как сравнивать двух клиентов при решении воп- роса о том, какой из них должен стоять в наборе выше другого. Это делается переписыванием методов KeyOf и Compare и реализации их следующим образом: PClientCollection = ^TClientCollection; TClientCollection = object(TSortedCollection) function KeyOf(Item: Pointer): Pointer; virtual; function Compare(Key1, Key2: Pointer): Integer; virtual; end; function TClientCollection.KeyOf(Item: Pointer): Pointer; begin KeyOf := PClient(Item)^.Account; end; function TClientCollection.Compare(Key1, Key2: Pointer): Integer; begin if PString(Key1)^ < PString(Key2) then Compare := 0; { возвращает 0, если равно } else if PString(Key1)^ < PString(Key2)^ then Compare := -1; { возвращает -1, если первым следует Key1 } else Compare := 1; { в противном случае возвращает 1, первым следует Key2 } end; Примечание: Так как ключи являются нетипизированными указателями, для них нужно выполнять приведение типа. KeyOf определяет, какое поле или поля используются в качест- ве ключей сортировки. В данном случае это поле клиента Name. Compare воспринимает два ключа сортировки и определяет, какой из них должен идти первым в соответствии с правилами сортировки. Compare возвращает -1, 0 или 1 в зависимости от того, Key1 мень- ше, равен или больше Key2, соответственно. В данном примере ис- пользуется сортировка по алфавиту (для букв верхнего и нижнего регистра) ключевой строки (Name). Обратите внимание на то, что ключи, возвращаемые KeyOf и пе- редаваемые в Compare являются нетипизированными указателями, поэ- тому до их разыменования и передачи в PString. Это практически все, что вам нужно определить! Теперь, если вы переопределите ClientList как PClientCollection вместо PCollection (сменив объявление var и вызов New), то легко сможете распечатать ваших клиентов в алфавитном порядке (см. пример прог- раммы COLLECT2.PAS): var ClientList: PClientCollection; . . begin ClientList := New(PClientCollection, Init(10,5)); . . end. Обратите внимание и на то, как легко будет сменить сортиров- ку списка клиентов по номеру счета на сортировку по имени. Все что вам нужно сделать, это сменить метод KeyOf на возврат поля Account на поле Name. *- Наборы строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Многим программам требуется работать с отсортированными строками. Для этих целей Turbo Vision предоставляет набор специ- ального назначения TStrCollection (он совпадает с типом TStringCollection, определенным для хранения строк Паскаля). Об- ратите внимание, что элементы TStrCollection - это не объекты. Они представляют собой указатели на строки, заканчивающиеся ну- лем. Поскольку наборы строк происходят от TSortedCollection, мож- но хранить и дублированные строки. Использовать наборы строк несложно. Просто определяется пе- ременная указателя для хранения набора строк. Разместим набор, задав его начальный размер и приращение для роста при добавлении новых строк (см. программу COLLECT3.PAS): var WordList: PCollection; WordRead: PChar; . . . begin WordList := New(PStrCollection, Init(10, 5)); . . . WordList первоначально рассчитан для хранения 10 строк с последующим приращением по 5 строк. Все что вам нужно сделать - это вставить несколько строк в набор. В данном примере слова счи- тываются из текстового файла и вставляются в набор: repeat . . . if GetWord(WordRead, WordFile)^ <> #0 then WordList^.Insert(NewStr(WordRead)); . . . until WordRead = ''; . . . Dispose(WordList, Done); Обратите внимание, что функция NewStr используется для копи- рования считанных слов, и адрес скопированной строки передается в набор. При использовании набора вы всегда передаете ему контроль над данными набора. Он позаботится об освобождении данных после работы. Он при этом делает то, что происходит при вызове Dispose: удаляется каждый элемент набора, и затем удаляется сам набор WordList. *- Пересмотренные итераторы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Метод ForEach просматривает весь набор, элемент за элемен- том, и выполняет над каждым из них заданную процедуру. В предыду- щем примере процедуре PrintWord передавался указатель строки для ее отображения. Обратите внимание, что процедура PrintWord вло- женная (или локальная). Она работает в другой процедуре, Print, которой передается указатель на TstrCollection. Print использует метод итератора ForEach для передачи каждого элемента своего на- бора в процедуру PrintWord. procedure Print(C: PCollection); procedure PrintWord(P: PString); far; begin Writeln(P^); { вывести строку } end; begin { печать } Writeln; Writeln; C^.ForEach(@PrintWord); { вызов PrintWord } end; PrintWord должен выглядеть как уже знакомая процедура. Она просто берет указатель строки и передает его значение Writeln. Обратите внимание на директиву far после описания PrintWord. PrintWord не может быть методом, это просто процедура. Кроме того это должна быть вложенная процедура. Print надо рассматривать как некую оболочку вокруг процедуры, которая выполняет некоторую ра- боту над каждым элементом набора (может быть отображает или моди- фицирует данные). Вы можете иметь несколько аналогичных PrintWord процедур, но каждая из них должна быть вложена в Print и должна быть дальней процедурой (использовать директиву far или {$F+}). *- Нахождение элемента ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Отсортированные наборы (и следовательно наборы строк) имеют метод Search, который возвращает индекс элемента с конкретным значением ключа. Но как найти элемент в неотсортированном наборе? Или когда критерий поиска не использует сам ключ? Конечно же, следует использовать FirstThat и LastThat. Вы просто определяете булевскую функцию для проверки нужного вам критерия и вызываете FirstThat. *- Полиморфические наборы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Как вы уже видели, что наборы могут динамически хранить лю- бой тип данных и они обладают множеством методов, которые помога- ют вам организовывать эффективный доступ к данным. В действитель- ности сам TCollection определяет 23 метода. Когда вы используете наборы в ваших программах, вы будете удивлены скоростью их рабо- ты: они разработаны с максимальной гибкостью и реализованы для использования с максимальной скоростью. Теперь пришло время рассмотреть реальные возможности набо- ров, элементы могут обрабатываться полиморфически. Это значит, что вы не просто можете хранить определенный тип объекта в набо- ре; вы можете хранить несколько разных типов объектов, взятых произвольно из вашей иерархии объектов. Если вы рассмотрите приведенные примеры наборов, вы можете заметить, что все элементы каждого набора были одно и того же ти- па. Мы имели дело со списком строк в котором каждый элемент был строкой. Мы также занимались списком клиентов. Но наборы могут хранить любые производные от TObject объекты, и вы можете произ- вольно смешивать эти объекты. Естественно, что вы желаете, чтобы эти объекты имели нечто общее. На самом деле вам нужно, чтобы у них был общий абстрактный объект-предок. В качестве примера рассмотрим программу, которая помещает в набор три различных графических объекта. Затем итератор ForEach используется для просмотра набора и отображения каждого объекта. Данный пример использует модуль Graph и драйверы BGI, поэто- му убедитесь, что в текущем каталоге или по маршруту модулей (OptionsіDirectoriesіUnit Directory) при компиляции находится GRAPH.TPU. При запуске программы измените его на каталог, содер- жащий драйверы .BGI, или модифицируйте вызов InitGraph, задав их расположение (например, C:\TP\BGI). Сначала определяется абстрактный объект-предок (см. программу COLLECT4.PAS). type PGraphObject = ^TGraphObject; TGraphObject = object(TObject) X,Y: Integer; constructor Init; procedure Draw; virtual; end; Из этого описания вы можете видеть, что каждый графический объект может инициализировать себя (Init) и отобразить себя на графическом экране (Draw). Теперь определим точку, круг и прямоу- гольник как производные от этого общего предка: PGraphPoint = ^TGraphPoint; TGraphPoint = object(TGraphObject) procedure Draw; virtual; end; PGraphCircle = ^TGraphCircle; TGraphCircle = object(TGraphObject) Radius: Integer; constructor Init; procedure Draw; virtual; end; PGraphRect = ^TGraphRect; TGraphRect = object(TGraphObject) Width, Height: Integer; constructor Init; procedure Draw; virtual; end; Все эти три типа объекта наследуют поля X и Y из PGraphObject, но все они разного размера. PGraphCircle добавляет Radius, а PGraphRect - Width и Height. Приведем исходный код для помещения этих фигур в набор: . . . GraphicsList := New(PCollection, Init(10,5)); { создать набор } for I := 1 to NumToDraw do begin case I mod 3 of { создать объект } 0: P := New(GraphPoint, Init); 1: P := New(GraphCircle, Init); 2: P := New(GraphRect, Init); end; List^.Insert(P); { добавить в набор } end; . . . Как вы можете видеть цикл, for вставляет графические объекты в набор List. Вы знаете только то, что каждый объект в List представляет собой некоторый вид TGraphObject. После помещения в набор у вас уже нет информации о том, является ли элемент набора прямоугольником, эллипсом или сектором. Благодаря полиморфизму, вам этого и не нужно знать, поскольку каждый объект содержит все данные и код (Draw), который ему нужен. Просмотрим набор с ис- пользованием итеративного метода и каждый набор будет сам отобра- жать себя: procedure DrawAll(C: PCollection); procedure CallDraw(P: PGraphObject); far; begin P^.Draw; { вызов метода Draw } end; begin { DrawAll } C^.ForEach(@CallDraw); { нарисовать каждый объект } end; var GraphicsList: PCollection; begin . . . DrawAll(GraphicsList); . . . end. Способность наборов хранить разные, но связанные объекты ос- новывается на мощном краеугольном камне объектно-ориентированного программирования. В следующей главе вы увидите тот же принцип по- лиморфизма, примененный к потокам с равными приоритетами. *- Наборы и управление памятью ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TCollection может динамически расти от начального размера, установленного Init, до максимального размера в 16380 элементов. Turbo Vision хранит максимальный размер набора в переменной MaxCollectionSize. Каждый добавляемый в набор элемент занимает четыре байта памяти, т.к. он хранится в виде указателя. Ни одна библиотека динамических структур данных не будет полной, если она не снабжена средствами обнаружения ошибок. Если для инициализации набора не хватает памяти, то возвращается ука- затель nil. Если не хватает памяти при добавлении элемента в набор, то вызывается метод TCollection.Error, и возникает ошибка этапа вы- полнения в динамически распределяемой области памяти. Вы можете переписать TCollection.Error для организации собственного метода информирования или исправления ошибки. Вам следует уделить особое внимание доступности динамической области памяти, поскольку у пользователя имеет значительно боль- ший контроль над программой Turbo Vision, чем над обычной прог- раммой языка Паскаль. Если добавлением объектов в набор управляет пользователь (например, открывая новое окно), то ошибку динами- ческой области памяти не так то легко предсказать. Вы можете предпринять некоторые шаги по защите пользователя от фатальной ошибки при выполнении программы либо проверяя память при исполь- зовании набора, либо обрабатывая сбой выполняемой программы таким образом, чтобы избежать прекращения ее работы. *- ГЛАВА 17. Потоки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Техника объектно-ориентированного программирования и Turbo Vision дают вам мощные средства инкапсуляции кода и данных и большие возможности построения взаимосвязанных структур объектов. Но что делать, если стоит простая задача, например, по хранению некоторых объектов на диске? Когда-то данные хранились исключительно в записях, и помеще- ние данных на диск было тривиальной задачей. Но данные в програм- мах Turbo Vision неразрывно связаны с объектами. Конечно, вы мо- жете отделить данные от объекта и записать их в дисковый файл. Объединение дает вам значительный шаг в направлении прогресса, а разъединение отбрасывает вас назад. Есть ли в самом объектно-ориентированном программировании и Turbo Vision некоторые средства, которые могли бы разрешить эту проблему? Есть, и это потоки. Поток в Turbo Vision - это набор объектов на их пути ку- да-либо: обычно в файл, EMS, в последовательный порт или некото- рое другое устройство. Потоки обслуживают операции ввода-вывода на уровне объектов, а не на уровне данных. При расширении объекта Turbo Vision вам нужно обеспечить обработку определенных вами дополнительных полей. Все сложные аспекты обработки на уровне объектов будут проделаны за вас. *- Вопрос: объектный ввод-вывод ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Поскольку вы пишете программы на языке Паскаль, то знаете, что до выполнения операций ввода-вывода с файлом, вы сначала должны сообщить компилятору, какой тип данных вы будете писать и считывать из файла. Файл должен иметь тип, и этот тип должен быть установлен во время компиляции. Паскаль реализует в этой связи очень удобное правило: можно организовать доступ к файлу неопределенного типа с помощью процедур BlockWrite и BlockRead. Отсутствие проверки типа возла- гает некоторую дополнительную ответственность на программиста, хотя позволяет очень быстро выполнять двоичные операции ввода-вы- вода. Вторая проблема состоит в том, что вы не можете непосредс- твенно использовать файлы с объектами. Паскаль не позволяет вам создавать файл с объектным типом. Объекты могут содержать вирту- альные методы, адреса которых определяются в процессе выполнения программы, поэтому хранение информации о виртуальных методах вне программы лишено смысла, еще более бессмысленно считывать эту ин- формацию в программу. Но эту проблему снова можно обойти. Вы можете выделить дан- ные из ваших объектов и записать эту информацию в какой-то файл некоторого вида, а уже позднее восстановить объекты из этих ис- ходных данных. Подобное решение, однако, будет недостаточно эле- гантным и существенно усложняет конструирование объектов. *- Ответ: потоки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Turbo Vision позволяет обойти все эти трудности и даже су- лит вам получение некоторых дополнительных выгод. Потоки дают вам простое, но изящное средство хранение данных объекта вне вашей программы. *- Полиморфизм потоков ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Потоки Turbo Vision позволяют вам работать с файлами опре- деленного и неопределенного типа: проверка типа имеется, но тип посылаемого объекта не должен обязательно определяться во время компиляции. Смысл в том, что потоки знают, что они имеют дело с объектами, и поскольку все объекты являются производными от TObject, поток может их обработать. В действительности различные объекты Turbo Vision могут также легко записываться в один по- ток, как и группы идентичных объектов. *- Потоки обрабатывают объекты ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Все что вам нужно сделать - это определить для потока, какие объекты ему нужно будет обрабатывать, чтобы он знал, как согласо- вывать данные с таблицами виртуальных методов. Затем без ка- ких-либо усилий вы можете помещать объекты в поток и извлекать их из потока. Но каким образом один и тот же поток может считывать и запи- сывать такие разные объекты как TCollection и TDialog, даже не зная в момент компиляции, какие типы объектов он будет обрабаты- вать? Это существенно отличается от традиционных операций вво- да-вывода языка Паскаль. В действительности потоки могут обраба- тывать даже новые типы объектов, которые вообще еще не были соз- даны к моменту компиляции потока. Ответом на это является так называемая регистрация. Каждому типу объекта Turbo Vision (или любому новому производному типу объекта) присваивается уникальный регистрационный номер. Этот но- мер записывается в поток перед данными объекта. Затем, при считы- вании объекта из потока, Turbo Vision сначала берет регистраци- онный номер и на его основании узнает, сколько данных нужно счи- тывать и какие таблицы виртуальных методов подключать к данным. *- Смысл использования потоков ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД На фундаментальном уровне вы можете рассматривать потоки как файлы языка Паскаль. В своей основе файл языка Паскаль представля- ет собой последовательное устройство ввода-вывода: вы записываете в него и считываете из него. Поток - это полиморфическое устройс- тво последовательного ввода-вывода, т.е. оно ведет себя, как пос- ледовательный файл, но вы можете считывать и записывать различные типы объектов в каждый момент времени. Потоки (как и файлы Паскаля) можно также просматривать, как устройства ввода-вывода произвольного доступа, искать определен- ное место в файле, считывать данные в этой точке или записывать данные в эту точку, возвращать позицию указателя файла и т.д. Все эти операции можно выполнять с потоками, и они описаны в разделе "Потоки с произвольным доступом". Есть два разных аспекта использования потоков, которыми вам нужно овладеть, и к счастью оба они очень простые. Первый - это установка потока, а второй - считывание и запись файлов в поток. *- Установка потока ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Все что нужно сделать для использования потока - это инициа- лизировать его. Точный синтаксис конструктора Init может быть разным, в зависимости от типа потока, с которым вы имеете дело. Например, если вы открываете поток DOS, вам нужно передать имя файла DOS и режим доступа (только чтение, только запись, чте- ние/запись) для содержащего поток файла. Например, для инициализации буферизированного потока DOS при загрузке набора объектов в программу, все что вам нужно это: var SaveFile: TBufStream; begin SaveFile.Init('COLLECT.DTA', stOpen, 1024); . . После инициализации потока все готово к работе. TStream это абстрактный механизм потока, поэтому вы будет работать не с ним, а с производными от TStream удобными объектами потока. Это будет, например, TDosStream для выполнения дисковых операций ввода-вывода, TBufStream для буферизованных операций ввода-вывода (очень удобен для частых операций считывания или за- писи небольших объемов информации на диск) и TEmsStream для пере- дачи объектов в память EMS (что особенно полезно для реализации быстрых ресурсов). Кроме того, Turbo Vision реализует индексированные потоки с указателем, указывающим место в потоке. Перемещая этот указатель вы можете организовать произвольный доступ в потоке. *- Чтение из потока и запись в поток ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Основной объект потока TStream реализует три главных метода, которые вам нужно четко понимать: Get, Put и Error. Get и Put грубо соответствуют процедурам Read и Write, которые вы использу- ете в обычных операциях ввода-вывода. Error - это процедура, ко- торая вызывается при появлении ошибок потока. *- Метод Put ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Давайте сначала рассмотрим процедуру Put. Общий синтаксис метода Put следующий: SomeStream.Put(PSomeObject); где SomeStream - это некоторый производный от TStream объект, ко- торый был инициализирован, а PSomeObject представляет собой ука- затель на некоторый производный от TObject объект, который заре- гистрирован с потоком. Это все, что вам нужно сделать. Поток мо- жет из таблицы виртуальных методов PSomeObject узнать, какой это тип объекта (предполагается, что тип зарегистрирован), поэтому он знает какой номер идентификатора писать, и сколько после него бу- дет данных. Специальный интерес для вас, как для программиста, работаю- щего с Turbo Vision, состоит в том факте, что при помещении в поток группы с дочерними окнами, дочерние окна также автоматичес- ки помещаются в поток. Таким образом, запись сложных объектов не так уж и сложна, более того, это делается автоматически! Вы може- те сохранить в потоке полное состояние оперативной области. При повторном запуске вашей программы и загрузке диалога будет выве- дено его состояние в момент записи. *- Метод Get ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Считывание объектов из потока столь же просто. Все что вам нужно сделать, это вызвать функцию Get: PSomeObject := SomeStream.Get; где SomeStream - это инициализированный поток Turbo Vision, а PSomeObject - указатель на некоторый тип объекта Turbo Vision. Get просто возвращает указатель на нечто, что он взял из потока. Сколько данных было взято и какой тип таблицы виртуальных методов (VMT) присвоен данным, определяется не типом PSomeObject, а типом объекта, обнаруженным в потоке. Следовательно, если объект в те- кущей позиции SomeStream имеет не совпадающий с PSomeObject тип, у вас будет некорректная информация. Как и Put, Get ищет сложные объекты. Следовательно, если вы ищите в потоке отображаемый элемент, которое владеет отображаемы- ми подэлементами, то они также будут загружены. *- Метод Error ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД И, наконец, процедура Error определяет что происходит при возникновении ошибки потока. По умолчанию TStream.Error просто устанавливает значение двух полей в потоке (Status и ErrorInfo). Если вы хотите сделать что-либо более содержательное, например, чтобы сгенерировать соответствующее сообщение о сбое в работе программы или вывести диалоговое окно c сообщением об ошибке, вам нужно переопределить процедуру Error. *- Закрытие потока ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы закончили использование потока, вы вызываете его метод Done, как вы обычно вызывали Close для дискового файла. Как и для других объектов Turbo Vision, это делается следующим обра- зом: Dispose(SomeStream, Done); как для уничтожения объекта потока, так и для его закрытия. *- Как сделать объекты потоковыми ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Все стандартные объекты Turbo Vision готовы к использованию в потоках, и все потоки Turbo Vision узнают стандартные объекты. При изготовлении нового типа объекта, производного от стандартно- го объекта, его очень просто подготовить к использованию в потоке и известить потоки о его существовании. *- Методы загрузки и записи Load и Store ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Действительное чтение и запись объектов в поток производится методами Load и Store. Каждый объект должен иметь эти методы для использования потока, поэтому вы никогда не будете вызывать их непосредственно (они вызываются из методов Get и Put.) Все что вам нужно сделать, это убедиться в том, что объект знает, как послать себя в поток, когда это потребуется. Благодаря объектно-ориентированному программированию это де- лается очень просто, т.к. большинство механизмов наследуются от объекта-предка. Все что должен делать ваш объект, это загружать и хранить те свои компоненты, которые вы в него добавляете, об ос- тальном позаботится метод предка. Например, вы производите от TWindow новый вид окна с именем художника-сюрреалиста Рене Маг- ритте, который нарисовал много известных картин с окнами: type TMagritte = object(TWindow) Surreal: Boolean; constructor Load(var S: TStream); procedure Draw; procedure Store(var S: TStream); end; Все что было добавлено к данным окна - это одно булевское поле. Для загрузки объекта вы затем просто считываете стандартный TWindow, а затем считываете дополнительный байт булевского поля. Это же относится к записи объекта: вы просто записываете TWindow, а затем записываете еще один байт. Типичные методы Load и Store для производных объектов будут выглядеть следующим образом: constructor TMagritte.Load(var S: Stream); begin inherited Load(S); { загрузка типа } S.Read(Painted, SizeOf(Boolean)); { чтение дополнительных полей } end; procedure TMagritte.Store(var S: Stream); begin inherited Store(S); { сохранение типа } S.Write(Painted, SizeOf(Boolean)); { запись дополнительных полей } end; Вы должны контролировать, что записывается и загружается один и тот же объем данных, и загрузка данных производится в той же последовательности, что и их запись. Компилятор не покажет ошибки. Если вы будете недостаточно аккуратны, то могут возник- нуть серьезные проблемы. Если вы изменяете поля объекта, то нужно изменить и метод Load, и метод Store. *- Регистрация потока ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Кроме определения методов Load и Store для новых объектов, вы также должны зарегистрировать этот новый тип объекта в пото- ках. Регистрация - это простой процесс, который состоит из двух этапов: сначала определяется запись регистрации потока, а затем она передается глобальной процедуре регистрации RegisterType. Для определения записи регистрации потока нужно следовать приводимому ниже формату. Запись регистрации потока это запись языка Pascal типа TStreamRec, которая определяется следующим об- разом: PStreamRec = ^TStreamRec; TStreamRec = record ObjType: Word; VmtLink: Word; Load: Pointer; Store: Pointer; Next: Word; end; По соглашению всем регистрационным записям потока Turbo Vision присваивается то же имя, что и соответствующим ти- пам объектов, но начальное "T" заменяется на "R". Следовательно, регистрационная запись для TDeskTop будет иметь имя RDeskTop. Та- кие абстрактные типы как TObject и TView не имеют регистрационных записей, поскольку их экземпляры вы никогда не будете хранить в потоках. *- Номера идентификаторов объектов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Вам действительно нужно думать только о поле ObjType записи, все остальное делается механически. Каждому новому определяемому вами типу требуется его собственный уникальный идентификатор типа в виде числа. Turbo Vision резервирует регистрационные номера от 0 до 99 для стандартных объектов, поэтому ваши регистрационные номера будут лежать в диапазоне от 100 до 65535. Ответственность за создание и ведение библиотеки номеров идентификаторов для всех ваших новых объектов, которые будут ис- пользоваться в потоках ввода-вывода, ложиться целиком на вас. Нужно сделать эти идентификаторы доступными для пользователей ва- ших модулей. Как и для идентификатора меню и определенных пользо- вателем сообщений, присваиваемые вами числа могут быть произволь- ными, но они должны быть уникальными и попадать в указанный диа- пазон. *- Автоматические поля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Поле VmtLink это связь с таблицей виртуальных методов объек- тов (VMT). Вы просто задаете его как смещение типа вашего объ- екта: RSomeObject.VmtLink := Ofs(TypeOf(TSomeObject)^); Поля Load и Store содержат, соответственно, адреса методов Load и Store. RSomeObject.Load := @TSomeObject.Load; RSomeObject.Store := @TSomeObject.Store; Значение последнего поля, Next, задается RegisterType и не требует никакого вмешательства с вашей стороны. Оно просто обес- печивает внутреннее использование скомпонованного списка регист- рационных записей потока. *- Регистрация на месте ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД После конструирования регистрационной записи потока вы вызы- ваете RegisterType с вашей записью в качестве параметра. Поэтому для регистрации вашего нового объекта TMagritte для его использо- вания в потоке вы включаете следующий код: const RMagritte: TStreamRec = ( ObjType: 100; VmtLink: Ofs(TypeOf(TMagritte)^); Load: @TMagritte.Load; Store: @TMagritte.Store ); RegisterType(RMagritte); Вот и все. Теперь вы можете помещать (Put) экземпляры вашего нового типа объекта в любой поток Turbo Vision и считывать их из потоков. *- Регистрация стандартных объектов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Turbo Vision определяет регистрационные записи потоков для всех ее стандартных объектов. Кроме того, каждый модуль Turbo Vision определяет процедуру RegisterXXXX, которая автоматически регистрирует все объекты этого модуля. *- Механизм потока ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД После того, как мы посмотрели на процесс использования пото- ков, следует заглянуть во внутреннюю работу, которую производит Turbo Vision c вашими объектами с помощью методов Put и Get. Это прекрасный пример взаимодействия объектов и использования встро- енных в них методов. *- Процесс Put ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы посылаете объект в поток с помощью метода Put, по- ток сначала берет указатель VMT со смещением 0 от объекта и прос- матривает список зарегистрированных типов потоков системы с целью найти совпадение. Когда это совпадение найдено, поток ищет ре- гистрационный номер идентификатора объекта и записывает его в по- ток. Затем поток вызывает метод Store объекта для завершения за- писи объекта. Метод Store использует процедуру потока Write, ко- торая действительно пишет корректное число байт по месту назначе- ния потока. Ваш объект не должен ничего знать о потоке - это может быть файл на диске, часть памяти EMS или любой другой вид потока - ваш объект просто говорит "запишите меня в поток", и поток делает все остальное. *- Процесс Get ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы считываете объект из потока с помощью метода Get, сначала ищется номер его идентификатора, и просматривается на совпадение список зарегистрированных типов. После обнаружения совпадения регистрационная запись дает потоку местоположение ме- тода Load объект и VMT. Затем для чтения нужного объема данных из потока вызывается метод Load. Вы опять просто говорите потоку, что нужно взять (Get) сле- дующий объект и поместить его в место, определяемое заданным вами указателем. Ваш объект даже не беспокоится о том, с каким потоком он имеет дело. Поток сам беспокоится о считывании нужного объема данных из потока с помощью метода объекта Load, который в свою очередь опирается на метод потока Read. Для программиста все это достаточно прозрачно, но в то же время вы ясно должны понять, насколько важно зарегистрировать тип до проведения каких-либо попыток ввода-вывода с потоком. *- Обработка указателей объектов со значением nil ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Вы можете записать в поток объект nil. Однако, если это сде- лать, то в поток запишется слово 0. При считывании идентификатора слова 0 поток возвратит указатель nil. Поэтому 0 считается заре- зервированным и не может использоваться в качестве номера иденти- фикатора объекта потока. *- Наборы в потоке: полный пример ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В Главе 16, "Наборы", вы уже видели как наборы могут содер- жать разные, но связанные объекты. Это свойство полиморфизма так- же применимо и к потокам, и их можно использовать для записи на- боров на диск для последующего обращения, даже в другой програм- ме. Вернемся к примеру COLLECT4.PAS. Что еще нужно добавить в эту программу для помещения набора в поток? Ответ будет очень простым. Сначала возьмем базовый объект TGraphObject и "научим" его хранить его данные (X и Y) в потоке. Для этого нужен метод Store. Затем определим новый метод Store для любого производного от TGraphObject объекта, в котором добав- ляются дополнительные поля (например, TGraphCircle добавляет RAdius, TGraphRec - Width и Height). Затем построим регистрацион- ную запись для каждого типа объекта, который предполагается запи- сать, и зарегистрируем все эти типы при первом запуске вашей программы. Вот и все. Остальное будет подобно обычным операциям ввода-вывода в файл: определяется переменная потока; создается новый поток; одним простым оператором весь набор помещается в по- ток, и поток закрывается. *- Добавление методов Store ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Приведем методы Store. Обратите внимание, что для PGraphEllipse и PGraphRect не требуются свои собственные методы, т.к. они не добавляют новых полей к унаследованным от PGraphObject: type PGraphObject = ^TGraphObject; TGraphObject = object(TObject) . . . procedure Store(var S: Stream); virtual; end; PGraphCircle = ^TGraphCircle; TGraphCircle = object(TGraphObject) Radius: Integer; . . . procedure Store(var S: Stream); virtual; end; PGraphRect = ^TGraphRect; TGraphRect = object(TGraphObject) Width, Height: Integer: . . . procedure Store(var S: Stream); virtual; end; PGraphRect = ^TGraphRect; TGraphRect = object(TGraphObject) Width, Height: Integer: . . . procedure Store(var S: Stream); virtual; end; Реализация метода Store вполне очевидна. Каждый объект вызы- вает свой унаследованный метод Store, который хранит все унасле- дованные данные. Затем вызывается метод Write для записи дополни- тельных данных: procedure TGraphObject.Store(var S: TStream); begin S.Write(Rect, SizeOf(X)); S.Write(Rect, SizeOf(Y)); end; procedure TGraphCircle.Store(var S: TStream); begin inherited Store(S); S.Write(Radius, SizeOf(Radius)); end; procedure TGraphRect.Store(var S: TStream); begin inherited Store(S); S.Write(Width, SizeOf(Width)); S.Write(Height, SizeOf(Height)); end; Примечание TGraphObject не вызывает TObject.Store, поскольку TObject не содержит данных для записи. Обратите внимание, что метод TStream Write делает двоичную запись. Его первый параметр может быть переменной любого типа, но TStream.Write не может узнать размеры этой переменной. Второй па- раметр содержит эту информацию, и вы должны придерживаться согла- шения относительно использования стандартной функции SizeOf. Та- ким образом, компилятор всегда может гарантировать, что вы всегда считываете и записываете нужное количество данных. *- Записи регистрации ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Наш последний шаг состоит в определении константы регистра- ционной записи для каждого производного типа. Хороший прием прог- раммирования состоит в следовании соглашению Turbo Vision отно- сительно использования для имени типа идентификатора, где вместо первой буквы T ставится R. Помните о том, что каждой регистрационной записи присваива- ется уникальный номер идентификатора объекта (Objtype). Номера от 0 до 99 резервируются Turbo Vision для стандартных объектов. Хо- рошо бы отслеживать все номера идентификаторов ваших объектов по- тока в некотором центральном месте, чтобы избежать дублирования. const RGraphPoint: TStreamRec = ( ObjType: 150; VmtLink: Ofs(TypeOf(TGraphPoint)^); Load: nil; { метод загрузки пока отсутствует } Store: @TGraphPoint.Store); RGraphCircle: TStreamRec = ( ObjType: 151; VmtLink: Ofs(TypeOf(TGraphCircle)^); Load: nil; { метод загрузки пока отсутствует } Store: @TGraphPoint.Store); RGraphCircle: TStreamRec = ( ObjType: 152; VmtLink: Ofs(TypeOf(TGraphRect)^); Load: nil; { метод загрузки пока отсутствует } Store: @TGraphRect.Store); Вам не нужно регистрационная запись для TGraphObject, так как это абстрактный тип, и он никогда не будет помещаться в набор или в поток. Указатель Load каждой регистрационной записи уста- навливается в nil, поскольку в данном примере рассматривается только помещение данных в поток. В следующем примере методы Load будут определены, и изменены регистрационные записи (см. программу STREAM2.PAS). *- Регистрация ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Всегда нужно зарегистрировать каждую из этих записей до про- ведения каких-либо операций ввода-вывода с потоком. Самый простой способ сделать это состоит в том, чтобы объединить их все в одну процедуру и вызвать ее в самом начале вашей программы (или в ме- тоде Init вашего приложения): procedure StreamRegistration; begin RegisterType(RCollection); RegisterType(RGraphPoint); RegisterType(RGraphCircle); RegisterType(RGraphRect); end; Обратите внимание, что вам нужно зарегистрировать TCollection (используя его запись RCollection - теперь вы видите, что соглашения о присваивании имен упрощают программирование), хотя вы и не определили TCollection. Правило очень простое и за- поминаемое: именно вы отвечаете за регистрацию каждого типа объ- екта, который ваша программа будет помещать в поток. *- Запись в поток ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Нужно следовать обычной последовательности операций вво- да-вывода в файл: создать поток; поместить в него данные (набор); закрыть поток. Вам не нужно писать итератор ForEach для помещения в поток каждого элемента набора. Вы просто говорите потоку, что нужно поместить (Put) набор в поток (см. программу STREAM1.PAS): var GraphicsList: PCollection; GraphicsStream: TBufStream; begin StreamRegistration; { регистрация всех объектов потока } . . . { поместить набор в поток на диске } GraphicsStream.Init('GRAPH.SMT', stCreate, 1024); GraphicsStream.Put(GraphicsList); { выходной набор } GraphicsStream.Done; { сброс потока } . . . end. В результате создастся файл на диске, который содержит всю информацию, необходимую для "считывания" набора назад в память. Когда поток открыт, и ищется набор, то (см. STREAM2.PAS) восста- навливаются все скрытые связи между набором и его элементами, объекты и их таблицы виртуальных методов. Следующий раздел пояс- няет, как помещать в поток объекты, которые содержат связи с дру- гими объектами. *- Как все хранится? ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Относительно потоков нужно сделать важное предостережение: только владелец объекта должен записывать его в поток. Это пре- достережение аналогично традиционному предостережению языка Паскаль, которое вам должно быть известно: только владелец указа- теля может уничтожить его. В реальных сложных приложениях множество объектов часто име- ют указатель на конкретную структуру. Когда возникает необходи- мость в выполнении операций ввода-вывода, вы должны решить, кто "владеет" структурой. Только этот владелец должен посылать струк- туру в поток. Иначе у вас может получиться несколько копий одной структуры в потоке. При считывании такого потока будет создано несколько экземпляров структуры, и каждый из первоначальных объ- ектов будет указывать на собственную персональную копию структуры вместо единственной первоначальной структуры. *- Экземпляры отображаемых подэлементов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Часто оказывается удобным хранить указатели на группы отоб- ражаемых подэлементов в экземплярах локальных переменных. Напри- мер, диалоговое окно часто хранит указатель на его объекты управ- ления в полях с мнемоническими именами для более удобного доступа (OKButton или FileINputLine). При включении отображаемого элемен- та в группу отображаемых элементов, владелец будет иметь два ука- зателя на отображаемый подэлемент, один - в поле, и еще один - в списке отображаемых подэлементов. Если на это не обратить внима- ния, то считывание такого объекта из потока приведет к дублирова- нию. Решение состоит в использовании методов TGroup GetSubViewPtr и PutSubViewPtr. При хранении поля, которое является отображаемым подэлементом, вместо записи указателя, как если бы это была прос- тая переменная, вы вызываете метод PutSubViewPtr, который записы- вает ссылку на порядковую позицию отображаемого подэлемента в списке подэлементов группы. Таким образом, при загрузке (Load) группы обратно из потока, вы вызываете метод GetSubViewPtr, кото- рый гарантирует, что поле и список отображаемых подэлементов ука- зывают на один и тот же объект. Приведем короткий пример использования GetChildPtr и PutChildPtr в простом окне: type TButtonWindow = object(TWindow) Button: PButton; constructor Load(var S: TStream); procedure Store(var S: TStream); virtual; . . . end; constructor TButtonWindow.Load(var S: TStream); begin inherited Load(S); GetSubView(S, Button); end; procedure TButtonWindow.Store(var S: TStream); begin inherited Store(S); PutSubViewPtr(S, Button); end; Давайте посмотрим теперь, чем метод Store отличается от обычного метода Store. После записи окна обычным образом все, что нужно сделать - это запись вместо самого поля, как это обычно де- лается, ссылки на поле Button. Фактически, когда вы вызываете TWindow.Store, объект командной кнопки записывается как отобража- емый подэлемент. Все, что вам нужно сделать кроме этого - это по- мещения в поток информации, указывающей, что Button должно указы- вать на этот подэлемент. Метод Load делает то же самое в обратном порядке, сначала загружая окно и его отображаемые подэлементы (командные кнопки), а затем восстанавливая указатель на этот отображаемый подэлементов в Button. *- Создание экземпляров братских отображаемых элементов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Аналогичная ситуация может возникнуть, если отображаемый элемент имеет поле, указывающее на одного из его "братьев". Отоб- ражаемый элемент называется братом другого отображаемого элемен- та, если они оба принадлежат одной и той же группе. Прекрасным примером этого является объект прокрутки. Поскольку объект прок- рутки знает о двух полосах прокрутки, которые являются членами одного и того же окна, которое содержит элемент прокрутки. Оно содержит два поля, которое указывает на эти отображаемые элемен- ты. Как и для отображаемых подэлементов, при чтении и записи ссылок на братские отображаемые элементы в поток могут возникнуть проблемы. Решение также будет аналогичным. Методы TView PutPeerViewPtr и GetPeerViewPtr предоставляют средства доступа к порядковой позиции другого отображаемого элемента в списке отоб- ражаемых подэлементов объекта-владельца. Единственно о чем нужно побеспокоиться, так это о загрузке ссылок на братские отображаемые элементы, которые еще не загруже- ны (т.е. в списке отображаемых подэлементов они идут ниже и, сле- довательно, позднее в потоке). Turbo Vision автоматически обраба- тывает эту ситуацию, отслеживая все подобные будущие ссылки и разрешая их после загрузки всех отображаемых подэлементов. Вам нужно иметь в виду, что ссылки на братские отображаемые элементы не будут действовать, пока Load не выполнится целиком. Принимая это во внимание, вы не должны помещать в Load никакой код, кото- рый использует отображаемые подэлементы, зависящие от их братских отображаемых элементов, поскольку в этом случае результат может быть непредсказуемым. *- Копирование потока ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TStream имеет метод CopyFrom(S,Count), который копирует за- данное число байт (Count) из заданного потока S. Метод CopyFrom может быть использован для копирования содержимого одного потока в другой. Если, например, вы циклически обращаетесь к дисковому потоку, то можете скопировать его в поток EMS для организации бо- лее быстрого доступа: NewStream := New(TEmsStream, Init(OldStream^.GetSize)); OldStream^.Seek(0); NewStream^.CopyFrom(OldStream, OldStream^.GetSize); *- Потоки произвольного доступа ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД До этого момента мы работали с потоками как с устройствами последовательного доступа: вы помещали (Put) объекты в конец ва- шего потока и считывали их назад (Get) в той же последовательнос- ти. Но Turbo Vision имеет и более мощные средства. Имеется воз- можность рассматривать поток как виртуальное устройство произ- вольного доступа. Кроме методов Get и Put, которые соответствуют Read и Write при работе с файлом, потоки обладают средствами про- ведения операций Seek, FilePos, FileSize и Truncate. - Процедура потока Seek перемещает текущий указатель потока к заданной позиции (число байт от начала потока), как стандартная процедура Seek языка Паскаль. - Процедура GetPos по своему действию обратна процедуре Seek. Она возвращает значение Longint с текущей позицией потока. - Функция GetSize возвращает размер потока в байтах. - Процедура Truncate удаляет все данные, которые расположены после текущей позиции потока, при этом текущая позиция по- тока становится концом потока. Поскольку работа с этими программами очень удобна, потоки произвольного доступа требуют от вас отслеживать вне потока ин- декс, отмечающий начальную позицию каждого объекта в потоке. В этом случае для хранения индекса вы можете прекрасно использовать набор. Фактически, эти средства используются Turbo Vision в фай- лах ресурсов. Если вы хотите использовать поток с произвольным доступом, посмотрите, нельзя ли для этого применить файл ресурса. Примечание: Ресурсы описываются в Главе 18 "Ресурсы". *- Необъектные элементы потоков ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В поток можно записывать и элементы, которые не являются объектами, но для этого следует использовать несколько иной под- ход. Стандартные методы потока Get и Put требуют загрузки или за- писи объекта, производного от TObject. Если вам нужно создать по- ток, который состоит не из объектов, переходите на нижний уровень процедур Read и Write, где в поток записывается или из него счи- тывается заданное число байт. Этот же механизм используют методы Get и Put для чтения и записи данных об объектах. Вы просто обхо- дите механизм таблицы виртуальных методов (VMT), который заложен в Put и Get. *- Разработка пользователем собственных потоков ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данный раздел суммирует возможности методов и обработки оши- бок потоков Turbo Vision, чтобы вы знали, что можно использовать для создания новых типов потоков. Сам TStream является абстрактным объектом и его можно расши- рить для создания удобного типа потока. Большинство методов TStream являются абстрактными и должны быть реализованы как их производные методы, основывающиеся на абстрактных методах TStream. Полностью реализованы только методы Error, Get и Put объекта TStream. GetPos, GetSize, Read, Seek, SetPos, Truncate и Write должны быть переопределены. Если производный тип объекта имеет буфер, то должен быть переопределен и метод Flush. *- Обработка ошибок потока ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TStream имеет метод Error(Code, Info), который вызывается при обнаружении ошибки потока. Error просто присваивает полю Status потока значение одной из констант, приведенных в Главе 21 "Справочник по Turbo Vision" в разделе "Константы stXXXX". Поле ErrorInfo не определено, если значение Status не есть stGetError или stPutError. Если значение поля Status равно stGetError, то поле ErrorInfo содержит номер идентификатора пото- ка незарегистрированного типа. Если значение поля Status равно stPutError, то поле ErrorInfo содержит смещение в таблице вирту- альных методов типа, который вы пытались поместить в поток. Вы можете переписать TStream.Error для генерации любого уровня обра- ботки ошибок, включая ошибки этапа выполнения. *- Версии потоков ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Turbo Vision 2.0 поддерживает ограниченную форму создания версий потоков. Версии позволяют приложениям, написанным с по- мощью версии 2.0 считывать объекты из потоков, созданных в версии 1.0. Потоки, записанные в версии 2.0, включающие в себя новые и измененные в данной версии объекты не считываются приложениями, написанными в версии 1.0. *- Флаги версий ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В поле Options в объектах Turbo Vision, имеющих поля, отлич- ные от соответствующих объектов версии 1.0, установлен бит ofVersion20. В версии 1.0 это бит не определен. *- Работа в различных версиях ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Конструкторами Load версии 2.0 обработка версий выполняется прозрачно. После вызова наследуемых конструкторов Load они прос- матривают бит ofVersion считанного поля Options. Затем на основе установки этого бита Load считывает остальную часть объекта (как он был записан), но записывает информацию, как внутренний объект версии 2.0. Методы Store версии 2.0 записывают только объекты версии 2.0. В программах версии 2.0 вы без изменения можете считать стандартные объекты, записанные в приложениях версии 1.0 Turbo Vision. *- ГЛАВА 18. Ресурсы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Файл ресурсы - это объект Turbo Vision, который сохраняет передаваемые в него объекты и затем выполняет их поиск по именам. Ваша программа т.о. получает возможность выполнять поиск своих объектов в ресурсе, а не инициализировать их. Вместо того, чтобы ваша программа инициализировала объекты, вы можете иметь отдель- ную программу для создания всех объектов и сохранять их в ресурсе. Этот механизм вполне прост: файл ресурса действует подобно потоку с произвольным доступом. Доступ к объектам в нем осущест- вляется по ключам, которые представляют собой уникальные строки, идентифицирующие ресурсы. В отличие от других средств Turbo Vision вам, вероятно, не потребуется изменять механизм ресурсов. Ресурсы являются мощным и гибким средством. Вы должны лишь обучиться ими пользоваться. *- Преимущества использования ресурсов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Использование файла ресурса имеет ряд преимуществ. Использование ресурсов позволяет настраивать прикладные программы без изменения фрагментов программ. Например, и текст блоков диалога, и метки пунктов меню, и цвета отображаемых эле- ментов могут быть изменены внутри ресурса, при этом вид вашей прикладной программы изменится без постороннего вмешательства. Обычным путем фрагмент программы можно сохранить, помещая все методы Init вашего объекта в отдельную программу. Методы Init часто бывают весьма сложными, содержат вычисления и другие операции, упрощающие остальную часть вашего фрагмента программы. В вашей прикладной программе имеется также метод Load для каждого объекта, но по сравнению с Init он достаточно тривиален. Обычно с помощью ресурса вы сможете сэкономить от 8 до 10% объема вашего программного кода. Использование ресурса упрощает также работу с прикладными программами, написанными на специфических языках. Прикладная программа выполняет загрузку объектов по именам, которым соот- ветствует представляемый ими язык. Если вам требуется разработать варианты прикладной программы с различными возможностями, вы можете, к примеру, создать два на- бора меню, один из которых будет обеспечивать доступ ко всем воз- можностям программы, а другой - к ограниченному набору ее функ- ций. В этом случае вам совсем не потребуется переписывать ваш фрагмент программы, а также предполагать случайное уничтожение неверной части программы. Вы можете полностью реализовать все функциональные возможности программы с помощью нового ресурса вместо замены всей программы. Короче говоря, ресурс изолирует представление объектов в ва- шей программе и облегчает ее изменение. *- Содержимое ресурса ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Прежде, чем более детально ознакомиться с ресурсами, вы должны убедиться, что хорошо разобрались с материалом о потоках и наборах, т.к. и те, и другие используются в механизме ресурсов. Вы можете использовать ресурсы, не зная их действия, но если вы захотите их изменить каким-либо образом, вы должны знать, что бу- дете в них помещать. TResourсeFile содержит как отсортированный строковый набор, так и поток. Строки набора являются ключами к объектам в потоке. TResourceFile имеет метод Init, который имеет входным параметром поток, а также метод Get, который имеет входным параметром строку и возвращает объект. *- Создание ресурса ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Создание файла ресурса представляет собой четырехшаговый процесс. Вы должны открыть поток, инициализировать в нем файл ресурсов, сохранить один или несколько объектов с их ключами, и закрыть ресурс. Следующий фрагмент программы создает простой файл ресурсов MY.TVR, содержащий один ресурс: строку состояния с ключом 'Waldo'. program Resourс1; uses Drivers, Objects, Views, App, Menus; type PHaltStream = ^THaltStream; THaltStream = object(TBufStream) procedure Error(Code, Info: Integer);virtual; end; const cmNewDlg = 1001; var MyRez: TResourceFile; MyStrm: PHaltStream; procedure THaltStream.Error(Code, Info: Integer); begin Writeln('Stream error: ', Code, ' (', Info, ')'); Halt(1); end; procedure CreateStatusLine; var R: TRect; StatusLine: PStatusLine; begin Assign(0, 24, 80, 25); StatusLine := New(PStatusLine, Init(R, NewStatusDef(0, $FFFF, NewStatusItem('~Alt-X~ Exit', AltX, cmQuit, NewStatusItem('~F3~ Open', F3Key, cmNewDlg, NewStatusItem('~F5~ Zoom', F5Key, cmZoom, NewStatusItem('~Alt-F3~ Close', AltF3, cmClose, nil)))), nil) )); MyRez.Put(StatusLine, 'Waldo'); Dispose(StatusLine, Done); end; begin MyStrm := New(PHaltStream, Init('MY.TVR', stCreate, 1024)); MyRez.Init(MyStrm); RegisterType(RStatusLine); CreateStatusLine; MyRez.Done; end. *- Чтение ресурса ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Выполнить поиск ресурса в файле ресурсов так же просто, как извлечь объект из потока: вы должны вызвать функцию Get файла ресурсов с нужным вам ключом ресурса в качестве параметра. Get возвратит указатель на общий объект PObject. Созданный в предыдущем примере ресурс строки состояния может быть обнаружен и использован в прикладной программе следующим образом: program MyApp; uses Objects, Drivers, Views, Menus, Dialogs, App; var MyRez: TResourceFile; type PMyApp = ^TMyApp; TMyApp = object(TApplication) constructor Init; procedure InitStatusLine; virtual; end; constructor TMyApp.Init; const MyResFileName: FName = 'MY.TVR'; begin MyRez.Init(New(PBufStream, Init(MyRezFileName, stOpen, 1024))); if MyRez.Stream^.Status <> 0 then Halt(1); RegisterType(RStatusLine); TApplication.Init; end; procedure TMyApp.InitStatusLine; begin StatusLine := PStatusLine(MyRez.Get('Waldo')); end; var ValdoApp: TMyApp; begin WaldiApp.Init; WaldiApp.Run; WaldiApp.Done; end. При считывании объекта из ресурса вы должны учитывать воз- можность получения указателя nil. Если имя вашего индекса неверно (т.е. в файле нет ресурса с таким ключом), функция Get возвращает nil. После отладки программы с ресурсом эта проблема отпадает. Вы можете неоднократно считывать объект из ресурса. Малове- роятно, что вы захотите проделать это, например, со строкой состояния, но, например, пользователь может потребовать многок- ратного использования блока диалога в процессе выполнения прик- ладной программы. Ресурс многократно выдает объект по его зап- росу. Здесь могут возникнуть потенциальные проблемы с медленным вводом-выводом с диска, даже в том случае, если файл ресурсов бу- феризован. Вы можете отрегулировать буферизацию вашего диска, или скопировать поток в поток ESM, если у вас имеется память EMS. *- Списки строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Кроме стандартного механизма ресурсов Turbo Vision распола- гает двумя специализированными объектами для обработки списков строк. Список строк - это специальный объект доступа к ресурсам, который обеспечивает вашей программе доступ к строкам ресурсов по номерам (обычно выраженным в виде констант) вместо ключевых строк. Это дает возможность программе хранить строки в файле ресурсов для облегчения их приспособления и интернационализации. Например, в интегрированной среде Турбо Паскаля IDE объект списка строк используется для выдачи всех сообщений об ошибках. Это означает, что программа может вызвать сообщение об ошибке по номеру, а для различных версий для различных стран в их ресурсах будут помещаться соответственно разные строки. Объект списка строк по конструкции не обладает большой гиб- костью, но в эксплуатации он удобен и имеет высокое быстро- действие. Объект TStringList обеспечивает доступ к строкам. Создание списка строк требует использования объекта TStrListMaker. Регист- рационные записи обоих этих объектов будут иметь одинаковый номер типа объекта. Объект списка строк не имеет метода Init. Единственным конструктором у него является метод Load, т.к. списки строк су- ществуют лишь в файлах ресурсов. Таким же образом, поскольку список строк является в сущности только ресурсом для чтения строк, он имеет функцию Get и не имеет процедуры Put. *- Создание списков строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Тип объекта TStrListMaker используется для создания списка строк в файле ресурсов, который будет применяться вместе с TStringList. В отличие от списка строк, предназначенного только для чтения строк, объект-создатель списка строк предназначен только для записи строк. С помощью этого объекта вы можете иници- ализировать список строк, последовательно записать в него строки и сохранить полученный список в потоке. *- ГЛАВА 19. Справочник по системе Turbo Vision ----------------------------------------------------------------- В настоящей главе описываются все элементы Turbo Vision, включая типы объектов, процедуры, функции, типы, переменные и константы. Все они приводятся в алфавитном порядке. Целью настоящей главы не является обучение использованию соответствующих элементов - это всего лишь справочник. Для лучшего обучения их использованию следует обратиться к соответствующим главам Части 2, "Использование Turbo Vision". При поиске информации о конкретном объекте следует иметь в виду, что многие свойства объекта из иерархии объектов наследуют- ся от порождающего объекта. Вместо бесконечного дублирования информации настоящая глава лишь описывает поля и методы, являющи- еся новыми или измененными для данного элемента. Просмотрев диаг- рамму наследования для объекта, легко увидеть, каким из предшест- венников порождено данное поле, и какие объекты вводят или перео- пределяют его методы. *- Процедура Abstract Objects ----------------------------------------------------------------- Описание: procedure Abstract; Функция: Вызов этой процедуры завершает программу с ошибкой этапа выполнения 211. При реализации абстрактных типов объектов используйте вызовы Abstract в тех виртуальных методах, которые должны быть переопределены в порожденных типах. Это предотвратит любые попытки использования экземпляров абстрактного типа объек- та. См. также: раздел "Абстрактные методы" в Главе 7. *- Переменная Application App ----------------------------------------------------------------- Описание: Application: PApplicaton = nil; Функция: На протяжение всего времени исполнения программы для Turbo Vision Application указывает на объект программы. Конс- труктор Init из TProgram устанавливает значение Application рав- ным @Self в начале программы, а деструктор Done сбрасывает его в nil. По умолчанию конструктор TAplication вызывает TProgram.Init, поэтому все объекты программ наследуют это поведение. См. также: TProgram.Init *- Переменная AppPalette App ----------------------------------------------------------------- Описание: AppPalette: Integer = apColor; Функция: Выбирает одну из трех доступных в программе палитр (apColor, apBlackWhite или apMonochrome). Метод InitScreen из TProgram устанавливает значение AppPalette в зависимости от теку- щего режима экрана. Метод GetPalette проверяет значение AppPalet- te и определяет, какую из трех палитр следует вернуть. Для изме- нения существующего по умолчанию выбора палитры можно переопреде- лить значение TProgram.InitScreen. См. также: TProgram.GetPalette, TProgram.InitScreen, конс- танты apXXXX *- Константы apXXXX App ----------------------------------------------------------------- Значения: Определены следующие значения констант палитры: Таблица 19.1. Константы палитры. ------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ apColor 0 Палитра для цветного монитора apBlackWhite 1 Палитра для жидкокристаллического монитора apMonochrome 2 Палитра для монохромного монитора ------------------------------------------------------------ Функция: Константы, начинающиеся с ap, используются для указания того, с какой из трех стандартных палитр будет работать программа на Turbo Vision для цветного, черно-белого и монохром- ного дисплеев. *- Процедура AssignDevice TextView ----------------------------------------------------------------- Описание: procedure AssignDevice(var T: Text; Screen: PTextDevice); Функция: Связывает текстовый файл с текстовым устройством. AssignDevice работает аналогично стандартной процедуре Assign за исключением того, что не указывается имя файла. Вместо этого, текстовый файл связывается с TTextDevice, которая передается Screen (запоминая Screen в первых 4 байтах поля UserData в TextRec(T). Последующие операции ввода-вывода для текстового файла будут читать и писать на устройство Screen с использованием виртуальных методов StrRead и StrWrite. Поскольку TTextDevice- это абстракт- ный тип, то параметр Screen должен указывать на копию потомка TTextDevice, такую, как TTerminal, которая реализует все функцио- нальные возможности прокручиваемого отображаемого элемента. См. также: TTextDevice, TextRec (в Справочнике программис- та.) *- Константы bfXXXX Dialogs ----------------------------------------------------------------- Определены следующие значения флага "кнопки": Рис. 19.1 Значения флага "кнопки" ЙННННСННННСННННСННННСННННСННННСННННСННННё єmsb і і і і і і і1sb і ИННННПННННПННННПННННПНСННПНСННПНСННПНСННѕ і і і АДДДДbfDefault = $01 і і АДДДДДДДДДbfLeftJust = $02 і АДДДДДДДДДДДДДДbfBroadcast = $04 АДДДДДДДДДДДДДДДДДДДbfGrabFocus = $08 Таблица 19.2. Значения флага кнопки ------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ bfNormal $00 Обычная "кнопка" bfDefault $01 "Кнопка", используемая по умолчанию bfLeftJust $02 Метка "кнопки" выравнена по левой границе bfBroadcast $04 При нажатии "кнопка" уведомляет владельца bfGrabFocus $08 При нажатии кнопки мыши "кнопка" получает фокус ввода ------------------------------------------------------------ Функция: Объекты кнопок имеют битовое поле Flags, содержащее комбинацию констант bfXXXX, определяющих стиль кнопки. bfNormal указывает на обычную (не назначенную по умолчанию) "кнопку". bfDefault указывает на тот факт, что кнопка будет кнопкой, опре- деленной по умолчанию. Вы должны сами следить за тем, чтобы кноп- ка была единственной определенной по умолчанию в группе кнопок. Значение bfLeftJust влияет на положение отображаемого внутри кнопки текста: если оно не задано, то текст располагается по центру; если задано, то метка выравнивается по левой границе. bfBroadcast управляет способом, которым объект кнопки гене- рирует события при ее нажатии: -Если значение не задано (что установлено по умолчанию), то при нажатии кнопки для генерации события команды она использует PutEvent: E.What := evCommand; E.Command := Command; E.InfoPtr := @Self; PutEvent (E); -Если значение bfBroadcast задано, то при нажатии кнопки для посылки сообщения владельцу используется Message: Message (Owner, evBroadcast, Command, @Self); Установка bfGrabFocus приводит к тому, что при выборе кнопки с помощью мыши к ней переходит фокус ввода. См. также: TButton.Flags, TButton.MakeDefault, TButton.Draw *- Переменная ButtonCount Drivers ----------------------------------------------------------------- Описание: ButtonCount: Byte = 0; Функция: ButtonCount хранит число кнопок "мыши" или значение 0, если "мышь" не установлена. Эту переменную можно использовать для определения того, доступна ли поддержка "мыши". Значение ус- танавливается в инициализационном коде в Drivers и не должно из- меняться. *- Константы cdXXXX StdDlg ----------------------------------------------------------------- ------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ cdNormal $0000 Создавать диалоговое окно обычным образом, включая загрузку каталога cdNoLoadDir $0001 Инициализировать диалоговое окно без загрузки содержимого каталога. Используется при создании диалоговых окон, хранящихся в потоке. cdHelpButton $0002 Поместить в диалоговое окно кнопку подсказки. ------------------------------------------------------------ Функция: Эти константы определяют величины, передаваемые конструктору Init диалогового окна изменения каталога в параметре AOptions. См. также: объект TChDirDialog *- Константы cfXXXX Dialogs ----------------------------------------------------------------- ------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ cfOneBit $0101 1 бит на кнопку с независимой фиксацией cfTwoBits $0203 2 бита на кнопку с независимой фиксацией cfFourBits $040F 4 бита на кнопку с независимой фиксацией cfEightBits $08FF 8 бит на кнопку с независимой фиксацией ------------------------------------------------------------ Функция: Многопозиционные кнопки с независимой фиксацией используют константы cfXXXX для описания того, сколько бит в поле Value представляют состояние каждой кнопки с независимой фиксаци- ей. Старшее слово константы показывает количество бит, используе- мых каждой кнопкой с независимой фиксацией, а младшее слово соде- ржит битовую маску для чтения этих бит. Например, значение cfTwoBits указывает на то, что Value использует для каждой кнопки два бита (что делает возможным испо- льзование в одном кластере 16 кнопок), и маскирует каждое из значений кнопки с независимой фиксацией маской $03. См. также: объект TMultiCheckBoxes *- Переменная CheckSnow Drivers ----------------------------------------------------------------- Описание: CheckSnow: Boolean; Функция: CheckSnow выполняет функцию одноименного флага стандартного модуля Турбо Паскаля - Crt. Проверка помех в виде "снега", которая замедляет вывод на экран, требуется только для некоторых старых адаптеров CGA. InitVideo устанавливает значение CheckSnow равным True только в том случае, если он обнаруживает адаптер CGA. Для более быстрого ввода/вывода на экран можно уста- новить значение False в любой момент после вызова InitVideo. См. также: InitVideo *- Процедура ClearHistory HistList ----------------------------------------------------------------- Описание: procedure ClearHistory; Функция: Удаляет все строки из всех списков протокола. *- Процедура ClearScreen Drivers ----------------------------------------------------------------- Описание: procedure ClearScreen; Функция: Очищает экран. ClearScreen предполагает, что внача- ле был вызван InitVideo. Как указано в описании InitVideo, Вам редко потребуется использовать эту процедуру. См. также: InitVideo *- Переменная Clipboard Editors ----------------------------------------------------------------- Описание: Clipboard: PEditor = nil; Функция: Переменная Clipboard указывает на объект редактора, используемый для передачи данных между другими объектами редакто- ра. Редактор системного буфера не должен поддерживать отмену из- менений (то есть поле CanUndo должно быть равно False). *- Константы cmXXXX ----------------------------------------------------------------- Функция: Эти константы представляют предопределенные команды Turbo Vision. Они передаются в поле Command событий evMessage (evCommand и evBroadcast) и заставляют методы HandleEvent станда- ртных объектов Turbo Vision выполнять различные задачи. Turbo Vision резервирует значения констант от 0 до 99 и от 256 до 999 для своих целей. Обработчики событий стандартных объе- ктов Turbo Vision реагируют на эти предопределенные константы. Программисты могут определить свои собственные константы в диапа- зонах от 100 до 255 и от 1, 000 до 65, 535 без конфликтов с пре- допределенными командами. Значения: Следующие стандартные команды определены в модуле Views и используются всеми отображаемыми элементами: Таблица 19.3. Коды стандартных команд. ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmValid 0 Передается в поле Valid отображаемого элемента для проверки вновь созданных копий отображаемых элементов. cmQuit 1 Завершает программу, вызывая метод EndModal объекта прикладной программы, передавая ему cmQuit). cmError 2 Не обрабатывается никаким объектом. Может использоваться для представления нереализованных или неподдерживаемых команд. cmMenu 3 Заставляет отображаемый элемент меню вызвать ExecView для самого себя в целях выполнения процесса выбора элемента меню, в результате чего может генерироваться новая команда с помощью PutEvent. cmClose 4 Закрывает окно. Если окно является режимным, то посредством PutEvent генерируется событие коман- ды со значением cmCancel. Если окно не режимное, то вызывается метод Close. cmZoom 5 Заставляет вызывать Zoom, если окно поддерживает возможность "распахивания". cmResize 6 Заставляет вызывать DragView для самого себя, если окно поддерживает изменение размеров. cmNext 7 Выбирает в качестве активного в рабочей области следующее окно. cmPrev 8 Выбирает в качестве активного в рабочей области предыдущее окно. ----------------------------------------------------------------- Следующие стандартные команды используются для определения поведения по умолчанию объектов диалогового окна: Таблица 19.4. Стандартные команды диалогового окна. ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmOK 10 Была нажата "кнопка" OK. cmCancel 11 Диалоговое окно было закрыто "кнопкой" Cancel, пиктограммой закрытия или клавишей Enter. cmYes 12 Была нажата "кнопка" Yes. cmNo 13 Была нажата "кнопка" No. cmDefault 14 Была нажата "кнопка", назначенная по умолчанию. ----------------------------------------------------------------- События с командами cmOK, cmCancel, cmYes или cmNo отменяют режимный (неигнорируемый) характер диалогового окна и возвращают это значение (вызывая EndModal). Обычно режимное диалоговое окно содержит по крайней мере одну кнопку с одним из этих значений ко- манд. Команда cmDefault имитирует нажатие "кнопки", определенной по умолчанию. По умолчанию диалоговые окна генерируют событие команды cmDefault в ответ на событие клавиатуры kbEnter. Для операций с системным буфером и окнами используются сле- дующие команды, генерируемые стандартными меню Edit и Window: Таблица 19.5. Стандартные команды меню Edit и Window ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmCut 20 Вырезать и перенести выделенный текст в системный буфер cmCopy 21 Скопировать выделенный текст в системный буфер cmPaste 22 Скопировать текст из системного буфера cmUndo 23 Отменить последнее изменение cmClear 24 Убрать выделенный текст cmTile 25 Расположить мозаично все окна, которые можно так расположить cmCascade 26 Расположить каскадно все окна, которые можно так расположить ----------------------------------------------------------------- См. также: функцию StdEditMenuItems, функцию StdWindowMenuItems Функция: Turbo Vision 2.0 определяет новые командные конста- нты для пунктов стандартного меню файлов. Значения: Модуль App определяет для программ следующие стан- дартные команды: Таблица 19.6. Стандартные команды прикладной программы ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmNew 30 Открыть новый файл из пункта меню File|New cmOpen 31 Открыть существующий файл из пункта меню File|Open cmSave 32 Сохранить текущий файл из пункта меню File|Save cmSaveAs 33 Сохранить файл с переименованием из пункта меню File|Save As cmSaveAll 34 Сохранить все открытые файлы из пункта меню File|Save All cmChangeDir 35 Изменить текущий каталог из пункта меню File|Change Dir cmDosShell 36 Выйти в DOS из пункта меню File|DOS Shell cmCloseAll 37 Закрыть все открытые файлы из пункта меню File|Close All ----------------------------------------------------------------- См. также: функцию StdFileMenuItems Для использования стандартными отображаемыми элементами оп- ределены следующие стандартные команды: Таблица 19.7. Стандартные команды для отображаемых элементов ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmReceivedFocus 50 TView.SetState использует функцию Message cmReleasedFocus 51 Для передачи владельцу события evBroad- cast с одним из этих значений при измене- нии sfFocused. Это информирует любой ви- димый в текущий момент времени элемент о том, что отображаемый элемент получил или потерял фокус, и что эти отображаемые элементы должны быть соответственно об- новлены. Объект-метка, например, реагиру- ет на эти команды, включая или выключая свою подсветку при получении или потере фокуса отображаемым элементом, который она отмечает. cmCommandSetChanged 52 Метод Idle программы генерирует событие с этим значением, как только он обнаружит изменение в текущем наборе команд. Изве- щение посылается к каждому отображаемому элементу программы, принимающему собы- тия-извещения. Отображаемый элемент дол- жен реагировать на изменения в наборе ко- манд перерисовыванием самого себя должным образом. cmScrollBarChanged 53 TScrollBar использует функцию Message для cmScrollBarClicked 54 передачи события с извещением с одним из этих значений своему собственнику, как только обнаруживается изменение его зна- чения или перещелкивание "мышью" на поло- се прокрутки. Отображаемые элементы, свя- занные с полосой прокрутки, такие, как элементы прокрутки и визуализаторы спис- ков, могут затем реагировать на это изве- щение. cmSelectWindowNum 55 Заставляет окно выбрать себя в случае, если InfoInt записи события соответствует полю окна Number. TProgram.HandleEvent реагирует на события от клавиатуры от Alt-1 до Alt-9 сообщением-уведомлением cmSelectWindowNum с InfoInt от 1 до 9. cmListItemSelected 56 Объекты просмотра списков извещают владельца событием со значением Command, равным cmListItemSelected, при выборе элемента списка. cmRecordHistory 60 Заставляет объект предыстории "записы- вать" текущее содержимое связанного объ- екта вводимой строки. Кнопки посылают эти сообщения владельцам при нажатии, застав- ляя "записывать" все объекты THistory в диалоговом окне. ----------------------------------------------------------------- См. также: TView.HandleEvent, TCommandSet Значения: объектами TEditor используются следующие констан- ты: ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmFind 82 Вызывает диалоговое окно поиска текста cmReplace 83 Вызывает диалоговое окно поиска и замены текста cmSearchAgain 84 Повтор предыдущего поиска ----------------------------------------------------------------- TEditor.HandleEvent преобразует различные клавиши в следую- щие команды: ---------------------------------------------------- Команда Значение Команда Значение ---------------------------------------------------- cmCharLeft 500 cmNewLine 512 cmCharRight 501 cmBackSpace 513 cmWordLeft 502 cmDelChar 514 cmWordRight 503 cmDelWord 515 cmLineStart 504 cmDelStart 516 cmLineEnd 505 cmDelEnd 517 cmLineUp 506 cmDelLine 518 cmLineDown 507 cmInsMode 519 cmPageUp 508 cmStartSelect 520 cmPageDown 509 cmHideSelect 521 cmTextStart 510 cmIndentMode 522 cmTextEnd 511 cmUpdateTitle 523 ----------------------------------------------------------------- Значения: Модуль StdDlg определяет для диалоговых окон сле- дующие команды: ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- cmFileOpen 800 Возвращается TFileDialog при выборе мышью Open cmFileReplace 801 Возвращается TFileDialog при выборе мышью Replace cmFileClear 802 Возвращается TFileDialog при выборе мышью Clear ----------------------------------------------------------------- *- Переменная ColorIndexes ColorSel ----------------------------------------------------------------- Описание: ColorIndexes: PColorIndex = nil; Функция: Хранит текущее состояние цветов диалогового окна программы, что позволяет легко сохранять и восстанавливать это состояние при последующем использовании. См. также: процедуру LoadIndexes, процедуру StoreIndexes *- Функция ColorGroup ColorSel ----------------------------------------------------------------- Описание: function ColorGroup (Name: String; Items: PColorItem; Next: PColorGroup): PColorGroup; Функция: Выделяет в динамической области памяти новую группу цветов с именем Name и перечнем цветовых элементов, переданным в Items, и возвращает указатель на группу. Next указывает на следу- ющую группу в связанном списке групп, где nil указывает на конец списка. См. также: тип TColorGroup *- Функция ColorItem ColorSel ----------------------------------------------------------------- Описание: function ColorItem (Name: String; Index: Byte; Next: PColorItem): PColorItem; Функция: Выделяет в динамической памяти новый цветовой эле- мент с именем Name и цветовым индексом, переданным в Index. Next указывает на следующий элемент цвета в связанном списке, где nil указывает на конец списка. *- Константы coXXXX Drivers ----------------------------------------------------------------- Функция: Константы coXXXX передаются TCollection.Error в качестве параметра Code, когда при работе набор обнаруживает ошибку. Значения: Для всех наборов определены следующие стандартные коды ошибок: Таблица 19.8. Коды ошибок набора. ----------------------------------------------------------------- Команда Значение Назначение ----------------------------------------------------------------- coIndexError -1 Индекс находится за пределами диапазона. Параметр Info, передаваемый методу Error, содержит неверный индекс. coOverflow -2 Переполнение набора. TCollection.SetLimit не удалось расширить набор до требуемого разме- ра. Параметр Info, передаваемый методу Er- ror, содержит запрошенный размер. ----------------------------------------------------------------- См. также: TCollection *- Функция: CStrLen Drivers ----------------------------------------------------------------- Описание: function CStrLen(S: String): Integer; Функция: Возвращает длину строки S, где S- это управляющая строка, использующая символы "~" для указания символов быстрого вызова. Символы "~" исключаются из длины строки, поскольку они не будут появляться на экране. Например, для строки '~B~roccoli', CStrLen возвращает 8. См. также: MoveCStr *- Переменная CtrlBreakHit Drivers ----------------------------------------------------------------- Описание: CtrlBreakHit: Boolean = False; Функция: Драйвер обработки прерываний от клавиатуры Turbo Vision всегда устанавливает ее равной True, когда нажата комбина- ция клавиш Ctrl-Break. Это позволяет программам на Turbo Vision перехватывать Ctrl-Break и реагировать на него. Этот флаг может быть сброшен в любой момент установкой его равным False. См. также: SaveCtrlBreak *- Функция: CtrlToArrow Drivers ----------------------------------------------------------------- Описание: function CtrlToArrow(KeyCode: Word): Word; Функция: Преобразует управляющие WordStar-совместимые коды клавиатуры в соответствующие коды клавиш управления курсором. Если младший байт KeyCode соответствует одному из значений управ- ляющих клавиш, описанных в Таблице 19.9, то результатом будет соответствующая константа kbXXXX. В противном случае KeyCode возвращается неизмененным. Таблица 19.9. Преобразование управляющих клавиш. ----------------------------------------- Клавиша Lo(KeyCode) Результат ----------------------------------------- Ctrl-A $01 kbHome Ctrl-C $03 kbPgDn Ctrl-D $04 kbRight Ctrl-E $05 kbUp Ctrl-F $06 kbEnd Ctrl-G $07 kbDel Ctrl-H $08 kbBack Ctrl-R $12 kbPgUp Ctrl-S $13 kbLeft Ctrl-V $16 kbIns Ctrl-X $18 kbDown ----------------------------------------- *- Переменная CursorLines Drivers ----------------------------------------------------------------- Описание: CursorLines: Word; Функция: Устанавливает начальную и конечную строки курсора с помощью InitVideo. Формат совпадает с форматом, ожидаемым функци- ей 1 прерывания BIOS $10 для установки типа курсора. См. также: InitVideo, TView.ShowCursor, TView.HideCursor, TView.BlockCursor, Tview.NormalCursor *- Функция: DefEditorDialog Editors ----------------------------------------------------------------- Описание: function DefEditorDialog (Dialog: Integer; Info: Pointer): Word; Функция: DefEditorDialog представляет собой значение, кото- рое по умолчанию присваивается переменной EditorDialog. Описание использования диалоговых функций редактора смотрите в описании типа TEditorDialog. DefEditorDialog не показывает никаких диало- говых окон, а просто возвращает значение cmCancel, как будто выз- ванное диалоговое окно было закрыто. См. также: тип TEditorDialog, переменную EditorDialog *- Переменная DeskTop App ----------------------------------------------------------------- Описание: DeskTop: PDeskTop = nil; Функция: Сохраняет указатель на объект рабочей области прог- раммы. Для создания объекта рабочей области объект программы ис- пользует виртуальный метод InitDeskTop, вызываемый конструктором Init программы, и присваивает этот указатель DeskTop. Для созда- ния рабочей области (отличной от существующей по умолчанию), для создания другого объекта рабочей области необходимо переопреде- лить объект программы InitDeskTop и присвоить его DeskTop. См. также: TProgram.InitDesktop *- Функция DesktopColorItems ColorSel ----------------------------------------------------------------- Описание: function DesktopColorItems (const Next: PColorItem): PColorItem; Функция: Возвращает связанный список записей типа TColorItem для стандартного объекта рабочей области. Для программ, позволяю- щих пользователю изменять цвета рабочей области с помощью диало- гового окна выбора цветов, DesktopColorItems упрощает процесс ус- тановки цветов. *- Функция DialogColorItems ColorSel ----------------------------------------------------------------- Описание: function DialogColorItems (Palette: Word; const Next: PColorItem): PColorItem; Функция: Возвращает связанный список записей типа TColorItem для стандартного объекта диалогового окна. Для программ, позволя- ющих пользователю изменять цвета диалогового окна с помощью диа- логового окна выбора цветов, DialogColorItems упрощает процесс установки цветов. *- Процедура DisposeBuffer Memory ----------------------------------------------------------------- Описание: procedure DisposeBuffer (P: Pointer); Функция: Освобождает буфер P^. P должен быть буфером, выде- ленным с помощью процедуры NewBuffer. См. также: процедуру NewBuffer *- Процедура DisposeCache Memory ----------------------------------------------------------------- Описание: procedure DisposeCache (P: Pointer); Функция: Освобождает кэш-буфер P^. P должен быть буфером, выделенным с помощью процедуры NewCache. См. также: процедуру NewCache *- Процедура DisposeMenu Menus ----------------------------------------------------------------- Описание: procedure DisposeMenu(Menu: PMenu); Функция: Освобождает все элементы указанного меню (и все его подменю). См. также: Тип TMenu *- Процедура DisposeNode Outline ----------------------------------------------------------------- Описание: procedure DisposeNode (Node: PNode); Функция: Освобождает узел структуры, созданный с помощью функции NewNode, включая рекурсивное освобождение всех порожден- ных узлов. См. также: функция NewNode *- Процедура DisposeStr Objects ----------------------------------------------------------------- Описание: procedure DisposeStr(P:String); Функция: Освобождает строку, выделенную в динамической памя- ти с помощью функции NewStr. См. также: NewStr *- Константы dmXXXX Views ----------------------------------------------------------------- Значения: Биты DragMode определены следующим образом: Рис. 19.2. Битовые флаги режима перемещения. ЪДДДВДВДВДДДДДДДДДДД dmLimitAll = $F0 ЙПННСПСПСПСНСНСНСННН» єmsbі і і і і і і1sbє ИСННПСПСПСПНПНПСПНСНј і і і і і АДД dmDragMove = $01 і і і і АДДДДД dmDragGrow = $02 і і і АДДДДДДДДДДД dmLimitLoX = $10 і і АДДДДДДДДДДДДД dmLimitLoY = $20 і АДДДДДДДДДДДДДДД dmLimitHiX = $40 АДДДДДДДДДДДДДДДДДДД dmLimitHiY = $80 Функция: Эти константы служат для двух целей. Константы, начинающиеся с dmLimit, используются в методе DragMode для указа- ния тех частей отображаемого элемента (если таковые существуют), которые не должны перемещаться при перемещении внутри отображае- мого элемента-владельца. Константы, начинающиеся с dmDrag, указы- вают на способ, которым отображаемый элемент реагирует на переме- щение - изменением своего положения или размеров. DragMode и константы режима перемещения объединяются и фор- мируют параметр Mode метода TView.DragView. Обычно с DragMode комбинируется или dmDragGrow или dmDragMove, и результат передае- тся в Mode. Программа DRAG.PAS демонстрирует, как флаг режима перемещения влияет на поведение отображаемого элемента при его перемещении. Константы режима перемещения определены следующим образом: Таблица 19.10. Константы режима перемещения. ------------------------------------------------------------ Константа Назначение ------------------------------------------------------------ dmDragMove Позволяет отображаемому элементу перемещаться. dmDragGrow Позволяет отображаемому элементу изменять размер. dmLimitLoX Левая сторона отображаемого элемента не может выходить за Limits. dmLimitLoY Верхняя сторона отображаемого элемента не может выходить за Limits. dmLimitHiX Правая сторона отображаемого элемента не может выходить за Limits. dmLimitHiY Нижняя сторона отображаемого элемента не может выходить за Limits. dmLimitAll Никакая часть отображаемого элемента не может выходить за Limits. ------------------------------------------------------------ Поле отображаемого элемента DragMode содержит любую комбина- цию флагов dmLimitXX. По умолчанию TView.Init устанавливает это поле равным dmLimitLoY. В настоящее время поле DragMode использу- ется только в TWindow для формирования параметра Mode для DragVi- ew при перемещении окна и изменении его размеров. *- Процедура DoneDosMem Memory ----------------------------------------------------------------- Описание: procedure DoneDosMem; Функция: Освобождает память для выхода в оболочку DOS или для выполнения другой программы. DoneDosMem освобождает все кэш-буфера, затем устанавливает SetMemTop на конец последнего элемента динамически распределяемой памяти, делая доступной ос- тавшуюся ее часть. После запуска программы необходимо вызвать Init- DosMem для передачи всей динамической памяти Вашей програм- ме. С примером использования InitDosMem и DoneDosMem можно озна- комиться на примере реализации TApplication.DosShell в APP.PAS. См. также: процедуру DoneDosMem, процедуру SetMemTop *- Процедура DoneEvents Drivers ----------------------------------------------------------------- Описание: procedure DoneEvents; Функция: Завершает работу администратора событий Turbo Visi- on, отключая обработчик прерываний "мыши". Вызывается автоматиче- ски при вызове TApplication.Done. См. также: TApplication.Done, InitEvents *- Процедура DoneHistory Drivers ----------------------------------------------------------------- Описание: procedure DoneHistory; Функция: Освобождает блок протокола (предыстории), выделен- ный InitHistory. Вызывается автоматически при вызове TApplicatio- n.Done. См. также: Процедура InitHistory, TApplication.Done *- Процедура DoneMemory Memory ----------------------------------------------------------------- Описание: procedure DoneMemory; Функция: Завершает работу администратора памяти Turbo Visi- on, освобождая все буфера, выделенные с помощью GetBufMem. Вызы- вается автоматически при вызове TApplication.Done. См. также: TApplication.Done, InitMemory *- Процедура DoneSysError Drivers ----------------------------------------------------------------- Описание: procedure DoneSysError; Функция: Завершает выполнение обработчика системных ошибок Turbo Vision, восстанавливая векторы прерываний 09H, 1BH, 21H, 23H, 24H и восстанавливая состояние Ctrl-Break в DOS. Вызывается автоматически при вызове TApplication.Done. См. также: TApplication.Done, InitSysError *- Процедура DoneVideo Drivers ----------------------------------------------------------------- Описание: procedure DoneVideo; Функция: Завершает выполнение администратора экрана Turbo Vision, восстанавливая начальный режим экрана (заданный в Startu- pMode), очищая экран и восстанавливая курсор. Вызывается автома- тически при вызове TApplication.Done. См. также: TApplication.Done, InitVideo, переменная StartupMode *- Переменная DoubleDelay Drivers ----------------------------------------------------------------- Описание: DoubleDelay: Word = 8; Функция: Определяет временной интервал (в единицах 1/18.2 секунд) между нажатиями кнопки "мыши" для того, чтобы различить двойное нажатие кнопки "мыши" и два отдельных последовательных нажатия. Используется GetMouseEvent для генерации события Double, если нажатия произошли в этом временном интервале. См. также: TEvent.Double, GetMouseEvent *- Константы dpXXXX Dialogs ----------------------------------------------------------------- ----------------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------------- dpBlueDialog 1 Фон диалогового окна синий dpCyanDialog 2 Фон диалогового окна голубой dpGrayDialog 3 Фон диалогового окна серый ----------------------------------------------------------------- Функция: Объекты диалоговых окон используют константы dpXXXX для указания той из трех стандартных палитр, которую необходимо использовать. По умолчанию объекты диалоговых окон используют dpGrayDialog. Можно выбрать любую другую из стандартных палитр, задав поле Palette равным одной из констант dpXXXX после констру- ирования объекта диалогового окна. *- Переменная EditorDialog Editors ----------------------------------------------------------------- Описание: EditorDialog: TEditorDialog = DefEditorDialog; Функция: EditorDialog является процедурной глобальной пере- менной. Она хранит функцию диалогового окна редактора, определен- ную для всех редакторов программы. По умолчанию EditorDialog хранит функцию DefEditorDialog, которая обходит выдачу на экран диалоговых окон и возвращает cmCancel. Turbo Vision также обеспечивает удобный набор диалоговых окон редактора посредством функции SetEditorDialog. См. также: функцию SetEditorDialog *- Переменная EditorFlags Editors ----------------------------------------------------------------- Описание: EditorFlags: Word = efBackupFiles + efPromptOnReplace; Функция: EditorDialog является битовой глобальной перемен- ной, управляющей поведением объекта редактора внутри всей програ- ммы. Биты определены константами efXXXX. По умолчанию EditorFlags заставляет сохранять страховые копии редактируемых файлов и перед заменой текста в операциях поиска-замены выдает запрос. См. также: константы efXXXX *- Константы edXXXX Editors ----------------------------------------------------------------- Функция: Объект редактора передает эти константы функции EditorDialog с целью определения того, какое из возможных диало- говых окон будет выдавать функция. Стандартные диалоговые окна редактора, обеспечиваемые StdEditorDialog, отвечают на все эти константы. Их необходимо использовать только в том случае, если Вы пишите собственные диалоговые окна редактора. ----------------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------------- edOutOfMemory 0 Выдает предупреждение "out of memory" edReadError 1 Ошибка чтения файла edWriteError 2 Ошибка записи в файл edCreateError 3 Ошибка создания файла edSaveModify 4 Закрываемый файл не сохранен edSaveUntitled 5 Закрывается файл без имени; сделать запрос о сохранении edSaveAs 6 Сохранение файла с новым именем или сохранение в первый раз edFind 7 Выдать пользователю запрос об искомом тексте edSearchFailed 8 Выдать пользователю сообщение о том, что искомая строка не найдена edReplace 9 Выдать пользователю запрос о тексте для поиска и замены edReplacePrompt 10 Выдать пользователю запрос о замене найденного текста ----------------------------------------------------------------- См. также: переменную EditorDialog, тип TEditorDialog *- Константы efXXXX Editors ----------------------------------------------------------------- Функция: Константы флагов редактора используются для управ- ления битовой глобальной переменной EditorFlags. Большая часть этих флагов влияет на работу операций поиска и замены, а один флаг определяет, создавать ли страховые копии файлов. ----------------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------------- efCaseSensitive $0001 Считает строчные и прописные буквы различными. efWholeWordsOnly $0002 Осуществляется поиск лишь целых слов (разделенных пробелами, символами табуляции или конца строки). efPromptOnReplace $0004 Перед заменой текста выдавать пользователю запрос. efReplaceAll $0008 Осуществлять поиск и замену всех найденных элементов поиска. efDoReplace $0010 Текст для замены найден. Используется TEditor. efBackupFiles $0100 Создавать страховые копии редактируемых файлов с расширением .BAK ----------------------------------------------------------------- Рис. 19.3. Битовые флаги редактора. ЙНННСНСНСНСНСНСНСНСНСНСНСНСНСНСНСННН» єmsbі і і і і і і і і і і і і і і1sbє ИНННПНПНПНПНПНПНПСПНПНПНПСПСПСПСПНСНј і і і і і АДДДefCaseSensitive = $0001 і і і і АДДДДДДefWholeWordsOnly= $0002 і і і АДДДДДДДДefPromptOnReplace=$0004 і і АДДДДДДДДДДefReplaceAll = $0008 і АДДДДДДДДДДДДefDoReplace = $0010 АДДДДДДДДДДДДДДДДДДДДefBackupFiles = $0100 *- Переменная EmsCurHandle Objects ----------------------------------------------------------------- Описание: EmsCurhandle: Word = $FFFF; Функция: Содержит текущий идентификатор EMS, отображенный TEmsStream в нулевую физическую страницу памяти EMS. TEmsStream избегает изменения структуры EMS с помощью сохранения состояния EMS. Если Ваша программа использует расширенную память (EMS) для других целей, установите EmsCurHandle и EmsCurPage равными $FFFF перед использованием TEmsStream- это будет вынуждать TEmsStream восстанавливать свое состояние. См. также: TEmsStream.Handle *- Переменная EmsCurPage Objects ----------------------------------------------------------------- Описание: EmsCurpage: Word = $FFFF; Функция: Содержит текущий номер логической страницы EMS, отображенной TEmsStream в нулевую физическую страницу памяти EMS. TEmsStream избегает изменения структуры EMS с помощью сохранения состояния EMS. Если Ваша программа использует расширенную память (EMS) для других целей, установите EmsCurHandle и EmsCurPage равными $FFFF перед использованием TEmsStream- это будет вынуж- дать TEmsStream восстанавливать свое состояние. См. также: TEmsStream.Page *- Переменная ErrorAttr Views ----------------------------------------------------------------- Описание: const ErrorAttr: Byte = $CF; Функция: Содержит байт видео атрибута, используемый в качес- тве значения, возвращаемого при ошибке вызова метода отображаемо- го элемента GetColor. Если GetColor не удается правильно отобра- зить индекс палитры в байт видео атрибута (вследствие выхода индекса за разрешенные пределы), то он возвращает ошибку в Erro- rAttr. Заданное по умолчанию значение ErrorAttr дает ярко-белые символы на красном фоне. Если Вы видите на экране эту цветовую комбинацию, то это, вероятнее всего, указывает на ошибку выбора палитры. См. также: TView.GetColor *- Константы evXXXX Drivers ----------------------------------------------------------------- Функция: Эти мнемоники обозначают типы событий для обработ- чиков событий Turbo Vision. Константы evXXXX используются в нес- кольких местах: - в поле What записи события - в поле EventMask отображаемого элемента - в переменных PositionalEvents и FocusedEvents. Значения: Следующие значения флагов событий обозначают стан- дартные типы событий: Таблица 19.11. Флаги стандартных событий. ------------------------------------------------------------ Константа Значение Смысл ------------------------------------------------------------ evMouseDown $0001 Кнопка "мыши" нажата evMouseUp $0002 Кнопка "мыши" отпущена evMouseMove $0004 "Мышь" изменила положение evMouseAuto $0008 Периодическое событие в то время, пока нажата кнопка "мыши" evKeyDown $0010 Клавиша нажата evCommand $0100 Событие-команда evBroadcast $0200 Событие-уведомление ------------------------------------------------------------ Следующие константы могут использоваться для маскирования типов событий: Таблица 19.12. Маски стандартных событий. ------------------------------------------------------------ Константа Значение Смысл ------------------------------------------------------------ evNothing $0000 Событие уже обработано evMouse $000F Событие от "мыши" evKeyboard $0010 Событие от клавиатуры evMessage $FF00 Событие-сообщение (команда, уведомление или событие, определенное пользователем). ------------------------------------------------------------ Биты маски события определены следующим образом: Рис. 19.4. Биты маски событий. ЪДВДВДВДВДВДВДВДДДДДДДДДДДДДДДДДДДДД> evMessage = $FF00 і і і і і і і і ЪДДДДДДДДДДДДД> evKeyboard = $0010 і і і і і і і і і ЪДВДВДДДВДДД> evMouse = $000F ЙНННПСПСПСПСПСПСПСПСНСНСНСПСПСПСПСННП» єmsb і і і і і і і і і і і і і і і1sbє ИННННПНПНПНПНПНПСПСПНПНПНПСПСПСПСПННСј і і і і і і АДДД> evMouseDown = $0001 і і і і і АДДДДДДД> evMouseUp = $0002 і і і і АДДДДДДДДД> evMouseMove = $0004 і і і АДДДДДДДДДДД> evMouseAuto = $0008 і і АДДДДДДДДДДДДД> evKeyDown = $0010 і АДДДДДДДДДДДДДДДДДДДДД> evCommand = $0100 АДДДДДДДДДДДДДДДДДДДДДДД> evBroadcast = $0200 Маски стандартных событий могут быть использованы для быст- рого определения того, принадлежит ли событие конкретному семейс- тву событий. Например: if Event.What and evMouse <> 0 then DoMouseEvent; См. также: методы TEvent, TView.EventMask, GetKeyEvent, GetMouseEvent, HandleEvent, PositionalEvents, FocusedEvents. *- Константы fdXXXX StdDlg ----------------------------------------------------------------- Функция: Константы fdXXXX передаются конструктору объектов TFileDialog в параметре AOptions. ------------------------------------------------------------ Константа Значение Смысл ------------------------------------------------------------ fdOkButton $0001 Включить в диалоговое окно кнопку "OK" fdOpenButton $0002 Включить в диалоговое окно кнопку "Open" fdReplaceButton $0004 Включить в диалоговое окно кнопку "Replace" fdClearButton $0008 Включить в диалоговое окно кнопку "Clear" fdHelpButton $0010 Включить в диалоговое окно кнопку "Help" fdNoLoadDir $0100 При работе Init не загружать в диалоговое окно содержимое текущего каталога. Это означает, что Вы собираетесь изменить WildCard при помощи SetData или сохранить диалоговое окно в потоке. ------------------------------------------------------------ Рис. 19.5. Флаги опций диалогового окна файлов ЙННННСНСНСНСНСНСНСНСНСНСНСНСНСНСНСННН» єmsb і і і і і і і і і і і і і і і1sbє ИННННПНПНПНПНПНПНПСПНПНПНПСПСПСПСПННСј і і і і і АДДД> fdOkButton = $0001 і і і і АДДДДДДД> fdOpenButton = $0002 і і і АДДДДДДДДД> fdReplaceButton=$0004 і і АДДДДДДДДДДД> fdClearButton = $0008 і АДДДДДДДДДДДДД> fdHelpButton = $0010 АДДДДДДДДДДДДДДДДДДДДД> fdNoLoadDir = $0100 См. также: TFileDialog *- Переменная FindStr Editors ----------------------------------------------------------------- Описание: FindStr: string [80] = ''; Функция: FindStr содержит последнюю строку, найденную при работе операций поиска. *- Тип FNameStr Objects ----------------------------------------------------------------- Описание: FNameStr = string[79]; Функция: Строка, содержащая имя файла DOS. *- Переменная FocusedEvents Views ----------------------------------------------------------------- Описание: FocusedEvents: Word = evKeyboard + evCommand; Функция: Определяет классы событий, являющиеся текущими событиями. Переменные FocusedEvents и PositionalEvents использую- тся методом TGroup.HandleEvent для определения того, как переда- вать события подэлементам группы. Если класс события не содержит- ся в FocusedEvents или PositionalEvents, то оно интерпретируется, как простое сообщение. См. также: Переменную PositionalEvents, TGroup.HandleEvent, TEvent, константы evXXXX. *- Процедура FormatStr Drivers ----------------------------------------------------------------- Описание: procedure FormatStr(var Result: String; Format: String; var Params); Функция: Общая процедура форматирования строки, которая работает подобно функции языка Си vsprintf. Format включает опи- сатели формата, а Params содержит список параметров. FormatStr выполняет форматированный вывод строки в Result. Параметр Format может содержать любое число описателей фор- мата, используемых для отображения параметров в Params. Формат описателей- %[-][nnn]X, где % указывает на начало описателя формата; [-] - необязательный знак минуса, указывающий на тот факт, что параметр будет выравнен по левой границе (по умолчанию пара- метры при отображении выравниваются по правой границе); [nnn] - необязательный десятичный описатель длины в диапазо- не 0 - 255 (0 указывает на то, что длина не указана, а ненулевая величина означает, что выводится поле длиной в nnn символов); - Х - символ формата: - 's' означает, что параметр является указателем на строку; - 'd' означает, что параметр типа LongInt выводится в деся- тичном представлении; - 'c' означает, что младший байт параметра- символ; - 'x' означает, что параметра типа LongInt выводится в шестнадцатиричном представлении; - '#'устанавливает индекс параметра равным nnn. Например, если параметр указывает на строку, содержащую 'spiny', следующая таблица показывает различные описатели и резу- льтат их применения при печати: Таблица 19.13. Описатели формата их результат их применения. ----------------------------------------- Описатель Результат ----------------------------------------- %6s ' spiny' %-6s 'spiny' %3s 'iny' %-3s 'spi' %06s '0spiny' %-06s 'spiny0' ----------------------------------------- Params- это нетипизированный параметр-переменная, содержащий достаточно параметров для того, чтобы удовлетворить любому описа- телю формата из Format. Params должен быть массивом из LongInt или указателей или записью, содержащей LongInt или указатели. Например, для вывода строки сообщения об ошибке: Error in file [file name] at line [line number] Вы должны передать Format следующую строку: 'Error in file %s at line %d'. Params должен содержать указатель на строку имени файла и параметр Longint, представляющий собой номер строки в файле. Это может быть сделано двумя способами: в массиве или в записи. Следующий пример показывает эти два типа описаний и присваи- ваний переменных, оба из которых создают допустимые значения, передаваемые в FormatStr в качестве параметра Params. type ErrMsgRec = record FileName: PString; LineNo: Longint; end; ErrMsgArray = array[0..1] of Longint; const TemplateMsg = 'Error in file %s at line %d'; var MyFileName: FNameStr; OopsRec: ErrMsgRec; DarnArray: ErrMsgArray; TestStr: String; begin MyFileName := 'WARTHOG.ASM'; with OopsRec do begin FileName := @MyFileName; LineTo := 42; end; FormatStr(TestStr, TemplateMsg, OopsRec); Writeln(TestStr); DarnArray[0] := Longint(@MyFileName); DarnArray[1] := 24; FormatStr(TestStr, TemplateMsg, DarnArray); Writeln(TestStr); end; См. также: Функцию SystemError, объект TParamText. *- Процедура FreeBufMem Memory ----------------------------------------------------------------- Описание: procedure FreeBufMem(P: Pointer); Функция: Освобождает кэш-буфер, на который ссылается указа- тель Р, посредством вызова DisposeCache. FreeBufMem введена для обеспечения совместимости с предшествующими версиями Turbo Vision; вместо использования ее нужно непосредственно вызвать DisposeCache. См. также: процедуру DisposeCache *- Функция: GetAltChar Drivers ----------------------------------------------------------------- Описание: function GetAltChar(KeyCode: Word): Char; Функция: Возвращает символ Ch, для которого Alt-Ch вырабаты- вает двухбайтовый код, заданный в аргументе KeyCode. Эта функция дает преобразование, обратное GetAltCode. См. также: GetAltCode. *- Функция: GetAltCode Drivers ----------------------------------------------------------------- Описание: function GetAltCode(Ch: Char): Word; Функция: Возвращает двухбайтовый скан-код, соответствующий Alt-Ch. Эта функция дает преобразование, обратное GetAltChar. См. также: GetAltChar. *- Функция: GetBufferSize Memory ----------------------------------------------------------------- Описание: function GetBufferSize (P: Pointer): Word; Функция: Возвращает размер буфера P^ в байтах. P должен указывать на буфер, выделенный с помощью процедуры NewBuffer. См. также: процедуру NewBuffer. *- Процедура GetBufMem Memory ----------------------------------------------------------------- Описание: procedure GetBufMem(var P: Pointer; Size: Word); Функция: Выделяет кэш-буфер размером Size байт, и сохраняет указатель на него в Р посредством вызова NewCache. GetBufMem введена для обеспечения совместимости с предшествующими версиями Turbo Vision; вместо использования ее нужно непосредственно выз- вать NewCache. См. также: процедуру NewCache *- Процедура GetKeyEvent Drivers ----------------------------------------------------------------- Описание: procedure GetKeyEvent(var Event: TEvent); Функция: Проверяет, доступно ли событие от клавиатуры посре- дством вызова прерывания BIOS INT 16H. Если клавиша была нажата, то Event.What устанавливается равным evKeyDown, а Event.KeyCode устанавливается равным значению скан-кода клавиши. В противном случае, Event.What устанавливается равным evNothing. Процедура GetKeyEvent вызывается TProgram.GetEvent. См. также: TProgramm.GetEvent, константы evXXXX, TView.HandleEvent. *- Процедура GetMouseEvent Drivers ----------------------------------------------------------------- Описание: procedure GetMouseEvent(var Event: TEvent); Функция: Проверяет, доступно ли событие от "мыши" из очереди событий "мыши", поддерживаемой обработчиком событий Turbo Vision. Если происходит событие от "мыши", то Event.What устанавливается равным evMouseDown, evMouseUp, evMouseMove или evMouseAuto; Event.Buttons устанавливается равным mbLeftButton или mbRightButton; Event.Double устанавливается равным True или False. Event.Where устанавливается равным положению "мыши" в гло- бальных координатах (соответствующих координатной системе TApplication). Если события от "мыши" недоступны, то Event.What устанавливается равным evNothing. GetMouseEvent вызывается из TProgram.GetEvent. См. также: TProgram.GetEvent, события evXXXX, методы HandleEvent. *- Константы gfXXXX Views ----------------------------------------------------------------- Функция: Эти мнемоники используются для установки полей GrowMode во всех объектах TView и порожденных объектах. Биты, установленные в GrowMode, определяют, как отображаемый элемент будет изменяться в зависимости от изменений размера его владель- ца. Значения: Биты GrowMode определены следующим образом: ЪДВДВДВДДД gfGrowAll = $0F ЙНСНСНСНСПСПСПСП» ИСПНПСПСПСПСПСПСј АДВДЩ і і і і АДДД gfGrowLoX = $01 і і і і АДДДДД gfGrowLoY = $02 Неопределены і і АДДДДДДД gfGrowHiX = $04 і АДДДДДДДДД gfGrowHiY = $08 АДДДДДДДДДДД gfGrowRel = $10 Рис. 19.6. Биты режима Grow. Таблица 19.14. Определения флагов режима Grow. ----------------------------------------------------------------- Константа Назначение ----------------------------------------------------------------- gfGrowLoX Если установлен, то левая сторона отображаемого элемента будет находиться на постоянном расстоянии от правой стороны владельца. gfGrowLoY Если установлен, то верхняя сторона отображаемого элемента будет находиться на постоянном расстоянии от нижней стороны владельца. gfGrowHiX Если установлен, то правая сторона отображаемого элемента будет находиться на постоянном расстоянии от правой стороны владельца. gfGrowHiY Если установлен, то нижняя сторона отображаемого элемента будет находиться на постоянном расстоянии от нижней стороны владельца gfGrowAll Если установлен, то отображаемый элемент будет сдвигаться вместе с правым нижним углом его владельца. gfGrowRel Для использования с объектами TWindow, которые находятся в оперативной области экрана: отображаемый элемент будет изменять относительный размера относительно владельца. Окно будет обрабатываться соответственно размеру владельца, даже когда происходит переключение между режимами 25 и 43/50 строк. ----------------------------------------------------------------- Заметим, что LowX = левая сторона; LowY = верхняя сторона; HiX = правая сторона; HiY = нижняя сторона. См. также: TView.GrowMode *- Константы hcXXXX App ----------------------------------------------------------------- Функция: Пункты меню, определенные с помощью стандартных функций работы с пунктами меню StdFileMenuItems, StdEditeMenuItems и StdWindowMenuItems приписывают каждому из них контексты подсказки. Для каждого из стандартных пунктов меню модуль App определяет константы, начинающиеся с hc. Внимание! Диапазоны контекста подсказки 0...999 и $FF00...$FFFF зарезервированы для Turbo Vision. Значения: В модуле App определены три набора контекстов подсказки для стандартных пунктов меню File, Edit и Window. Их значения показаны в следующих таблицах: Таблица 19.15. Контексты подсказки стандартного меню File ------------------------------------------------------------ Константа Значение Смысл ------------------------------------------------------------ hcNew $FF01 File|New hcOpen $FF02 File|Open hcSave $FF03 File|Save hcSaveAs $FF04 File|Save As hcSaveAll $FF05 File|Save All hcChangeDir $FF06 File|Change Dir hcDosShell $FF07 File|Dos Shell hcExit $FF08 File|Exit ------------------------------------------------------------ Таблица 19.16. Контексты подсказки стандартного меню Edit ------------------------------------------------------------ Константа Значение Смысл ------------------------------------------------------------ hcUndo $FF10 Edit|Undo hcCut $FF11 Edit|Cut hcCopy $FF12 Edit|Copy hcPaste $FF13 Edit|Paste hcClear $FF14 Edit|Clear ------------------------------------------------------------ Таблица 19.17. Контексты подсказки стандартного меню Window ------------------------------------------------------------ Константа Значение Смысл ------------------------------------------------------------ hcTile $FF20 Window|Tile hcCascade $FF21 Window|Cascade hcCloseAll $FF22 Window|Close All hcResize $FF23 Window|Resize hcZoom $FF24 Window|Zoom hcNext $FF25 Window|Next hcPrev $FF26 Window|Prev hcClose $FF27 Window|Close ------------------------------------------------------------ *- Константы hcXXXX Views ----------------------------------------------------------------- Значения: Определены следующие константы контекста подсказ- ки: Таблица 19.18. Константы контекста подсказки. ----------------------------------------- Константа Значение Назначение ----------------------------------------- hcNoContext 0 Контекст не задан hcDragging 1 Объект перемещаем ----------------------------------------- Функция: Значение TView.HelpCtx по умолчанию- hcNoContext, которое указывает на тот факт, что для отображаемого элемента нет контекста подсказки. TView.GetHelpCtx возвращает hcDragging при каждом перемещении отображаемого элемента (это указывается состо- янием флага sfDragging). Turbo Vision резервирует для контекста подсказки значения от 0 до 999. Программисты могут определять свои константы в диапазо- не от 1000 до 65535. См. также: TView.HelpCtx, TStatusLine.Update. *- Процедура HideMouse Drivers ----------------------------------------------------------------- Описание: procedure HideMouse; Функция: Курсор "мыши" изначально является видимым после вызова InitEvents. HideMouse делает невидимым курсор "мыши" и увеличивает внутренний счетчик "спрятываний мыши" в драйвере "мыши". ShowMouse будет уменьшать значение этого счетчика и пока- зывать курсор "мыши", когда счетчик становится равным 0. Таким образом, вызовы HideMouse и ShowMouse могут быть парными, но всегда количества их вызовов должны быть равны. См. также: InitEvents, DoneEvents, ShowMouse *- Переменная HiResScreen Drivers ----------------------------------------------------------------- Описание: HiResScreen: Boolean; Функция: Устанавливается равным True с помощью InitVideo, если экран поддерживает режим 43/50 строк (EGA/VGA); в противном случае устанавливается равным False. См. также: InitVideo *- Процедура HistoryAdd HistList ----------------------------------------------------------------- Описание: procedure HistoryAdd(Id: Byte; var Str: String); Функция: Добавляет строку Str в список протокола, на который указывает Id. См. также: функцию HistoryStr, функцию HistoryCount *- Переменная HistoryBlock HistList ----------------------------------------------------------------- Описание: HistoryBlock: Pointer = nil; Функция: Указывает на буфер, называемый блоком протокола и используемый для хранения строк протокола. Размер блока определя- ется с помощью HistorySize. Указатель равен nil до тех пор, пока он не будет установлен с помощью InitHistory. Его значение не следует изменять. См. также: процедуру InitHistory, переменную HistorySize. *- Функция HistoryCount HistList ----------------------------------------------------------------- Описание: function HistoryCount(Id: Byte): Word; Функция: Возвращает количество строк в списке протокола, соответствующее номеру ID. *- Переменная HistorySize HistList ----------------------------------------------------------------- Описание: HistorySize: Word = 1024; Функция: Указывает размер блока протокола, используемый администратором списка протокола для хранения значений, введенных в строках ввода. Размер фиксируется посредством InitHistory при запуске программы. По умолчанию размер блока равен 1К, но он может быть изменен перед вызовом InitHistory. Это значение не следует изменять после вызова InitHistory. См. также: процедуру InitHistory, переменную HistoryBlock. *- Функция HistoryStr HistList ----------------------------------------------------------------- Описание: function HistoryStr(Id: Byte; Index: Integer): String; Функция: Возвращает строку из списка протокола с номером Index с Id, равным ID. См. также: процедуру HistoryAdd, процедуру HistoryCount *- Переменная HistoryUsed HistList ----------------------------------------------------------------- Описание: HistoryUsed: Word = 0; Функция: Служит для внутреннего использования администрато- ром списка протокола (для указания на смещение внутри блока про- токола). Это значение не следует изменять. *- Процедура InitDosMem Memory ----------------------------------------------------------------- Описание: procedure InitDosMem; Функция: Передает программе всю динамически распределяемую память после выхода в оболочку DOS или запуска другой программы посредством вызова SetMemTop, помещающей конец динамически расп- ределяемой памяти в начало доступной памяти. С примером использо- вания InitDosMem и DoneDosMem можно ознакомиться на примере реа- лизации TApplication.DosShell в APP.PAS. См. также: процедуру DoneDosMem, процедуру SetMemTop *- Процедура InitEvents Drivers ----------------------------------------------------------------- Описание: procedure InitEvents; Функция: Инициализирует администратор событий Turbo Vision, подключая обработчик прерываний "мыши" и показывая курсор "мыши". Вызывается автоматически TApplication.Init. См. также: DoneEvents. *- Процедура InitHistory HistList ----------------------------------------------------------------- Описание: InitHistory; Функция: Вызывается с помощью TApplication.Init для выделе- ния блока динамически распределяемой памяти, используемого адми- нистратором управления списком протокола (предыстории). Размер блока определяется переменной HistorySize. После вызова InitHis- tory переменная HistoryBlock указывает на начало блока. См. также: TProgram.Init, процедуру DoneHistory. *- Процедура InitMemory Memory ----------------------------------------------------------------- Описание: procedure InitMemory; Функция: Инициализирует администратор памяти Turbo Vision, устанавливая функцию динамически распределяемой памяти HeapError. Вызывается автоматически посредством TApplication.Init. См. также: DoneMemory. *- Процедура InitSysError Drivers ----------------------------------------------------------------- Описание: procedure InitSysError; Функция: Инициализирует обработчик системных ошибок Turbo Vision, захватывая векторы прерываний 09H, 1BH, 21H, 23H, 24H и отключая состояние Ctrl-Break из DOS. Вызывается автоматически посредством TApplication.Init. См. также: DoneSysError. *- Процедура InitVideo Drivers ----------------------------------------------------------------- Описание: procedure InitVideo; Функция: Инициализирует администратор экрана Turbo Vision. Сохраняет текущий режим экрана в StartupMode и переключает экран в режим, указанный в ScreenMode. Переменные ScreenWidth, ScreenHeight, HiResScreen, CheckSnow, ScreenBuffer и CursorLines корректируются соответственно. Режим экрана позднее может быть изменен использованием SetVideoMode. InitVideo вызывается автома- тически посредством TApplication.Init. См. также: DoneVideo, SetVideoMode, smXXXX. *- Функция InputBox MsgBox ----------------------------------------------------------------- Описание: function InputBox (const Title, ALabel: String; var S: String; Limit: Byte): Word; Функция: Выдает на экран диалоговое окно размером 60*8 с полем заголовка из Title, текстом метки из ALabel, и имеющее кнопку "OK", кнопку "Cancel" и одну строку для ввода текста, первоначально содержащую строку из S. Возвращает значение, возв- ращенное ExecView по окончании выдачи диалогового окна. Если пользователь не закрывает это диалоговое окно, то S содержит строку, введенную пользователем. Limit указывает максимальное количество символов во введенной строке. *- Функция InputBoxRect MsgBox ----------------------------------------------------------------- Описание: function InputBoxRect (var Bounds: TRect; const Title, ALabel: String; var S: String; Limit: Byte): Word; Функция: Работает точно так же, как и InputBox, но позволяет также указывать прямоугольник, ограничивающий диалоговое окно. См. также: функцию InputBox *- Константы kbXXXX Drivers ----------------------------------------------------------------- Функция: Два набора констант, начинающихся с "kb", связаны с клавиатурой. Значения: Следующие значения определяют состояние клавиатуры и могут быть использованы при анализе регистров Shift клавиатуры, которые запоминается в байте с абсолютным адресом Seg0040: $17. Например: var ShiftState: Byte absolute Seg0040:$17; ... if ShiftState and kbAltShift <> 0 then AltKeyDown; Таблица 19.19. Состояние клавиатуры и маски Shift. ------------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------------ kbRightShift $0001 Установлено, если правая клавиша Shift нажата kbLeftShift $0002 Установлено, если левая клавиша Shift нажата kbCtrlShift $0004 Установлено, если нажата клавиша Ctrl kbAltShift $0008 Установлено, если нажата клавиша Alt kbScrollState $0010 Установлено, если клавиатура находится в состоянии ScrollLock kbNumState $0020 Установлено, если клавиатура находится в состоянии NumLock kbCapsState $0040 Установлено, если клавиатура находится в состоянии CapsLock kbInsState $0080 Установлено, если клавиатура в состоянии InsLock ----------------------------------------------------------------- Рис. 19.7. Флаги маски состояния клавиатуры ЙНННСНСНСНСНСНСНСНСНСНСНСНСНСНСНСННН» єmsbі і і і і і і і і і і і і і і1sbє ИНННПНПНПНПНПНПНПНПСПСПСПСПСПСПСПНСНј і і і і і і і АДДДkbRightShift = $0001 і і і і і і АДДДДДДkbLeftShift = $0002 і і і і і АДДДДДДДДkbCtrlShift = $0004 і і і і АДДДДДДДДДДkbAltShift = $0008 і і і АДДДДДДДДДДДДkbScrollState = $0010 і і АДДДДДДДДДДДДДДkbNumState = $0020 і АДДДДДДДДДДДДДДДДkbCapsState = $0040 АДДДДДДДДДДДДДДДДДДkbInsState = $0080 Следующие значения определяют скан-коды клавиатуры и могут использоваться для анализа поля TEvent.KeyCode записи события evKeyDown: Таблица 19.20. Коды клавиш Alt-буква. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAltA $1E00 kbAltN $3100 kbAltB $3000 kbAltO $1800 kbAltC $2E00 kbAltP $1900 kbAltD $2000 kbAltQ $1000 kbAltE $1200 kbAltR $1300 kbAltF $2100 kbAltS $1F00 kbAltG $2200 kbAltT $1400 kbAltH $2300 kbAltU $1600 kbAltI $1700 kbAltV $2F00 kbAltJ $2400 kbAltW $1100 kbAltK $2500 kbAltX $2D00 kbAltL $2600 kbAltY $1500 kbAltM $3200 kbAltZ $2C00 ----------------------------------------------------------- Таблица 19.21. Коды специальных клавиш. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAltEqual $8300 kbEnd $4F00 kbAltMinus $8200 kbEnter $1C0D kbAltSpace $0200 kbEsc $011B kbBack $0E08 kbGrayMinus $4A2D kbCtrlBack $0E7F kbHome $4700 kbCtrlDel $0600 kbIns $5200 kbCtrlEnd $7500 kbLeft $4B00 kbCtrlEnter $1C0A kbNoKey $0000 kbCtrlHome $7700 kbPgDn $5100 kbCtrlIns $0400 kbPgUp $4900 kbCtrlLeft $7300 kbrayPlus $4E2B kbCtrlPgDn $7600 kbRight $4D00 kbCtrlPgUp $8400 kbShiftDel $0700 kbCtrlPrtSc $7200 kbShiftIns $0500 kbCtrlRight $7400 kbShiftTab $0F00 kbDel $5300 kbTab $0F09 kbDown $5000 kbUp $4800 ----------------------------------------------------------- Таблица 19.22. Коды клавиш Alt-число. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAlt1 $7800 kbAlt6 $7D00 kbAlt2 $7900 kbAlt7 $7E00 kbAlt3 $7A00 kbAlt8 $7F00 kbAlt4 $7B00 kbAlt9 $8000 kbAlt5 $7C00 kbAlt0 $8100 ----------------------------------------------------------- Таблица 19.23. Коды функциональных клавиш. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbF1 $3B00 kbF6 $4000 kbF2 $3C00 kbF7 $4100 kbF3 $3D00 kbF8 $4200 kbF4 $3E00 kbF9 $4300 kbF5 $3F00 kbF10 $4400 ----------------------------------------------------------- Таблица 19.24. Коды клавиш Shift-функциональная клавиша. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbShiftF1 $5400 kbShiftF6 $5900 kbShiftF2 $5500 kbShiftF7 $5A00 kbShiftF3 $5600 kbShiftF8 $5B00 kbShiftF4 $5700 kbShiftF9 $5C00 kbShiftF5 $5800 kbShiftF10 $5D00 ----------------------------------------------------------- Таблица 19.25. Коды клавиш Ctrl-функциональная клавиша. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbCtrlF1 $5E00 kbCtrlF6 $6300 kbCtrlF2 $5F00 kbCtrlF7 $6400 kbCtrlF3 $6000 kbCtrlF8 $6500 kbCtrlF4 $6100 kbCtrlF9 $6600 kbCtrlF5 $6200 kbCtrlF0 $6700 ----------------------------------------------------------- Таблица 19.26. Коды клавиш Alt-функциональная клавиша. ----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAltF1 $6800 kbAltF6 $6D00 kbAltF2 $6900 kbAltF7 $6E00 kbAltF3 $6A00 kbAltF8 $6F00 kbAltF4 $6B00 kbAltF9 $7000 kbAltF5 $6C00 kbAltF10 $7100 ----------------------------------------------------------- См. также: evKeyDown, GetKeyEvent. *- Процедура LoadHistory HistList ----------------------------------------------------------------- Описание: procedure LoadHistory (var S: TStream); Функция: Читает из потока S блок предыстории программы, причем сначала читает размер блока, а затем сам блок. Устанавли- вает HistoryUsed на конец прочитанного блока. Для восстановления блока предыстории, сохраненного с помощью StoreHistory, исполь- зуйте LoadHistory. См. также: переменную HistoryUsed, процедуру StoreHistory *- Процедура LoadIndexes ColorSel ----------------------------------------------------------------- Описание: procedure LoadIndexes (var S: TStream); Функция: Загружает набор индексов из потока S и сохраняет его в переменной ColorIndexes. Сохранив и восстановив ColorIndexes в потоке, программа может восстановить состояние выбора цветов диалогового окна, что позволит пользователю легко изменять и восстанавливать изменения цветов. См. также: переменную ColorIndexes, процедуру StoreIndexes *- Функция: LongDiv Objects ----------------------------------------------------------------- Описание: function LongDiv(X: Longint; Y: Integer): Integer; inline($59/$58/$5A/$F7/$F9); Функция: быстрая ассемблерная процедура деления, возвращаю- щая целое значение X/Y. *- Функция: LongMul Objects ----------------------------------------------------------------- Описание: function LongMul(X, Y: Integer): Longint; inline($5A/$58/$F7/$EA); Функция: быстрая ассемблерная процедура умножения, возвраща- ющая длинное целое значение X*Y. *- Тип LongRec Objects ----------------------------------------------------------------- Описание: LongRec = record Lo, Hi: Word; end; Функция: Полезный тип записи для обработки переменных длиной в двойное слово. *- Функция: LowMemory Memory ----------------------------------------------------------------- Описание: function LowMemory: Boolean; Функция: Возвращает значение True, если память имеет младшие адреса, в противном случае False. True означает, что вызов функ- ции выделения памяти достиг области резервного буфера динамичес- кой памяти. Размер резервного буфера динамической памяти опреде- ляется переменной LowMemSize. См. также: Главу 7, "Обзор Turbo Vision", InitMemory, TView.Valid, LowMemSize. *- Переменная LowMemSize Memory ----------------------------------------------------------------- Описание: LowMemSize: Word = 4096 div 16; Функция: Устанавливает размер резервного буфера динамической памяти в 16- байтовых параграфах. Величина, установленная по умолчанию, представляет собой практически возможный минимум этой области, но она может быть увеличена для удовлетворения потребно- стям программы. См. также: InitMemory, область надежной памяти, TView.Valid, LowMemory *- Переменная MaxBufMem Memory ----------------------------------------------------------------- Описание: MaxBufMem: Word = 65536 div 16; Функция: Указывает максимальный объем памяти в 16-байтовых параграфах, которая может быть выделена для кэш-буферов. См. также: GetBufMem, FreeBufMem. *- Переменная MaxCollectionSize Objects ----------------------------------------------------------------- Описание: MaxCollectionSize = 65520 div SizeOf(Pointer); Функция: MaxCollectionSize определяет максимальное число элементов, которые может содержать набор, по существу это число указателей, которое помещается в сегменте памяти размером 64К. *- Переменная MaxHeapSize Memory ----------------------------------------------------------------- Описание: MaxHeapSize: Word = 65360 div 16; Функция: Определяет максимальный размер буфера динамически распределяемой памяти в 16- байтных параграфах. Буфера из динами- чески распределяемой памяти используются объектами редактора для выделения перемещаемых буферов с изменяемыми размерами, не затра- гивая динамическую память программы. См. также: процедуру NewBuffer, TFileEditor.InitBuffer *- Переменная MaxLineLength Editors ----------------------------------------------------------------- Описание: MaxLineLength = 256; Функция: MaxLineLength определяет максимальную длину строки в объекте редактора. *- Константа MaxViewWidth Views ----------------------------------------------------------------- Описание: MaxViewWidth = 132; Функция: Устанавливает максимальную ширину отображаемого элемента. См. также: поле TView.Size. *- Константы mbXXXX Drivers ----------------------------------------------------------------- Функция: Эти константы могут использоваться при анализе поля TEvent.Buttons записи события evMouse. if (Event.What = evMouseDown) and (Event.Button = mbLeftButton) then LeftButtonDown; Значения: Определены следующие константы: Таблица 19.27. Константы кнопок "мыши". -------------------------------------------------------------- Константа Значение Назначение -------------------------------------------------------------- mbLeftButton $01 Установлено, если была нажата левая кнопка mbRightButton $02 Установлено, если была нажата правая кнопка -------------------------------------------------------------- См. также: GetMouseEvent. *- Функция: MemAlloc Memory ----------------------------------------------------------------- Описание: function MemAlloc(Size: Word): Pointer; Функция: Выделяет Size байт динамически распределяемой обла- сти памяти и возвращает указатель на выделенный блок. Если блок требуемого размера не может быть выделен, то возвращается значе- ние nil. В отличие от стандартных процедур New и GetMem, MemAlloc не залазит в область резервного буфера динамической памяти. Блок, выделенный с помощью MemAlloc, может быть освобожден стандартной процедурой FreeMem. См. также: New, GetMem, Dispose, FreeMem, MemAllocSeg *- Функция: MemAllocSeg Memory ----------------------------------------------------------------- Описание: function MemAllocSeg(Size: Word): Pointer; Функция: Выделяет блок памяти, выровненный по границе сегме- нта. Соответствует MemAlloc, за исключением того, смещение резу- льтирующего значения указателя всегда равно 0. См. также: MemAlloc *- Переменная MenuBar App ----------------------------------------------------------------- Описание: MenuBar: PMenuView = nil; Функция: Сохраняет указатель на строку меню программы (нас- ледник TMenuView). Переменная MenuBar инициализируется с помощью TProgram.InitMenuBar, которая вызывается через TProgram.Init. Значение nil указывает на то, что программа не имеет строки меню. *- Функция MenuColorItems ColorSel ----------------------------------------------------------------- Описание: function MenuColorItem (const Next: PColorItem): PColorItem; Функция: Возвращает связанный список записей типа TColorItem для стандартных отображаемых элементов меню. Для программ, позво- ляющих пользователю изменять цвета меню с помощью диалогового окна изменения цветов, MenuColorItems упрощает процесс установки цветов. *- Функция: Message Views ----------------------------------------------------------------- Описание: function Message(Receiver: PView; What, Command: Word; InfoPtr: Pointer): Pointer; Функция: Message устанавливает запись события с аргументами What, Command или InfoPtr, а затем, если это возможно, вызывает Receiver^.HandleEvent для обработки этого события. Message возвращает значение nil, если Receiver имеет значе- ние nil или если событие не обработано успешно. Если событие успешно обработано (HandleEvent возвращает Event.What, равное evNothing), то Message возвращает Event.InfoPtr. Его можно испо- льзовать для определения того, каким отображаемым элементом обра- ботано событие, поскольку ClearEvent устанавливает InfoPtr указы- вающим на объект, который обработал событие. Аргумент What обычно устанавливается равным evBroadcast. Например, по умолчанию TscrollBar.ScrollDraw посылает следующее сообщение владельцу полосы прокрутки: Message(Owner, evBroadcast, cmScrollBarChanged, @Self); Это сообщение гарантирует, что соответствующие отображаемые элементы отобразятся заново, как только значение полосы прокрутки Value изменится. См. также: TView.HandleEvent, тип TEvent, константы cmXXXX, константы evXXXX. *- Функция: MessageBox MsgBox ----------------------------------------------------------------- Описание: function MessageBox (const Msg: String; Params: Pointer; AOptions: Word): Word; Функция: Выдает в центре экрана диалоговое окно размером 80*9. Диалоговое окно содержит сообщение, переданное в параметре Msg, и вставляет параметры, переданные в Param. AOptions содержит комбинации констант флагов сообщений mfXXXX, определяющих кнопки, которые появятся в диалоговом окне. Для включения параметров, переданных Msg в параметре Param, MessageBox использует процедуру FormatStr. См. также: константы mfXXXX, процедуру FormatStr *- Функция: MessageBoxRect MsgBox ----------------------------------------------------------------- Описание: function MessageBoxRect (var R: TRect; const Msg: String; Params: Pointer; AOptions: Word): Word; Функция: Работает так же, как и MessageBox, но позволяет задавать ограничивающий прямоугольник для диалогового окна. См. также: функцию MessageBox *- Константы mfXXXX MsgBox ----------------------------------------------------------------- Функция: Функции Turbo Vision для работы с окнами сообщений, MessageBox и MessageBoxRect, используют константы mfXXXX для описания типа выдаваемых сообщений и кнопок, появляющихся в окне. Значения: Следующие константы, передаваемые MessageBox в параметре AOptions, обозначают тип окна сообщений: --------------------------------------------------------------- Константа Значение Назначение --------------------------------------------------------------- mfWarning $0000 Выдавать окно предупреждений mfError $0001 Выдавать окно ошибок mfInformation $0002 Выдавать окно информации mfConfirmation $0003 Выдавать окно подтверждения --------------------------------------------------------------- Следующие константы, передаваемые MessageBox или MessageBox- Rect в параметре AOptions, определяют, какие кнопки появляются в окне сообщений: --------------------------------------------------------------- Константа Значение Назначение --------------------------------------------------------------- mfYesButton $0100 Помещать в диалоговое окно кнопку "Yes" mfNoButton $0200 Помещать в диалоговое окно кнопку "No" mfOKButton $0400 Помещать в диалоговое окно кнопку "OK" mfCancelButton $0800 Помещать в диалоговое окно кнопку "Cancel" mfYesNoCancel $0B00 Стандартное диалоговое окно "Yes", "No", "Cancel" mfOKCancel $0C00 Стандартное диалоговое окно "OK", "Cancel" --------------------------------------------------------------- Рис. 19.8. Флаги окна событий. ЪДДДДДДДДДДДДДДДДДДДДДДДДДДД> mfOKCancel =$0C00 ГДВДВДВДДДДДДДДДДДДДДДДДДДДД> mfYesNoCancel=$0B00 і і і і ЪДДДВДДД> mfConfirmation=$0003 ЙНННСНСНСНСПСПСПСПСНСНСНСНСНСНСПСННП» єmsbі і і і і і і і і і і і і і і1sbє ИНННПНПНПНПНПНПСПСПСПСПНПНПНПНПСПНСНј і і і і і АДДДД> mfError = $0001 і і і і АДДДДДДД> mfInformation= $0002 і і і АДДДДДДДДДДДДДДДДД> mfYesButton = $0100 і і АДДДДДДДДДДДДДДДДДДД> mfNoButton = $0200 і АДДДДДДДДДДДДДДДДДДДДД> mfOKButton = $0400 АДДДДДДДДДДДДДДДДДДДДДДД> mfCancelButton=$0800 См. также: функцию MessageBox, функцию MessageBoxRect *- Переменная MinWinSize Views ----------------------------------------------------------------- Описание: MInWinSize: TPoint = (X: 16; Y: 6); Функция: Определяет минимальный размер объекта окна. Значе- ние возвращается в параметре Min при вызове TWindow.SizeLimits. MinWinSize- глобальная переменная. Ее значение влияет на все окна, если только какой-либо тип окна не переопределяет SizeLimits, игнорируя MinWinSize. См. также: TWindow.SizeLimits *- Переменная MouseButtons Drivers ----------------------------------------------------------------- Описание: MouseButtons: Byte; Функция: Содержит текущее состояние кнопок "мыши". Значение MouseButtons обновляется обработчиком прерываний "мыши", при каждом нажатии или отпускании кнопки. Для анализа MouseButtons можно использовать константы mbXXXX. См. также: константы mbXXX *- Переменная MouseEvents Drivers ----------------------------------------------------------------- Описание: MouseEvents: Boolean = False; Функция: Устанавливается равным True, если InitEvents обна- руживает "мышь"; в противном случае, устанавливается равным False. В случае значения False все процедуры обработки событий от "мыши" обходятся. См. также: GetMouseEvent *- Переменная MouseIntFlag Drivers ----------------------------------------------------------------- Описание: MouseIntFlag: Byte; Функция: Используется внутри драйвера "мыши" Turbo Vision и отображаемыми элементами. Устанавливается при возникновении собы- тия от "мыши". *- Переменная MouseReverse Drivers ----------------------------------------------------------------- Описание: const MouseReverse: Boolean = False; Функция: Установка значения MouseReverse равным True застав- ляет администратор событий поменять местами флаги mbLeftButton и mbRightButton из поля Button записей TEvent. См. также: константы mbXXXX, тип TEvent *- Переменная MouseWhere Drivers ----------------------------------------------------------------- Описание: MouseWhere: TPoint; Функция: Содержит текущую позицию "мыши" в глобальных коор- динатах. Значение MouseWhere обновляется обработчиком прерываний от "мыши" при ее перемещении. Используйте процедуру MakeLocal для преобразования к локальным (относительно окна) координатам. MouseWhere передается обработчикам событий вместе с другими данными "мыши". См. также: методы GetMouseEvent, GetEvent; MakeLocal *- Процедура MoveBuf Objects ----------------------------------------------------------------- Описание: procedure MoveBuf(var Dest; var Source; Attr: Byte; Count: Word); Функция: Помещает текст и видеоатрибуты в буфер для исполь- зования совместно с методами WriteBuf или WriteLine. Dest должен представлять собой TDrawBuffer (или эквивалентный массив слов), а Source должен быть массивом байт. Count байт помещается из Source в младшие байты соответствующих слов в Dest. Старшие байты слов в Dest устанавливаются равными Attr или остаются неизменными, если Attr- 0. См. также: тип TDrawBuffer, MoveChar, MoveCStr, MoveStr. *- Процедура MoveChar Drivers ----------------------------------------------------------------- Описание: procedure MoveChar(var Dest; C: Char; Attr: Byte; Count: Word); Функция: Копирует символы в буфер для использования с TView.WriteBuf или TView.WriteLine. Параметр Dest должен быть массивом TDrawBuffer (или эквивалентным массивом слов). Младшие байты первых Count слов Dest устанавливаются равными С или остаются неизменными, если Ord(C) равно 0. Старшие байты слов устанавливаются равными Attr или остаются неизменными, если Attr равно 0. См. также: тип TDrawBuffer, MoveBuf, MoveCStr, MoveStr *- Процедура MoveCStr Drivers ----------------------------------------------------------------- Описание: procedure MoveCStr(var Dest; Str: String; Attrs: Word); Функция: Копирует двухцветную строку в буфер для использова- ния с TView.WriteBuf или TView.WriteLine. Параметр Dest должен быть массивом TDrawBuffer (или эквивалентным массивом слов). Символы из Str копируются в младшие байты соответствующих слов в Dest. Старшие байты слов устанавливаются равными Lo(Attr) или Hi(Attr). Символы "~" в строке используются для переключения между двумя байтами атрибута, передаваемыми в слове Attr. См. также: тип TDrawBuffer, MoveChar, MoveBuf, MoveStr *- Процедура MoveStr Drivers ----------------------------------------------------------------- Описание: procedure MoveStr(var Dest; Str: String; Attr: Byte); Функция: Копирует строку в буфер для использования с TView.WriteBuf или TView.WriteLine. Параметр Dest должен быть массивом TDrawBuffer (или эквивалентным массивом слов). Символы в Str копируются в младшие байты соответствующих слов в Dest. Старшие байты слов устанавливаются равными Attr или остаются неизменными, если Attr равно 0. См. также: тип TDrawBuffer, MoveChar, MoveCStr, MoveBuf *- Процедура NewBuffer Memory ----------------------------------------------------------------- Описание: procedure NewBuffer (var P: Pointer; Size: Word); Функция: Выделяет перемещаемый буфер изменяемых размеров с размером Size байт помимо динамически распределяемой памяти в области, отведенной для буферов редактора, и присваивает указа- тель P. Впоследствии размер памяти, связанной с P, можно изменить с помощью SetBufferSize. Этот буфер освобождается с помощью DisposeBuffer, а не FreeMem или Dispose. Внимание! В любой момент администратор памяти может перемес- тить этот буфер, но в этом случае он соответственно изменит зна- чение указателя P. Это означает, что P всегда является правильным указателем, однако другие величины, основанные на нем, могут стать неверными без предупреждения. См. также: процедуру DisposeBuffer, функцию GetBufferSize, функцию SetBufferSize *- Процедура NewCache Memory ----------------------------------------------------------------- Описание: procedure NewCache (var P: Pointer; Size: Word); Функция: Выделяет "кэш"- буфер размером Size байт и присваи- вает указатель P. Если "кэш"- буфер таких размеров выделить не удается, то P присваивается значение nil. Если в дальнейшем администратору памяти понадобится передать это кэш-пространство для других целей, то он присвоит P значение nil. Перед использованием кэш-буферов убедитесь в том, что они существуют, поскольку Ваша программа не контролирует действия ад- министратора памяти. Turbo Vision использует кэш-буфера при работе с объектами групп со взведенными флагами ofBuffered, поскольку это значитель- но ускоряет работу операций перерисовки. См. также: процедуру DisposeCache *- Функция: NewItem Menus ----------------------------------------------------------------- Описание: function NewItem(Name, Param: TMenuStr; KeyCode: Word; Command: Word; AHelpCtx: Word; Next: PMenuItem): PMenuItem; Функция: Выделяет память и возвращает указатель на новую запись TMenuItem, которая представляет элемент меню (используя NewStr для выделения полей указателей на строки Name и Param). Параметр Name должен быть непустой строкой, а параметр Command должен быть ненулевым. Вызовы NewItem, NewLine, NewMenu и NewSubMenu могут быть вложенными для создания полного дерева меню в одном операторе Паскаля. Примеры можно найти в Главе 10, "Объекты прикладной программы". См. также: TApplication.InitMenuBar, тип TMenuView, NewLine, NewMenu, NewSubMenu *- Функция: NewLine Menus ----------------------------------------------------------------- Описание: function NewLine(Next: PMenuItem): PMenuItem; Функция: Выделяет память и возвращает указатель на новую запись TMenuItem, которая представляет разделительную строку в окне меню. См. также: TApplication.InitMenuBar, тип TMenuView, NewMenu, NewSubMenu, NewItem *- Функция: NewMenu Menus ----------------------------------------------------------------- Описание: function NewMenu(Items: PMenuItem): Pmenu; Функция: Выделяет память и возвращает указатель на новую запись TMenu. Поля Items и Default записи устанавливаются равными значению, заданному параметром Items. См. также: TApplication.InitMenuBar, тип TMenuView, NewLine, NewSubMenu, NewItem *- Функция: NewNode OutLine ----------------------------------------------------------------- Описание: function NewNode (const AText: String; AChildren, ANext: PNode): PNode; Функция: Создает память и выделяет узловую запись типа TNode для списка иерархической структуры и возвращает указатель на новый узел. NewNode задает поля нового узла Text, ChildList и Next равными соответственно AText, AChildList и ANext. См. также: процедуру DisposeNode, тип TNode *- Функция: NewSItem Dialogs ----------------------------------------------------------------- Описание: function NewSItem(const Str: String; ANext: PSItem): PSItem; Функция: Выделяет и возвращает указатель на новую запись PSItem. Поля Value и Next записи устанавливаются равными NewStr(Str) и ANext соответственно. Функция NewSItem и запись типа TSItem позволяют легко создавать связанные списки строк. Примеры можно найти в Главе 12. *- Функция: NewStatusDef Menus ----------------------------------------------------------------- Описание: function NewStatusDef(AMin, AMax: Word; AItems: PStatusItem; ANext: PStatusDef): PStatusDef; Функция: Выделяет память и возвращает указатель на новую запись TStatusDef. Запись инициализируется заданными значениями параметров. Вызовы NewStatusDef и NewStatusKey могут быть вложен- ными для создания полных описаний строк состояния в одном опера- торе Паскаля. Примеры можно найти в Главе 2. См. также: TApplication.InitStatusLine, TStatusLine, NewStatusKey *- Функция: NewStatusKey Menus ----------------------------------------------------------------- Описание: function NewStatusKey (AText: String; AKeyCode: Word; ACommand: Word; ANext: PStatusItem): PStatusItem; Функция: Выделяет память и возвращает указатель на новую запись TStatusItem. Запись инициализируется со значениями параме- тров (NewStr используется для создания поля указателя Text). Если AText пусто (результатом будет nil в поле Text), то элемент стро- ки состояния будет невидимым, но будет обеспечивать, однако, связь данного KeyCode с Command. См. также: TApplication.InitStatusLine, TStatusLine, NewStatusDef *- Функция: NewStr Objects ----------------------------------------------------------------- Описание: function NewStr(const S: String): PString; Функция: Это подпрограмма выделения строки в динамической области памяти. Если S- нулевая, то NewStr возвращает указатель nil; в противном случае, выделяются Length(S)+1 байт, содержащие копию S и возвращается указатель на первый байт. Строки, создаваемые с помощью NewStr, могут быть освобождены с помощью DisposeStr. См. также: DisposeStr *- Функция: NewSubMenu Menus ----------------------------------------------------------------- Описание: function NewSubMenu (Name: TmenuStr; AHelpCtx: Word; SubMenu: PMenu; Next: PMenuItem): PMenuItem; Функция: Выделяет память и возвращает указатель на новую запись TMenuItem, которая представляет собой подменю (для выделе- ния поля указателя Name используется NewStr). См. также: TApplication.InitMenuBar,TMenuView, NewLine, NewItem *- Константы ofXXXX Views ----------------------------------------------------------------- Функция: Эти мнемонические обозначения относятся к битовым положениям позиции поля Options отображаемого элемента. Установка бита в 1 указывает на тот факт, что отображаемый элемент имеет данный конкретный атрибут; сброс бита означает, что атрибут отк- лючен или запрещен. Например: MyWindow.Options := ofTileable + ofSelectable; Значения: Определены следующие параметры флагов: Таблица 19.28. Флаги Options. ----------------------------------------------------------------- Константа Значение, если установлена ----------------------------------------------------------------- ofSelectable Отображаемый элемент должен выбираться автоматически, например, отметкой "мышью" на отображаемом элементе или клавишей Tab в диалоговом окне. ofTopSelect Отображаемый элемент помещается перед всеми другими отображаемыми элементами, когда он выбирается. Когда бит ofTopSelect установлен, вызов TView.Select соответствует вызову TView.MakeFirst. В окнах (TWindow и его потомках) по умолчанию этот бит установлен, что заставляет их при выборе располагаться перед всеми другими окнами в оперативной области экрана. ofFirstClick После выбора отображаемого элемента с помощью "мыши" нажатие будет также обработано как обычное нажатие "мыши". Если флаг ofSelectable не установлен, то действие флага не имеет эффекта. Если бит сброшен, то отметка "мышью", которая выбирает отображаемый элемент, не имеет дальнейшего действия. ofFramed Отображаемый элемент должен иметь вокруг себя рамку. TWindow и его потомки имеют TFrame в качестве своего последнего подэлемента. Когда объект рамки рисует себя, он также рисует рамку вокруг любого другого подэлемента, у которого установлен бит ofFrame. ofPreProcess Отображаемый элемент должен получать активные события (события для активного отображаемого элемента) перед тем, как они будут посланы активному отображаемому элементу. ofPostProcess Отображаемый элемент должен получать активные события, если активный отображаемый элемент не смог их обработать. ofBuffered Используется только для объектов TGroup. Если имеется достаточное количество памяти, то должен быть выделен кэш-буфер. Буфер группы содержит образ экрана для всей группы, таким образом увеличивая скорость перерисовки. При отсутствии буфера, TGroup.Draw вызывается для метода DrawView каждого подэлемента. Если впоследствии New и GetMem не могут получить достаточно памяти, то память под буфера группы будет освобождена. ofTileable Оперативная область экрана может расположить этот отображаемый элемент мозаично (или каскадно). Используется только с объектами TWindow. ofCenterX При вставке в группу отображаемый элемент центрируется по оси Х своего владельца. ofCenterY При вставке в группу отображаемый элемент центрируется по оси Y своего владельца. ofCentered При вставке в группу отображаемый элемент центрируется по обеим осям своего владельца. ofValidate Перед потерей фокуса ввода отображаемый элемент должен вызывать Valid. ofVersion Отображаемый элемент содержит поля, зависящие от версии. Подробная информация о версиях содержится в Главе 17. ofVersion10 Отображаемый элемент является отображаемым элементом версии 1.0. Подробная информация о версиях содержится в Главе 17. ofVersion20 Отображаемый элемент является отображаемым элементом версии 2.0. Подробная информация о версиях содержится в Главе 17. ----------------------------------------------------------------- Биты Options определены следующим образом: Рис. 19.9. Битовые флаги Options. ЪДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДД> ofVersion = $3000 і і ЪДВДДДДДДДДДДДДДДДДДДДДД> ofCentered = $0300 ЙНННСНСПСПСНСНСПСПСНСНСНСНСНСНСНСННН» єmsbі і і і і і і і і і і і і і і1sbє ИНННПНПНПСПНПСПСПСПСПСПСПСПСПСПСПННСј і і і і і і і і і і і АДДД> ofSelectable = $0001 і і і і і і і і і і АДДДДДДД> ofTopSelect = $0002 і і і і і і і і і АДДДДДДДДД> ofFirstClick = $0004 і і і і і і і і АДДДДДДДДДДД> ofFramed = $0008 і і і і і і і АДДДДДДДДДДДДД> ofPreProcess = $0010 і і і і і і АДДДДДДДДДДДДДДД> ofPostProcess = $0020 і і і і і АДДДДДДДДДДДДДДДДД> ofBuffered = $0040 і і і і АДДДДДДДДДДДДДДДДДДД> ofTileable = $0080 і і і АДДДДДДДДДДДДДДДДДДДДД> ofCenterX = $0100 і і АДДДДДДДДДДДДДДДДДДДДДДД> ofCenterY = $0200 і АДДДДДДДДДДДДДДДДДДДДДДДДД> ofValidate = $0400 АДДДДДДДДДДДДДДДДДДДДДДДДДДДДД> ofVersion20 = $1000 См. также: TView.Options *- Константы ovXXXX Outline ----------------------------------------------------------------- Функция: Метод CreateGraph из TOutlineViewer получает пара- метр с именем Flags, содержащий комбинацию констант ovXXXX. Flags определяет то, как визуализатор иерархических структур должен рисовать графическую часть иерархической структуры. Значения: Определены следующие константы: ЙННННСННННСННННСННННСННННСННННСННННСННННё єmsb і і і і і і і1sb і ИНСННПННННПННННПННННПНСННПНСННПНСННПНСННѕ АДДДДДДДДДДВДДДДДДДДЩ і і АДДДДovExpanded = $01 і і АДДДДДДДДДovChildren = $02 Не определены АДДДДДДДДДДДДДДovLast = $04 Таблица 19.29. Константы просмотра иерархических структур ------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ ovExpanded $01 Узел "раскрывается" (показываются порожденные узлы) ovChildren $02 Узел имеет порожденные узлы ovLast $04 Узел является последним порожденным узлом порождающего узла ------------------------------------------------------------ *- Переменная PositionalEvents Views ----------------------------------------------------------------- Описание: PositionalEvents: Word = evMouse; Функция: Определяет классы событий, являющиеся события поло- жения. Метод объекта группы HandleEvent использует переменные FocusedEvents и PositionalEvents для определения того, как пере- дать события подэлементам группы. Если класс события не принадле- жит FocusedEvents или PositionalEvents, то оно интерпретируется группой как событие-извещение. См. также: TGroup.HandleEvent, тип TEvent, константы события evXXXX, переменная FocusedEvents *- Процедура PrintStr Drivers ----------------------------------------------------------------- Описание: procedure PrintStr(S: String); Функция: Печатает строку S на экране, используя вызов функ- ции DOS 40H для записи на стандартное устройство вывода DOS. Имеет тот же эффект, что и Write(S), с той разницей, что PrintStr не требует компоновки прикладной программы с библиотекой вво- да-вывода файлов. *- Тип PString Objects ----------------------------------------------------------------- Описание: PString = ^String; Функция: Определяет указатель на строку. *- Тип PtrRec Objects ----------------------------------------------------------------- Описание: PtrRec = record Ofs, Seg: Word; end; Функция: Запись, содержащая значение сегмента и смещения указателя. *- Процедура RegisterColorSel ColorSel ----------------------------------------------------------------- Описание: procedure RegisterColorSel; Функция: Для каждого из типов объектов, определенных в моду- ле ColorSel: TColorSelector, TMonoSelector, TColorDisplay, TColorGroupList, TColorItemList и TColorDialog, вызывает RegisterType. После вызова RegisterColorSel каждый из этих типы можно читать и писать из потока ввода-вывода. См. также: процедуру RegisterType *- Процедура RegisterDialogs Dialogs ----------------------------------------------------------------- Описание: procedure RegisterDialogs; Функция: Вызывает RegisterType для каждого типа объекта, определенного в модуле Dialogs: TDialog, TInputLine, TButton, TCluster, TRadioButtons, TCheckBoxes, TListBox, TStaticText, TParamText, TLabel, THistory. Вызов RegisterDialogs позволяет использовать все эти типы для чтения и записи с потока ввода-вы- вода. См. также: TStreamRec, RegisterType *- Процедура RegisterEditors Editors ----------------------------------------------------------------- Описание: procedure RegisterEditors; Функция: Вызывает RegisterType для каждого типа объекта, определенного в модуле Editors: TEditor, TMemo, TFileEditor, TIndicator и TEditWindow. Вызов RegisterEditors позволяет исполь- зовать все эти типы для чтения и записи с потока ввода-вывода. См. также: RegisterType *- Процедура RegisterStdDlg StdDlg ----------------------------------------------------------------- Описание: procedure RegisterStdDlg; Функция: Вызывает RegisterType для каждого типа объекта, определенного в модуле StdDlg: TFileInputLine, TFileCollection, TFileList, TFileInfoPane, TFileDialog, TDirCollection, TDirListBox и TChDirDialog. Вызов RegisterStdDlg позволяет использовать все эти типы для чтения и записи с потока ввода-вывода. См. также: RegisterType *- Процедура RegisterType Objects ----------------------------------------------------------------- Описание: procedure RegisterType(var S: TStreamRec); Функция: Регистрирует все типы объектов с потоками Turbo Vision, создавая вход в связанный список всех известных объектов. Потоки могут хранить и возвращать только эти известные типы объе- ктов. Каждый зарегистрированный объект требует уникальной записи регистрации в потоке типа TStreamRec. См. также: TStream.Get, TStreamPut, TStreamRec *- Процедура RegisterValidate Validate ----------------------------------------------------------------- Описание: procedure RegisterValidate; Функция: Вызывает RegisterType для каждого типа объекта, определенного в модуле Validate: TPXPictureValidator, TFilterValidator, TRangeValidator, TLookupValidator и TStringLookupValidator. Вызов RegisterValidate позволяет исполь- зовать все эти типы с потоками ввода-вывода. См. также: RegisterType *- Переменная RepeatDelay Drivers ----------------------------------------------------------------- Описание: RepeatDelay: Word = 8; Функция: Определяет число тиков таймера (1/18.2 часть секун- ды), которое должно пройти перед генерацией событий evMouseAuto. Временной интервал между событиями evMouseAuto всегда составляет один тик. См. также: DoubleDelay, GetMouseEvent, константы evXXXX *- Переменная ReplaceStr Editors ----------------------------------------------------------------- Описание: ReplaceStr: string [80] = ''; Функция: содержит последнюю строку, замененную в операции поиска и замены. См. также: переменную FindStr, TEditor.DoSearchReplace *- Переменная SaveCtrlBreak Drivers ----------------------------------------------------------------- Описание: SaveCtrlBreak: Boolean = False; Функция: Процедура InitSysError сохраняет в этой переменной состояние реакции на Ctrl-Break из DOS перед запрещением реакции на Ctrl-Break. DoneSysError восстанавливает состояние реакции на Ctrl-Break в соответствии со значением, сохраненным в этой переменной. См. также: InitSysError, DoneSysError *- Константы sbXXXX Views ----------------------------------------------------------------- Функция: Эти константы определяют различные области TScrollBar, в которых может произойти перещелкивание "мышью". Функция TScrollBar.ScrollStep осуществляет преобразование этих констант в действительные значения шага прокрутки. Хотя она определена, константа sbIndicator никогда не передается в TScrollBar.ScrollStep. Таблица 19.30. Константы полосы прокрутки. ----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- sbLeftArrow 0 Левая стрелка горизонтальной полосы прокрутки. sbRightArrow 1 Правая стрелка горизонтальной полосы прокрутки. sbPageLeft 2 Левая страничная область горизонтальной полосы прокрутки. sbPageRight 3 Правая страничная область горизонтальной полосы прокрутки. *- Константы sbXXXX Views ----------------------------------------------------------------- Функция: Эти константы определяют различные области TScrollBar, в которых может произойти перещелкивание "мышью". Функция TScrollBar.ScrollStep осуществляет преобразование этих констант в действительные значения шага прокрутки. Хотя она определена, константа sbIndicator никогда не передается в TScrollBar.ScrollStep. Таблица 19.30. Константы полосы прокрутки. ----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- sbLeftArrow 0 Левая стрелка горизонтальной полосы прокрутки. sbRightArrow 1 Правая стрелка горизонтальной полосы прокрутки. sbPageLeft 2 Левая страничная область горизонтальной полосы прокрутки. sbPageRight 3 Правая страничная область горизонтальной полосы прокрутки. sbUpArrow 4 Стрелка вверх вертикальной полосы прокрутки. sbDownArrow 5 Стрелка вниз вертикальной полосы прокрутки. sbPageUp 6 Верхняя страничная область вертикальной полосы прокрутки. sbPageDown 7 Нижняя страничная область вертикальной полосы прокрутки. sbIndicator 8 Индикатор на полосе прокрутки. ----------------------------------------------------------- ^ >ДД sbUpArrow ± ± >ДД sbPageUp ± sbIndicator ДДДДДДДД< і ± і ± і ± і ± >ДД sbPageDown і ± і ± V V >ДД sbDownArrow <±±±±±±±±±±±±±±± ±±±±±±±±±±±±±±±±±±±>ДЩ ^ ^ ^ ^ і і і і і sbPageLeft sbPageRight і sbLeftArrow sbRightArrow Рис. 19.10. Элементы полосы прокрутки. Методу TWindow.StandardScrollBar могут передаваться следующие значения: Таблица 19.31. Константы StandardScrollBar. ----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- sbHorizontal $0000 Полоса прокрутки горизонтальна. sbVertical $0001 Полоса прокрутки вертикальна. sbHandleKeyboard $0002 Полоса прокрутки реагирует на команды клавиатуры. ----------------------------------------------------------- См. также: TScrollBar, TScrollBar.TScrollStep *- Переменная ScreenBuffer Drivers ----------------------------------------------------------------- Описание: ScreenBuffer: Pointer; Функция: Указатель на буфер экрана, установленный InitVideo. См. также: InitVideo *- Переменная ScreenHeight Drivers ----------------------------------------------------------------- Описание: ScreenHeight: Byte; Функция: Устанавливается InitVideo и SetVideoMode равной высоте экрана в строках для текущего экрана. См. также: InitVideo, SetVideoMode, ScreenWidth *- Переменная ScreenMode Drivers ----------------------------------------------------------------- Описание: ScreenMode: Word; Функция: Хранит текущий видеорежим. Изначально устанавливае- мая инициализационным кодом модуля Drivers, ScreenMode может быть изменена с использованием SetVideoMode. Значения ScreenMode обыч- но устанавливаются с использованием мнемонических констант режима экрана smXXXX. См. также: InitVideo, SetVideoMode, smXXXX *- Переменная ScreenWidth Drivers ----------------------------------------------------------------- Описание: ScreenWidth: Byte; Функция: Устанавливается InitVideo равным ширине экрана (числу символов с строке). См. также: InitVideo *- Тип SelectMode Views ----------------------------------------------------------------- Описание: SelectMode = (NormalSelect, EnterSelect, LeaveSelect); Функция: Используется внутри Turbo Vision. См. также: TGroup.ExecView, TGroup.SetCurrent. *- Функция SetBufferSize Memory ----------------------------------------------------------------- Описание: SetBufferSize (P: Pointer; Size: Word): Boolean Функция: Устанавливает размер буфера, на который указывает P, равным Size байт. P должен быть буфером, выделенным с помощью NewBuffer. Если новое выделение памяти происходит успешно, то возвращает True; в противном случае False, и размер буфера остае- тся неизменным. См. также: процедуру NewBuffer, функцию GetBufferSize *- Процедура SetMemTop Memory ----------------------------------------------------------------- Описание: SetMemTop (MemTop: Pointer); Функция: Устанавливает верхнюю границу блока памяти програм- мы. Первоначальная верхняя граница соответствует значению, храня- щемуся в переменной HeapEnd. SetMemTop обычно используется для уменьшения блока памяти программы перед запуском оболочки DOS или другой программы и его последующего расширения. *- Процедура SetVideoMode Drivers ----------------------------------------------------------------- Описание: procedure SetVideoMode(Mode: Word); Функция: Устанавливает видеорежим. Mode- это одна из конс- тант smCO80, smBW80 или smMono с необязательным добавлением smFont8x8 для выбора 43 или 50-строчного режима в случае EGA или VGA. SetVideoMode инициализирует те же самые переменные, что и InitVideo (за исключением переменной StartupMode, которая не изменяется). SetVideoMode обычно не вызывается непосредственно. Вместо этого следует использовать метод объекта программы SetScreenMode, который также устанавливает палитру программы. См. также: InitVideo, константы smXXXX, TProgram.SetScreenMode *- Константы sfXXXX Views ----------------------------------------------------------------- Функция: Эти константы используются для доступа к соответст- вующим битам полей TView.State. Поля TView.State никогда не сле- дует изменять непосредственно, вместо этого Вы должны использо- вать метод отображаемого элемента SetState. Значения: Определены следующие флаги состояния: Таблица 19.32. Константы флагов состояния. ----------------------------------------------------------------- Константа Смысл, если флаг установлен ----------------------------------------------------------------- sfVisible Отображаемый элемент виден на фоне своего владельца. sfVisible установлен по умолчанию. Методы отображаемого элемента Show и Hide изменяют его значение. При sfVisible отображаемый элемент не обязательно видим на экране, поскольку его владелец может быть невидим. Для проверки видимости на экране вызовите метод отображаемого элемента sfExposed. sfCursorVis Курсор отображаемого элемента видим. По умолчанию сброшен. ShowCursor и HideCursor изменяют значение sfCursorVis. sfCursorIns Курсор отображаемого элемента представляет собой сплошной блок (прямоугольник). По умолчанию сброшен, делая курсор подчеркнутым. BlockCursor и NormalCursor изменяют значение sfCursorVis. sfShadow Отображаемый элемент имеет тень. sfActive Отображаемый элемент представляет собой активное окно или подэлемент элемента активного окна. sfSelected Отображаемый элемент - это выбранный в настоящий момент подэлемент внутри своего владельца. Каждый объект группы имеет поле Current, которое указывает на текущий выбранный подэлемент (или nil, если подэлементы не выбраны). В группе может быть только один выбранный подэлемент. sfFocused Отображаемый элемент имеет фокус ввода. Отображаемый элемент имеет фокус ввода, если он выбран и все владельцы выше его также выбраны, т.е. если отображаемый элемент находится в цепи, образованной указателями Current всех групп, начиная с Application. Последний отображаемый элемент цепи - это конечное место назначения для всех событий, находящихся в фокусе. sfDragging Отображаемый элемент перемещается. sfDisabled Отображаемый элемент недоступен. Недоступный элемент игнорирует все события, посылаемые ему. sfModal Отображаемый элемент является режимным. Когда отоб- ражаемый элемент начинает исполняться (путем вызова ExecView), этот отображаемый элемент становится ре- жимным. Режимный видимый элемент представляет собой вершину (корень) дерева активных событий, получая события и управляя ими до тех пор, пока не будет вызван его метод EndModal. Во время этого "локаль- ного" цикла событий события передаются нижним подэ- лементам в дереве отображаемых подэлементов. Собы- тия от этих нижних отображаемых элементов передают- ся вверх по дереву, не выходя за пределы режимного отображаемого элемента. sfExposed У отображаемого элемента прямой или косвенный вла- делец - объект TApplication и, следовательно, он может быть виден на экране. Метод Exposed использу- ет этот флаг для определения того, может ли быть какая-либо часть отображаемого элемента действи- тельно видимой на экране. ----------------------------------------------------------------- ЙНННСНСНСНСНСНСНСНСНСНСНСНСНСНСНСННН» єmsbі і і і і і і і і і і і і і і1sbє ИНННПНПНПНПСПНПСПСПСПСПСПСПСПСПСПННСј і і і і і і і і і і АДДД> sfVisible = $0001 і і і і і і і і і АДДДДДДД> sfCursorVis = $0002 і і і і і і і і АДДДДДДДДД> sfCursorIns = $0004 і і і і і і і АДДДДДДДДДДД> sfShadow = $0008 і і і і і і АДДДДДДДДДДДДД> sfActive = $0010 і і і і і АДДДДДДДДДДДДДДД> sfSelected = $0020 і і і і АДДДДДДДДДДДДДДДДД> sfFocused = $0040 і і і АДДДДДДДДДДДДДДДДДДД> sfDragging = $0080 і і АДДДДДДДДДДДДДДДДДДДДД> sfDisabled = $0100 і АДДДДДДДДДДДДДДДДДДДДДДД> sfModal = $0200 АДДДДДДДДДДДДДДДДДДДДДДДДДДД> sfExposed = $0800 Рис. 19.11. Биты флага состояния. См. также: TView.State *- Переменная ShadowAttr Views ----------------------------------------------------------------- Описание: ShadowAttr: Byte = $80; Функция: Эта переменная управляет цветом "тени", доступной отображаемым элементам с установленным битом sfShadow. "Тень"- это обычно разреженная серая область, отображаемая прямо за края- ми видимого элемента для обеспечения иллюзии трехмерности. См. также: ShadowSize *- Переменная ShadowSize Views ----------------------------------------------------------------- Описание: ShadowSize: TPoint = (X: 2; Y: 1); Функция: Это значение управляет размером "тени", которая доступна отображаемым элементам с установленным битом sfShadow. "Тень"- это обычно разреженная серая область, отображаемая прямо за краями видимого элемента для обеспечения иллюзии трехмерности. По умолчанию, размер "тени" - 2 по оси X и 1 по Y. TProgram.InitScreen инициализирует ShadowSize следующим образом: если режим экрана равен smMono, то ShadowSize устанавли- вается равным (0, 0). В остальных случаях ShadowSize устанавлива- ется равным (2, 1), если только не установлен smFont8x8 (43- или 50-строчный режим), в этом случае устанавливается равным (1, 1). См. также: TProgram.InitScreen, ShadowAttr *- Переменная ShowMarkers Drivers ----------------------------------------------------------------- Описание: ShowMarkers: Boolean; Функция: Используется для указания того, будут ли вокруг активных элементов управления размещаться индикаторы. TProgram.InitScreen устанавливает ShowMarkers равным True, если установлен монохромный видеорежим. В противном случае равным False. Значение ShowMarkers может быть установлено равным True также в цветном и черно-белом режиме. См. также: TProgram.InitScreen, переменная SpecialChars *- Процедура ShowMouse Drivers ----------------------------------------------------------------- Описание: procedure ShowMouse; Функция: ShowMouse уменьшает значение "счетчика спрятываний" в драйвере "мыши", и делает курсор "мыши" видимым при значении счетчика, равном 0. См. также: InitEvents, DoneEvents, HideMouse *- Константы smXXXX Drivers ----------------------------------------------------------------- Функция: Эти мнемонические константы используются с SetVideoMode для установки соответствующего значения видеорежима в ScreenMode. Значения: В Turbo Vision определены следующие режимы экрана: Таблица 19.33. Константы режимов экрана. ----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- smBW80 $0002 Черно-белый режим на цветном адаптере smCO80 $0003 Цветной режим smMono $0007 Монохромный режим smFont8x8 $0100 43- или 50-строчный режим ----------------------------------------------------------- См. также: SetVideoMode, ScreenMode *- Переменная SpecialChars Views ----------------------------------------------------------------- Описание: SpecialChars: array[0..5] of Char = (#175, #174, 26, #27, ' ', ' '); Функция: Определяет символы индикатора, используемые для подсветки активного отображаемого элемента в монохромном видеоре- жиме. Эти символы отображаются, если переменная ShowMarkers имеет значение True. См. также: переменную ShowMarkers *- Константы stXXXX Objects ----------------------------------------------------------------- Функция: Существует два набора констант, начинающихся с "st", которые используются потоками Turbo Vision. Значения: Следующие константы режима используются в TDosStream и TBufStream для определения режима доступа к файлу при открытии файла в потоках Turbo Vision: Таблица 19.34. Режимы доступа к потоку. ----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- stCreate $3C00 Создать новый файл stOpenRead $3D00 Открыть файл только на чтение stOpenWrite $3D01 Открыть файл только на запись stOpen $3D02 Открыть файл на чтение/запись ----------------------------------------------------------- Следующие значения возвращаются методом объекта Error в поле ErrorInfo, когда возникает ошибка потока: Таблица 19.35. Коды ошибок потока. ----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- stOk 0 Нет ошибки stError -1 Ошибка доступа stInitError -2 Нельзя инициализировать поток stReadError -3 Чтение за концом потока stWriteError -4 Нельзя расширить поток stGetError -5 Get для незарегистрированного типа объекта stPutError -6 Put для незарегистрированного типа объекта ----------------------------------------------------------- См. также: TStream *- Переменная StartupMode Drivers ----------------------------------------------------------------- Описание: StartupMode: Word; Функция: InitVideo сохраняет текущий режим экрана в этой переменной до переключения в режим экрана, заданный в ScreenMode. DoneVideo восстанавливает режим экрана в соответствие со значени- ем, запомненным в StartupMode. См. также: InitVideo, DoneVideo, ScreenMode *- Переменная StatusLine App ----------------------------------------------------------------- Описание: StatusLine: PStatusLine = nil; Функция: Указывает на строку состояния программы или равна nil, если программа не имеет строки состояния. Виртуальный метод InitStatusLine объекта программы создает объект строки состояния и присваивает его StatusLine. Настроенную строку состояния можно определить, заменив InitStatusLine, который создаст объект желае- мой строки состояния и заставит StatusLine указывать на нее. См. также: InitStatusLine *- Функция StdEditMenuItems App ----------------------------------------------------------------- Описание: function StdEditMenuItems (Next: PMenuItem): PMenuItem; Функция: Возвращает указатель на связанный список пунктов стандартного меню Edit. Этот список можно использовать либо как целое меню, либо как часть более обширного списка пунктов. Пункты стандартного меню Edit- Undo, Cut, Copy, Paste и Clear. *- Функция StdEditorDialog Editors ----------------------------------------------------------------- Описание: function StdEditorDialog (Dialog: Integer; Info: Pointer): Word; Функция: Выдает на экран диалоговое окно в соответствии со значением Dialog и информацией, переданной в Info. StdEditorDialogs рассматривается в качестве рабочего набора диалоговых окон, присваиваемых EditorDialog. Этот список можно использовать либо как целое меню, либо как часть более обширного списка пунктов. См. также: переменную EditorDialog, тип TEditorDialog *- Функция StdFileMenuItems App ----------------------------------------------------------------- Описание: function StdFileMenuItems (Next: PMenuItem): PMenuItem; Функция: Возвращает указатель на связанный список пунктов стандартного меню File. Этот список можно использовать либо как целое меню, либо как часть более обширного списка пунктов. Пункты стандартного меню File- New, Open, Save, Save As, Save All, Change Dir, Dos Shell и Exit. *- Функция StdStatusKeys App ----------------------------------------------------------------- Описание: function StdStatusKey (Next: PStatusItem): PStatusItem; Функция: Возвращает указатель на связанный список клавиш, часто используемых в строке состояния. Строка состояния, опреде- ленная по умолчанию для TApplication, использует в качестве пол- ного списка клавиш состояния StdStatusKeys. К определяемой поль- зователем строке состояния можно добавить StdStatusKeys, чтобы она также поддерживала стандартные команды и определения клавиш. Ниже приводится реализация StdStatusKeys: function StdStatusKeys (Next: PStatusItem): PStatusItem; begin StdStatusKeys := NewStatusKey ('', kbAltX, cmQuit, NewStatusKey ('', kbF10, cmMenu, NewStatusKey ('', kbAltF3, cmClose, NewStatusKey ('', kbF5, cmZoom, NewStatusKey ('', kbCtrlF5, cmResize, NewStatusKey ('', kbF6, cmNext, Next )))))); end; *- Функция StdWindowMenuItems App ----------------------------------------------------------------- Описание: function StdWindowMenuItems (Next: PMenuItem): PMenuItem; Функция: Возвращает указатель на список пунктов стандартного меню Window. Этот список можно использовать либо как целое меню, либо как часть более обширного списка пунктов. Пункты стандартного меню Window- Tile, Cascade, Close All, Size/Move, Zoom, Next, Previous и Close. *- Переменная StreamError Objects ----------------------------------------------------------------- Описание: StreamError: Pointer = nil; Функция: Если значение отлично от nil, то StreamError указы- вает на процедуру, которая вызывается методом Error потока при возникновении ошибки. Процедура должна иметь тип far и использо- вать параметр-переменную типа TStream, т.е. иметь описание: procedure MyStreamErrorProc(var S: TStream); far; Переменная StreamError позволяет глобально переопределить всю обработку ошибок потока. Чтобы изменит обработку ошибок для определенного типа потока, необходимо переопределить метод Error этого потока. *- Процедура StoreHistory HistList ----------------------------------------------------------------- Описание: procedure StoreHistory (var S: TStream); Функция: Пишет используемую в настоящий момент часть блока предыстории в поток S, причем сначала пишет длину блока, а затем сам блок. Для восстановления блока предыстории используйте проце- дуру LoadHistory. См. также: процедуру LoadHistory *- Процедура StoreIndexes ColorSel ----------------------------------------------------------------- Описание: procedure StoreIndexes (var S: TStream); Функция: Пишет набор цветовых индексов из ColorIndexes в поток S. Сохранив и повторно загрузив ColorIndexes в потоке, программа может восстановить состояние диалогового окна выбора цветов, что позволяет пользователю легко изменять цвета и восста- навливать произведенные изменения. См. также: переменную ColorIndexes, процедуру LoadIndexes *- Переменная SysColorAttr Drivers ----------------------------------------------------------------- Описание: SysColorAttr: Word = $4E4F; Функция: Цвет по умолчанию используется для вывода сообщений об ошибках обработчиком системных ошибок. На монохромных системах вместо SysColorAttr SysMonoAttr используется. Сообщения об ошиб- ках с параметром отмены/восстановления отображаются в строке состояния. Предыдущая строка состояния сохраняется и восстанавли- вается, когда условия позволяют это сделать. См. также: SystemError, SysMonoAttr *- Переменная SysErrActive Drivers ----------------------------------------------------------------- Описание: SysErrActive: Boolean = False; Функция: Указывает, активен ли обработчик системных ошибок в данный момент. Устанавливается равным True InitSysError. *- Переменная SysErrorFunc Drivers ----------------------------------------------------------------- Описание: SysErrorFunc: TSysErrorFunc = SystemError; Функция: SysErrorFunc - это функция системной ошибки типа TSysErrorFunc. Функция системной ошибки вызывается при возникно- вении критической ошибки DOS или когда требуется свопинг на компьютере с одним гибким диском. ErrorCode- это значение от 0 до 15, как определено в таблице 19.36, а Drive- это номер устройства (0=A, 1=B и т.д.) для дисковых ошибок. По умолчанию функция сис- темной ошибки - это SystemError. Вы можете установить свою функ- цию системной ошибки, присвоив ее SysErrorFunc. Функции системных ошибок не могут быть оверлейными. Таблица 19.36. Коды функции системной ошибки. ------------------------------------------------------------ Код ошибки Значение ------------------------------------------------------------ 0..12 Коды критических ошибок DOS 13 Плохой образ таблицы распределения файлов (FAT) в памяти 14 Ошибка доступа к устройству 15 Уведомление о свопинге ------------------------------------------------------------ Возвращаемые значения функции: Таблица 19.37. Значения, возвращаемые функцией системной ошибки. ---------------------------------------------------------------- Возвращаемое значение Назначение ---------------------------------------------------------------- 0 Пользователь запросил повтор 1 Пользователь запросил отмену ---------------------------------------------------------------- См. также: функцию SystemError, тип TSysErrorFunc, процедуру InitSysError *- Переменная SysMonoAttr Drivers ----------------------------------------------------------------- Описание: SysMonoAttr: Word = $7070; Функция: Атрибут по умолчанию используется для вывода сооб- щений об ошибках обработчиком системных ошибок. На цветных систе- мах вместо SysMonoAttr используется SysColorAttr. Сообщения об ошибках с параметром отмены/восстановления отображаются в строке состояния. Предыдущая строка состояния сохраняется и восстанавли- вается, когда условия позволяют это сделать. См. также: SystemError, SysColorAttr *- Функция: SystemError Drivers ----------------------------------------------------------------- Описание: function SystemError(ErrorCode: Integer; Drive: Byte): Integer; Функция: Функция системной ошибки, используемая по умолча- нию. Она отображает в строке состояния одно из следующих сообще- ний об ошибке, в зависимости от значения ErrorCode, используя при этом атрибуты цвета, определяемые SysColorAttr или SysMonoAttr. Таблица 19.38. Сообщения функции SystemError. ----------------------------------------------------------- Код ошибки Сообщение ----------------------------------------------------------- 0 Disk is write-protected in drive X (Диск в дисководе Х защищен от записи) 1 Critical disk error on drive X (Критическая ошибка диска на диске X) 2 Disk is not ready in drive X (Дисковод диска Х не готов) 3 Critical disk error on drive X (Критическая ошибка диска на диске X) 4 Data integrity error on drive X (Ошибка данных на диске X) 5 Critical disk error on drive X (Критическая ошибка диска на диске X) 6 Seek error on drive X (Ошибка позиционирования на диске X) 7 Unknown media type in drive X (Неизвестный тип носителя в дисководе X) 8 Sector not found on drive X (Не найден сектор на диске X) 9 Printer out of paper (Нет бумаги на принтере) 10 Write fault on drive X (Ошибка записи на диске X) 11 Read fault on drive X (Ошибка чтения на диске X) 12 Hardware failure on drive X (Аппаратная неисправность на диске X) 13 Bad memory image of FAT detected (В образе таблицы распределения файлов FAT в памяти обнаружена ошибка) 14 Device access error (Ошибка доступа к устройству) 15 Insert diskette in drive X (Вставьте дискету в дисковод X) ----------------------------------------------------------- См. также: SysColorAttr, SysMonAttr, SysErrorFunc *- TApplication App ----------------------------------------------------------------- TApplication является просто "оберткой" для TProgram и отли- чается от TProgram только методами конструктора и деструктора. Обычно объект прикладной программы получается из TApplication. Если Вам понадобится другой порядок инициализации и закрытия подсистем, то по прежнему можно получить Вашу программу из TProg- ram и вручную проинициализировать и закрыть подсистемы Turbo Vision в соответствии с Вашими потребностями. Внимание! В версии 2.0 TApplication добавляет некоторые новые методы для обработки стандартных команд программы. Сейчас TApplication имеет метод HandleEvent, обрабатывающий команды стандартных меню, и методы, располагающие окна каскадно и мозаич- но, а также выходит в оболочку DOS. *- Методы ----------------------------------------------------------------- Init constructor Init; Создает объект программы, сначала инициализируя все подсис- темы Turbo Vision (администраторы памяти, видео, событий, систем- ных ошибок и списка предыстории), а затем вызывая конструктор Init, унаследованный от TProgram. См. также: InitMemory, InitVideo, InitEvents, InitSysError, InitHistory, TProgram.Init Done destructor Done; virtual; Освобождает все объекты прикладной программы, вызывая снача- ла деструктор Done, унаследованный от TProgram, а затем закрывая все подсистемы Turbo Vision. Переопределяемость: иногда См. также: DoneMemory, DoneVideo, DoneEvents, DoneSysError, DoneHistory, TProgram.Done Cascade procedure Cascade; Вызывает GetTileRect для получения области, над которой окна должны мозаично располагаться, а затем, если DeskTop не равна nil, вызывает метод Cascade оперативной области, передавая полу- ченный прямоугольник. См. также: TApplication.GetTileRect, TDesktop.Cascade DosShell procedure DosShell; Вызывает оболочку DOS. DosShell сначала прекращает работу подсистем администратора памяти, администратора видео, админист- ратора событий, администратора системных ошибок, а затем вызывает WriteShellMsg, выдающую сообщения пользователя, после чего выпол- няет командный процессор, указанный в переменной среды COMSPEC. После выхода пользователя из оболочки DOS DosShell перезапу- скает эти подсистемы, и вызывает Redraw для перерисовки отобража- емых элементов программы. См. также: TApplication.WriteShellMsg GetTileRect procedure GetTileRect (var R: TRect); virtual; Устанавливает R равным прямоугольнику оперативной области, который должен закрывать окна, расположенные мозаично или каскад- но. По умолчанию GetTileRect возвращает размер всего отображаемо- го элемента оперативной области. Методы Cascade и Tile вызывают GetTileRect для определения области, в которой будут располагать- ся окна. Ваша программа может переопределить GetTileRect для того, чтобы она возвратила другой прямоугольник, например, для исключе- ния областей, закрытых окнами сообщений. См. также: TApplication.Cascade, TApplication.Tile HandleEvent procedure HandleEvent (var Event: TEvent); virtual; Обрабатывает большинство событий, вызывая метод HandleEvent, унаследованный от TProgram, а затем отвечает на три стандартных команды программы, cmTile, cmCascade, cmDosShell, вызывая соот- ветственно методы Tile, Cascade и DosShell. В версии 1.0 TApplication не заменяла TProgram.HandleEvent. См. также: TProgram.HandleEvent, TApplication.Cascade, TApplication.DosShell, TApplication.Tile Tile procedure Tile; Вызывает GetTileRect для получения области, над которой окна должны мозаично располагаться, а затем, если DeskTop не равна nil, вызывает метод Tile оперативной области, передавая получен- ный прямоугольник. См. также: TApplication.GetTileRect, TDesktop.Tile WriteShellMsg procedure WriteShellMsg; virtual; Перед вызовом в оболочку DOS печатает для пользователя сооб- щение. Процедура DosShell вызывает WriteShellMsg непосредственно перед запуском интерпретатора команд. По умолчанию WriteShellMsg выдает следующее сообщение: Type EXIT to return... Для выдачи пользователю другого сообщения можно переобозна- чить WriteShellMsg. Лучше выдать сообщение при помощи процедуры PrintStr, а не Writeln, поскольку PrintStr не требует использова- ния стандартной библиотеки момента исполнения. См. также: TApplication.DosShell *- TBackground App ----------------------------------------------------------------- TBackground- это обычный отображаемый элемент, содержащий однотонно заполненный прямоугольник. Обычно он принадлежит TDeskTop. *- Поля ----------------------------------------------------------------- Pattern (только для чтения) Pattern: Char; Это битовый шаблон для фона отображаемого элемента. *- Методы ----------------------------------------------------------------- Init constructor Init(var Bounds: TRect; APattern: Char); Данный метод создает объект TBackground с границами Bounds, вызывая конструктор Init, унаследованный от TView. GrowMode уста- навливается равным gfGrowHiX + gfGrowHiY, а поле Pattern - равным APattern. См. также: TView.Init, TBackground.Pattern Load constructor Load(var S: TStream); Создает и загружает объект фона из потока S, вызывая конс- труктор Load, а затем считывая символ Pattern. См. также: TView.Load Draw procedure Draw; virtual; Переопределяемость: переопределяется редко Заполняет прямоугольник отображаемого элемента текущим Pattern с цветом, установленным по умолчанию. GetPalette function GetPalette: PPalette; virtual; Переопределяемость: переопределяется редко Возвращает указатель на используемую по умолчанию палитру CBackground. Store procedure Store(var S: TStream); Сохраняет отображаемый элемент TBackground в потоке, вызывая метод Store, унаследованный от TView, а затем записывая символ Pattern. См. также: TView.Store, TBackground.Load *- Палитра ----------------------------------------------------------------- Объекты фона используют палитру CBackground, определенную по умолчанию, для копирования первого элемента палитры программы. 1 ЙННН» CBackground є 1 є ИНСНј Color ДДДДЩ *- TBufStream Objects ----------------------------------------------------------------- TBufStream реализует буферизованную версию TDosStream. До- полнительные поля указывают размер и положение буфера, а также текущую и последнюю позицию в буфере. Помимо переопределения вось- ми методов TDosStream, TBufStream определяет абстрактный метод TStream.Flush. Конструктор TBufStream создает и открывает файл, вызывая TDosStream.Init, затем создает буфер с помощью GetMem. TBufStream значительно эффективнее TDosStream при передаче в поток большого количества малых по размеру данных, как это имеет место при сохранении и загрузке объектов с использованием TStrea- m.Get и TStream.Put. *- Поля ----------------------------------------------------------------- BufEnd (только для чтения) BufEnd: Word; Если буфер не заполнен, то BufEnd дает смещение последнего используемого элемента буфера относительно указателя на Buffer. Buffer (только для чтения) Buffer: Pointer; Указатель на начало буфера потока. BufPtr (только для чтения) BufPtr: Word; Смещение текущего положения буфера относительно указателя на Buffer. BufSize (только для чтения) BufSize: Word; Размер буфера в байтах. *- Методы ----------------------------------------------------------------- Init constructor Init(FileName: FNameStr; Mode, Size: Word); Создает объект и открывает файл с именем FileName и режимом доступа Mode, вызывая конструктор Init, унаследованный от TDosStream. Создает в динамической памяти буфер размером SizeBuf. Устанавливает BufPtr и BufEnd равными нулю Типичный размер буфера - от 512 до 2048 байт. См. также: TDosStream.Init Done destructor Done; virtual; Переопределяемость: никогда не переопределяется Вызывает Flush и сбрасывает содержимое потока на диск, после чего уничтожает объект буферизованного потока вызовом деструктора Done, унаследованного от TDosStream. Освобождает память, выделен- ную под буфер См. также: TBufStream.Flush, TDosStream.Done Flush procedure Flush; virtual; Переопределяемость: никогда не переопределяется Сбрасывает буфер потока на диск, если поток будет в состоя- нии stOK. Деструктор Done вызывает Flush для обеспечения того, чтобы все данные были записаны на диск перед освобождением объек- та потока. См. также: TBufStream.Done GetPos function GetPos: LongInt; virtual; Переопределяемость: никогда не переопределяется Возвращает значение текущей позиции потока (не путайте с BufPtr- текущей позицией в буфере). См. также: TBufStream.Seek GetSize function GetSize: LongInt; virtual; Переопределяемость: никогда не переопределяется. Сбрасывает буфер, а затем возвращает общее число байт в потоке. Read procedure Read(var Buf; Count: Word); virtual; Переопределяемость: никогда не переопределяется В состоянии потока stOK, читает Count байт в буфер Buf, начиная с текущей позиции потока. Заметим, что Buf- это не буфер потока, а внешний буфер, содержащий данные, читаемые из потока. См. также: TBufStream.Write, stReadError Seek procedure Seek(Pos: LongInt); virtual; Переопределяемость: никогда не переопределяется Сбрасывает буфер, а затем устанавливает текущую позицию равной Pos байт от начала вызывающего потока. Начальная позиция потока- 0. См. также: TBufStream.GetPos, TBufStream.Flush Truncate procedure Truncate; virtual; Переопределяемость: никогда не переопределяется Сбрасывает буфер, затем удаляет все данные потока от текущей позиции до конца потока с использованием метода Truncate, унасле- дованного от TDosStream. Текущая позиция устанавливается равной новому концу потока. См. также: TBufStream.GetPos, TBufStream.Seek Write procedure Write(var Buf; Count: Word); virtual; Переопределяемость: никогда не переопределяется В состоянии потока stOK, записывает Count байт из буфера Buf в поток, начиная с текущей позиции. Заметим, что Buf- это не буфер потока, а внешний буфер, содержащий данные, записываемые в поток. При вызове Write, Buf указывает на переменную, значение которой записывается. См. также: TBufStream.Read, stWriteError *- TButton Dialogs ----------------------------------------------------------------- Объект TButton представляет собой отображаемый элемент с заголовком и "тенью", генерирующий команду при нажатии и наиболее часто встречающийся в диалоговых окнах. "Кнопку" можно "нажать" нажатием подсвеченной буквы, переходом на кнопку с помощью клави- ши Tab и нажатием клавиши пробела, нажатием клавиши Enter, когда "кнопка" используется по умолчанию (выделяется подсветкой) или перещелкиванием (двойным нажатием) кнопки "мыши". При цветной и черно-белой палитрах "кнопка" имеет трехмерный отображаемый элемент, который изменяется при нажатии. На монохро- мных системах Turbo Vision выделяет кнопки скобками и другими символами ASCII, которые используются для указания того, является ли "кнопка" определенной по умолчанию, выбранной и т.д. Как и другие элементы управления, определенные в модуле Dialogs, TButton- это конечный объект, который может быть встав- лен в любую группу и использован без переопределения его методов. Вы можете установить в окне или диалоговом окне только одну "кнопку" (по умолчанию) в любой момент времени. "Кнопки", которые равнозначны в группе, получают и отдают состояние по умолчанию посредством сообщения evBroadcast. Недоступность или доступность команды, связанной с кнопкой, делает также недоступной или досту- пной саму кнопку. *- Поля ----------------------------------------------------------------- AmDefault (только для чтения) AmDefault: Boolean; В случае значения True "кнопка" используется по умолчанию (и следовательно, выбирается при нажатии клавиши Enter). В противном случае это "обычная" кнопка. См. также: константы флага "кнопки" bfXXXX Command (только для чтения) Commаnd: Word; Слово команды события, генерируемого при нажатии "кнопки". См. также: TButton.Init Flags (чтение/запись) Flags: Byte; Flags- это битовое поле, используемое для указания того, будет ли текст "кнопки" располагаться по центру или выравниваться по левой границе. Конкретные флаги описаны в разделе "Константы флага "кнопки" bfXXXX" в настоящей главе. См. так же: TButton.Draw, константы bfXXXX Title (только для чтения) Title: PString; Указатель на текст "кнопки". *- Методы ----------------------------------------------------------------- Init constructor Init(var Bounds: TRect; ATitle: TTitleStr; ACommand: Word; AFlags: Byte); Создает объект кнопки с заданными границами, вызывая конст- руктор Init, унаследованный от TView. Выделяет память под строку заголовка Title, вызывая NewStr (ATitle). AFlags используется в двух целях: если AFlags и bfDefault не равны 0, то AmDefault устанавливается равным True; кроме того, AFlags указывает, будет заголовок центрироваться или выравниваться по левой границе про- веркой на 0 значения AFlags и bfLeftJust. Options устанавливается равным (ofSelectable + ofFirstClick + ofPreProcess + ofPostProcess). EventMask устанавливается равным evBroadсast. Если данная команда ACommand не разрешена, то поле State устанавливается равным sfDisabled. Для определения оперативной клавиши кнопки необходимо заклю- чить один из символов из Title в знаки тильд (~), после чего эта клавиша станет оперативной. См. также: TView.Init, константы флага "кнопки" bfXXXX Load constructor Load(var S: TStream); Создает объект кнопки и инициализирует его из заданного потока S, вызывая конструктор Load(S), унаследованный от TView. Другие поля устанавливаются посредством вызовов S.Read, а State устанавливается в соответствии с тем, доступна ли команда в поле Command. Используется в сочетании со Store для сохранения и полу- чения объектов кнопок из TStream. См. также: TView.Load, TButton.Store Done destructor Done; virtual; Переопределяемость: никогда не переопределяется. Освобождает память, выделенную под Title, а затем вызывает деструктор Done, унаследованный от TView, для уничтожения отобра- жаемого элемента. См. также: TView.Done Draw procedure Draw; virtual; Переопределяемость: переопределяется редко Рисует "кнопку", используя соответствующую ее текущему сос- тоянию палитру (обычная, по умолчанию, недоступная) и располагает метку в соответствии с битом bfLeftJust поля Flags. DrawState procedure DrawState (Down: Boolean); Переопределяемость: иногда переопределяется Рисует "кнопку" либо в нажатом, либо в ненажатом состоянии. Если Down равно True, то DrawState рисует кнопку нажатой, в про- тивном случае рисует ее ненажатой. Для рисования отображаемого элемента Draw вызывает DrawState со значением Down, равным False. В зависимости от положения мыши в момент перещелкивания HandleEvent вызывает DrawState в ответ на перемещение и перещелкивание мыши. См. также: TButtonDraw GetPalette function GetPalette: PPalette; virtual; Переопределяемость: иногда переопределяется Возвращает указатель на палитру CButton, установленную по умолчанию. HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Переопределяемость: иногда переопределяется Отвечает на одно из трех способов нажатий: выбор "кнопки" с помощью "мыши", нажатие оперативной клавиши или нажатие "кнопки", используемой по умолчанию при получении сообщения cmDefault. Когда пользователь нажимает кнопку, кнопка генерирует командное событие с PutEvent, устанавливая значение Event.Command равным значению поля Command кнопки, а Event.InfoPtr равным @Self. "Кнопки" так же распознают сообщения cmGrabDefault и cmReleaseDefault, что позволяет им получать или терять состояние "кнопки", используемой по умолчанию, и cmCommandSetChanged, заставляющее их проверять, разрешены их команды или запрещены. Все остальные события обрабатываются вызовом метода HandleEvent, унаследованного от TView. См. так же: TView.HandleEvent MakeDefault procedure MakeDefault(Enable: Boolean); Этот метод ничего не делает, если "кнопка" уже используется по умолчанию. В противном случае он уведомляет Owner об изменении ее статуса "кнопки по умолчанию" с помощью сообщения. Если Enable = True, то выдается сообщение cmGrabDefault, в противном случае посылает сообщение cmReleaseDefault. "Кнопка" отображается зано- во, чтобы показать новое состояние. См. так же: TButton.AmDefault, bfDefault Press procedure Press; virtual; Переопределяемость: иногда переопределяется Вызывается для генерации эффекта, связанного с "нажатием" объекта кнопки. Существующий по умолчанию метод посылает владель- цу кнопки сообщение evBroadcast с параметром команды cmRecordHistory (заставляющее все объекты типа THistory записать содержимое объектов введенных строк, которыми они управляют), а затем используют PutEvent или Message для генерации сообщения в зависимости от значения флага bfBroadcast. Press можно переопределить для изменения поведения кнопки при нажатии, но возможно, что в измененном методе Press понадобится вызывать унаследованный метод. См. так же: TView.HandleEvent SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Переопределяемость: переопределяется редко. Вызывает метод SetState, унаследованный от TView, для уста- новки флагов состояния, а затем вызывает DrawView, если "кнопка" получила состояние sfSelected или sfActive. Если она стала актив- ной (т. е. если AState содержит sfFocused), то "кнопка" забирает или отдает состояние "по умолчанию" кнопке, используемой по умол- чанию, с помощью MakeDefault. См. также: TCView.SetState, TButton.MakeDefault Store procedure Store(var S: TStream); Сохраняет объект кнопки в потоке S, вызывая метод Store(S), унаследованный от TView, а затем вызывает S.Write для сохранения значений Title и Command. Используется совместно с TButton.Load для сохранения и восстановления объектов TButton из потока. См. также: TView.Store, TButton.Load, TStream.Write *- Палитра ----------------------------------------------------------------- Объект "кнопки" использует назначенную по умолчанию палитру CButton для отображения элементов от 10 до 15 палитры CDialog. 1 2 3 4 5 6 7 8 ЙННННСННННСННННСННННСННННСННННСННННСНННН» CButton є 10 і 11 і 12 і 13 і 14 і 14 і 14 і 15 є ИННСНПННСНПННСНПННСНПННСНПННСНПННСНПНСННј і і і і і і і і Нормальный ДДЩ і і і і і і АДДТень текст і і і і і і Текст по ДДДДДДЩ і і і і АДДДД Выделенная умолчанию і і і і оперативная клавиша Выделенный ДДДДДДДДДДДЩ і і АДДДДДДДДД Оперативная текст і і клавиша по умолчанию Запрещенный ДДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДД Оперативная текст обычная клавиша *- Тип TByteArray Objects ----------------------------------------------------------------- Описание: TByteArray = array[0..32767] of Byte; Функция: Тип массива байт для общего использования при прео- бразовании типа. См. также: TStringListMaker *- Тип TCharSet Objects ----------------------------------------------------------------- Описание: TCharSet = set of Char; Функция: Объекты фильтра определителя допустимости использу- ют поле типа TCharSet для определения допустимых символов, кото- рые пользователь может вводить в строке с фильтруемым вводом. См. также: TFilterValidator.ValidChars *- Объекты TChDirDialog StdDialog ----------------------------------------------------------------- TChDirDialog реализует диалоговое окно с названием "Change Directory", обеспечивающее строку для ввода пользователем имени каталога. Строка ввода имеет список предыстории и строку-список каталога с вертикальным полем прокрутки и деревом структуры ката- лога. *- Поля ----------------------------------------------------------------- ChDirButton ChDirButton: PButton; ChDirButton указывает на объект кнопки, изменяющий каталог, показываемый в текущий момент в строке ввода DirInput. DirInput DirInput: PInputLine; DirInput указывает на объект вводимой строки, в которой пользователь может печатать изменяемый каталог. По умолчанию вводимая строка показывает имя пути каталога, выбранного в теку- щий момент в дереве каталога. DirList DirList: PDirListBox; DirList указывает на окно-список, содержащее структуру ката- лога на текущем диске. OkButton OkButton: PButton; DirList указывает на объект кнопки, закрывающей диалоговое окно. *- Методы ----------------------------------------------------------------- Init constructor Init (AOptions: Word; HistoryId: Word); Создает объект диалогового окна изменения каталога с опция- ми, указанными в Options, и связывает список предыстории, обозна- ченный HistoryID, с вводимой строкой каталогов, на которую указы- вает DirInput. AOptions содержит сочетание констант cdXXXX. См. также: константы cdXXXX Load constructor Load (var S: TStream); Создает и загружает объект диалогового окна изменения ката- лога из потока путем вызова конструктора Load, унаследованного от TDialog, с последующим чтением дополнительных полей, определенных в TChDirDialog. См. также: TDialog.Load DataSize function DataSize: Word; virtual; По умолчанию DataSize возвращает ноль. Если новый объект создается на базе TChDirDialog, использующего для передачи данных диалоговому окну методы SetData и GetData, то необходимо также переопределить DataSize, чтобы она возвращала размер в байтах данных, используемых SetData и GetData. GetData procedure GetData (var Rec); virtual; Обрабатывает события в диалоговом окне, вызывая сначала унаследованный HandleEvent из TDialog для обработки стандартного поведения диалогового окна, после чего обрабатывает команды cmRevert и cmChangeDir, которые могут генерироваться кнопками диалогового окна. SetData procedure SetData (var Rec); virtual; По умолчанию SetData не выполняет никаких действий. Если диалоговому окну методы SetData и GetData, то необходимо также переопределить DataSize, чтобы она возвращала размер в байтах данных, используемых SetData и GetData. GetData procedure GetData (var Rec); virtual; Обрабатывает события в диалоговом окне, вызывая сначала унаследованный HandleEvent из TDialog для обработки стандартного поведения диалогового окна, после чего обрабатывает команды cmRevert и cmChangeDir, которые могут генерироваться кнопками диалогового окна. SetData procedure SetData (var Rec); virtual; По умолчанию SetData не выполняет никаких действий. Если объекты получаются на основе TChDirDialog, имеющему органы управ- ления, значения которых необходимо задавать, то необходимо перео- пределить SetData так, чтобы она копировала в Rec DataSize байт. При переопределении SetData необходимо также переопределять DataSize и GetData. SetData procedure Store (var S:TStream); Сохраняет объект диалогового окна в потоке S, вызывая снача- ла метод Store, унаследованный от TDialog, а затем записывая дополнительные поля, введенные TChDirDialog. Valid function Valid (Command: Word): Boolean; virtual; Возвращает True в случае, если Command отлично от cmOK. Если пользователь нажал кнопку Ok, генерирующую команду cmOK, то Valid проверяет содержимое строки ввода DirInput на предмет того, ука- зывает ли она правильное имя каталога. Если каталог является допустимым, то Valid возвращает значение True; в противном случае она вызывает окно сообщений "Invalid Directory" и возвращает False. *- TCheckBoxes Dialogs ----------------------------------------------------------------- TCheckBoxes- это специализированный кластер, содержащий от 1 до 16 элементов управления. В отличие от кнопок с зависимой фик- сацией, здесь может выбираться любое количество независимых "кно- пок", поэтому кластер содержит кнопки, выбранные по умолчанию. Кнопки можно отмечать "мышью", движением курсора и нажатием ком- бинации Alt-буква. Каждая кнопка может быть подсвечена и ее сос- тояние выбранности может быть включено/выключено (клавишей пробе- ла). Если кнопка выбрана, то в ней появляется Х. Другие части Вашей программы обычно проверяют состояние независимых "кнопок" для определения того, какая установка выбра- на пользователем (например, в интегрированной среде параметры компилятора и компоновщика выбираются именно таким способом). Кластеры независимых "кнопок" часто связаны с объектами TLabel, дающими пользователю обзор выбираемых установок. *- Методы ----------------------------------------------------------------- Заметим, что TCheckBoxes не переопределяет конструкторов TCluster, деструктор и обработчик событий. Порожденные типы объе- ктов могут, однако, при необходимости переопределить их. Draw procedure Draw; virtual; Переопределяемость: переопределяется редко. Рисует объект TCheckBoxes, вызывая наследуемый метод TCluster.DrawBox. По умолчанию независимая "кнопка" имеет вид: " [ ] ", когда она не выбрана, и " [X] ", когда она выбрана. Заметим, что если границы отображаемого элемента достаточно велики, то независимые "кнопки" могут отображаться в несколько колонок. См. так же: TCluster.DrawBox Mark function Mark(Item: Integer) : Boolean; virtual; Переопределяемость: переопределяется редко. Возвращает значение True, если бит элемента в Value с номе- ром Item взведен, т.е. если данная кнопка нажата. Вы можете пере- определить это, установив другую интерпретацию поля Value. По умолчанию элементы нумеруются от 0 до 15. См. также: TCheckBoxes.Press Press procedure Press(Item: Integer); virtual; Изменяет значение бита элемента Value с номером Item на противоположное. Вы можете переопределить его для другой интерп- ретации поля Value. По умолчанию элементы нумеруются от 0 до 15. См. также: TCheckBoxes.Mark *- Палитра ----------------------------------------------------------------- По умолчанию объекты независимых "кнопок" используют CCluster- палитру, назначаемую по умолчанию для всех объектов-кластеров. 1 2 3 4 ЙННННСННННСННННСНННН» CCluster є 16 і 17 і 18 і 18 є ИННСНПННСНПННСНПННСНј Нормальный ДДДДЩ і і АДДД Выделенная текст і і оперативная клавиша Выделенный ДДДДДДДДДЩ АДДДДДДДД Обычная оперативная текст клавиша *- TCluster Dialogs ----------------------------------------------------------------- Кластер - это группа элементов управления, которые "отклика- ются" одинаковым образом. TCluster представляет собой абстрактный тип объекта, поведение которого обобщает работу с независимыми и зависимыми кнопками. В то время, как "кнопки" используются для генерации команд, а строки ввода - для редактирования строк, кластеры используются для переключения битовых значений поля Value типа Longint. Эти стандартные наследники TCluster используют различные алгоритмы изменения Value: TCheckBoxes просто изменяет значение бита на противоположное, а TRadioButtons взводит один бит и сбрасывает предварительно установленный бит. Оба эти объекта наследуют почти все свое поведение от TCluster. *- Поля ----------------------------------------------------------------- EnableMask EnableMask: Longint; EnableMask содержит допустимое состояние первых 32 элементов кластера, причем каждый бит соответствует каждому элементу клас- тера. Младший бит управляет состоянием первого элемента кластера. Если бит EnableMask взведен, то элемент является доступным. Сбра- сывание бита делает соответствующий элемент недоступным. По умол- чанию конструктор кластера устанавливает значение EnableMask равным $FFFFFFFF, что означает тот факт, что доступны все элемен- ты. Sel (только для чтения) Sel: Integer; Выбранный в настоящий момент элемент кластера. Strings (только для чтения) Strings: TStringCollection; Список элементов кластера. Value (только для чтения) Value: Longint; Текущие значения элемента управления. Действительный смысл этого поля определяется методами, разработанными в типах объек- тов, порожденных от TCluster. *- Методы ----------------------------------------------------------------- Init constructor Init(var Bounds: TRect; AStrings: PSItem); Очищает поля Value и Sel. Параметр AStrings обычно представ- ляет собой набор вложенных вызовов глобальной функции NewSItem, позволяющих создавать весь кластер зависимых или независимых кнопок в одном вызове конструктора: var Control: PView; ... R.Assign(30, 5, 52, 7); Control := New(PRadioButtons, Init(R, NewSItem('~F~orward', NewSItem('~B~ackward', nil)))); ... Для добавления в кластер дополнительных зависимых или неза- висимых "кнопок" просто скопируйте первый вызов NewSItem и заме- ните заголовок на требуемый текст. Затем добавляется дополнитель- ная закрывающая скобка для каждой вновь добавленной строки, и оператор будет компилироваться без синтаксических ошибок. См. так же: тип TSItem Load constructor Load(var S: TStream); Создает объект TCluster, вызывая сначала конструктор Load, унаследованный от TView, а затем устанавливая значения полей Value и Set вызовом S.Read. Наконец, поле String кластера загру- жается из S с помощью Strings.Load(S). Используется совместно с TCluster.Store для сохранения и получения объектов TCluster из потока. См. так же: TCluster.Store, TView.Load Done destructor Done; virtual; Переопределяемость: иногда переопределяется. Освобождает память, выделенную под строку кластера, затем уничтожает отображаемый элемент, вызывая метод деструктора Done, унаследованный от TView. См. также: TView.Done ButtonState function ButtonState (Item: Integer): Boolean; Возвращает состояние доступности кнопки кластера с номером Item. Значение True указывает на тот факт, что кнопка доступна; False - недоступна. Объекты кластера вызывают ButtonState в мето- дах Draw и HandleEvent для обеспечения того, чтобы недоступные элементы выглядели отлично от доступных, и чтобы пользователь не мог работать с ними. См. также: TCluster.EnableMask DataSize function DataSize: Word; virtual; Переопределяемость: используется редко. Возвращает размер Value. При создании новых объектов на базе TCluster, которые изменяют Value или добавляют другие поля, необ- ходимо переопределять DataSize, чтобы она возвращала размер любых данных, переданных GetData и SetData. См. также: TCluster.GetData, TCluster.SetData DrawBox procedure DrawBox(Icon: String; Marker: Char); Вызывается методами Draw порожденных типов, чтобы рисовать прямоугольник перед строкой для каждого элемента кластера. Icon - это строка из 5 символов (' [ ] ' для независимых и ' ( ) ' для зависимых "кнопок"). Marker- это символ, используемый для указа- ния того, что "кнопка" отмечена ('X' для независимых и '.' для зависимых "кнопок"). См. также: TCheckBoxes.Draw, TRadioButtons.Draw DrawMultiBox procedure DrawMultiBox(Icon: String; Marker: String); Многопозиционные кнопки с независимой фиксацией вызывают вместо DrawBox DrawMultiBox, передавая вместо символа маркеров строку маркеров. Символы в Marker соответствуют возможным состоя- ниям кнопки. См. также: TCluster.DrawBox, TCluster.MultiMark GetData procedure GetData(var Rec); virtual; Переопределяемость: используется редко. Записывает поле Value в Rec. Если на базе TCluster создается новый объект, изменяющий значение поля Value, то необходимо пере- определить GetData для того, чтобы она работала с DataSize и SetData. См. также: TCluster.DataSize, TCluster.GetData, TCluster.SetData GetHelpCtx function GetHelpCtx: Word; virtual; Переопределяемость: используется редко. Возвращает значение Sel, сложенное с HelpCtx. Это позволяет задать отдельный контекст подсказки для каждого элемента класте- ра. Допустимый диапазон контекстов равен HelpCtx + число элемен- тов кластера - 1. GetPalette function GetPalette: PPalette; virtual; Переопределяемость: иногда используется. Возвращает указатель на палитру (назначенную по умолчанию) CCluster. HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Переопределяемость: используется редко. Вызывает метод HandleEvent, унаследованный от TView, а затем обрабатывает все события от "мыши" и клавиатуры, относящиеся к этому кластеру. Элементы управления выделяются отметкой с помощью "мыши" или клавишами перемещения курсора (при выборе клавишей пробела). Кластер отображается заново, чтобы показать вновь выб- ранные элементы. См. так же: TView.HandleEvent Mark function Mark(Item: Integer): Boolean; virtual; Переопределяемость: всегда переопределяется. По умолчанию TCluster.Mark возвращает значение False. Каждый новый объект, созданный на базе TCluster, должен переопределять Mark, возвращая значение True, если элемент управления с номером Item в кластере отмечен, и False в противном случае. Draw вызыва- ет Mark для определения отмеченных элементов и рисования для них соответствующих окон. MovedTo procedure MovedTo(Item: Integer); virtual; Переопределяемость: используется редко. Перемещает поле выбора к Item-му элементу кластера. Вызыва- ется из HandleEvent в ответ на события перещелкивания мышью или нажатия клавиш управления курсором. MultiMark function MultiMark (Item: Integer): Byte; virtual; В кластере многопозиционных кнопок с независимой фиксацией возвращает состояние отметки для кнопки с номером Item. В обычных кластерах кнопка имеет только два состояния, поэтому Mark возвра- щает значение типа Boolean. Однако кластеры с многопозиционных кнопок должны нести большее количество информации, поэтому вместо Mark они вызывают MultiMark. См. также: TCluster.Mark Press procedure Press(Item: Integer); virtual; Переопределяемость: всегда переопределяется. Вызывается из HandleEvent, когда элемент управления с номе- ром Item в кластере выбирается с помощью "мыши", либо нажатия клавиши "пробела". Press представляет собой абстрактный метод, который должен быть переопределен при создании любого нового типа на базе TCluster. SetButtonState procedure SetButtonState (AMask: Longint; Enable: Boolean); Сбрасывает или взводит биты EnableMask в соответствии с битами из AMask. Если Enable равно True, то все взведенные биты из AMask делаются доступными в EnableMask; если Enable равно False, то биты сбрасываются. Если в результате установки отдель- ных битов недопустимыми весь кластер состоит из недопустимых кнопок, то SetButtonState делает кластер невыбираемым. SetData procedure SetData(var Rec); virtual; Переопределяемость: используется редко. Читает поле Value из данной записи и вызывает DrawView для перерисовки кластера. Если на базе TCluster создается новый объект, изменяющий значение поля Value или добавляющий новые поля, то необходимо переопределить SetData для того, чтобы она работала с DataSize и GetData. См. также: TCluster.DataSize, TCluster.GetData, TView.DrawView SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Переопределяемость: используется редко. Вызывает метод SetState, унаследованный от TView, для взвода или сброса битов, переданных в AState, а затем вызывает DrawView для обновления кластера в случае, если AState равно sfSelected. См. также: TView.SetState, TView.DrawView Store procedure Store(var S: TStream); Сохраняет объект TCluster в потоке S, вызывая сначала метод Store, унаследованный от TView, а затем записывает Value и Sel в S, после чего сохраняет поле Strings кластера, используя его метод Store. Используется совместно с TCluster.Load для сохране- ния и получения объектов TCluster из потока. См. также: TCluster.Load, TStream.Write *- Палитра ----------------------------------------------------------------- Объекты TCluster используют CCluster (палитру, назначенную по умолчанию) для всех объектов кластера, чтобы отобразить в ней элементы с 16 по 18 стандартной палитры диалогового окна: 1 2 3 4 ЙННННСННННСННННСНННН» CCluster є 16 і 17 і 18 і 18 є ИННСНПННСНПННСНПННСНј Нормальный ДДДДЩ і і АДДД Выделенная текст і і оперативная клавиша Выделенный ДДДДДДДДДЩ АДДДДДДДД Обычная оперативная текст клавиша *- TCollection Objects ----------------------------------------------------------------- TCollection- это основной тип для реализации любого набора элементов, включающих другие объекты. TCollection- это намного более общее понятие, чем обычные массив, множество или список. Размер объектов TCollection динамически устанавливается во время выполнения, и обеспечивает базовый тип для многих специализирова- нных типов, таких, как TSortedCollection, TStringCollection и TResourceCollection. В дополнение к методам добавления и удаления элементов, TCollection представляет несколько итерационных прог- рамм, которые вызывают процедуру или функцию для каждого элемента набора. TCollection предполагает, что элементы набора получаются прямо или косвенно из TObject так, что для уничтожения элемента он может вызывать деструктор элемента Done. Если Вы хотите испо- льзовать набор элементов, не происходящих от TObject, то необхо- димо обязательно переопределить метод FreeItem для того, чтобы правильно уничтожить элемент. Набор строк, например, осуществляет набор динамических строк Паскаля. *- Поля ----------------------------------------------------------------- Count (только для чтения) Count: Integer; Текущее число элементов в наборе, максимальное число которых равно MaxCollectionSize. Заметьте, что наборы индексируют элемен- ты с 0, а это означает, что Count часто превышает на 1 индекс последнего элемента. См. также: переменная MaxCollectionSize Delta (только для чтения) Delta: Integer; Число элементов, на которое увеличивается список Items при его заполнении. Если Delta равна 0, то набор не может расти боль- ше размера, установленного в Limit. Примечание: Увеличение размера набора достаточно плохо влия- ет на производительность. Чтобы минимизировать число раз, когда это происходит, попытайтесь установить начальное Limit равным такому количеству, которого будет достаточно для всех элементов, которые Вы собираетесь объединять в набор, и установите Delta так, чтобы его значение допускало расширение на разумное количес- тво. См. также: Limit, TCollection.Init Items (только для чтения) Items: PItemList; Указатель на массив указателей на элементы. См. также: тип TItemList Limit (только для чтения) Limit: Integer; Выделенный в текущий момент размер (в элементах) списка Items. См. также: Delta, TCollection.Init *- Методы ----------------------------------------------------------------- Init constructor Init(ALimit, ADelta: Integer); Создает объект набора с Limit, равным ALimit, и Delta, рав- ным ADelta. Набор выделяет объем памяти, достаточный для для работы с ALimit элементов, но набор может расширяться, увеличива- ясь по ADelta до тех пор, пока будет достаточно памяти или пока число элементов не достигнет MaxCollectionSize. См. также: TCollection.Limit, TCollection.Delta. Load constructor Load(var S: TStream); Создает и загружает набор из потока S. TCollection.Load вызывает метод GetItem для каждого элемента набора. См. также: TCollection.GetItem Done destructor Done; virtual; Переопределяемость: часто используется. Удаляет набор и освобождает память, занимаемую всеми элемен- тами набора, вызывая метод TCollection.FreeAll и устанавливая Limit равным 0. См. также: TCollection.FreeAll At function At(Index: Integer) : Pointer; Возвращает указатель на элемент с индексом Index в наборе. Этот метод позволяет интерпретировать набор, как индексированный с 0 массив. Если индекс меньше 0 или больше или равен Count, то At вызывает Error с аргументом coIndexError, после чего возвраща- ет nil. См. также: TCollection.IndexOf |