компонентов общего назначения библиотеки Delphi5

         

Диалог в старом стиле при включенной опции ofOldStyleDialog и выключенной опции ofHideReadOnly

В компонентах диалогов открытия и сохранения файлов предусмотрена возможность обработки ряда событий. Такая обработка может потребоваться, если рассмотренных опций, несмотря на их количество, не хватает, чтобы установить все диктуемые конкретным приложением ограничения на выбор файлов. Событие OnCanClose возникает при нормальном закрытии пользователем диалогового окна после выбора файла. При отказе пользователя от диалога — нажатии кнопки Отмена, клавиши Esc и т.д. событие OnCanClose не наступает. В обработке события OnCanClose вы можете произвести дополнительные проверки выбранного пользователем файла и, если по условиям вашей задачи этот выбор недопустим, вы можете известить об этом пользователя и задать значение false передаваемому в обработчик параметру CanClose. Это не позволит пользователю закрыть диалоговое окно.

Можно также написать обработчики событий OnFolderChange — изменение каталога, OnSelectionChange — изменение имени файла, OnTypeChange — изменение типа файла. В этих обработчиках вы можете предусмотреть какие-то сообщения пользователю.

Теперь приведем примеры использования диалогов OpenDialog и SaveDialog. Пусть ваше приложение включает окно редактирования Memo1, в которое по команде меню Открыть вы хотите загружать текстовый файл, а после каких-то изменений, сделанных пользователем, — сохранять по команде Сохранить текст в том же файле, а по команде Сохранить как... — в файле с другим именем.

Введите на форму компоненты — диалоги OpenDialog и SaveDialog. Предположим, что вы оставили их имена по умолчанию — OpenDialog1 и SaveDialog1. Поскольку после чтения файла вам надо запомнить его имя, чтобы знать под каким именем потом его сохранять, вы можете определить для этого имени переменную, назвав ее, например, FName: var FName: string;

Тогда обработка команды Открыть может сводиться к следующему оператору: if OpenDialog1.Execute then begin FName := OpenDialog1.FileName; Memo1.Lines.LoadFromFile(FName); end;

Этот оператор вызывает диалог, проверяет, выбрал ли пользователь файл (если выбрал, то функция Execute возвращает true), после чего имя выбранного файла (OpenDialog1.FileName) сохраняется в переменной FName и файл загружается в текст Memo1 методом LoadFromFile.

Обработка команды Сохранить выполняется оператором Memo1.Lines.SaveToFile(FName);

В данном случае нет необходимости обращаться к какому-то диалогу, поскольку имя файла известно: оно хранится в переменной FName.

Обработка команды Сохранить как... выполняется операторами: SaveDialog1.FileName := FName; if SaveDialog1.Execute then begin FName := SaveDialog1.FileName; Memo1.Lines.SaveToFile(FName); end;

Первый из этих операторов присваивает свойству FileName компонента SaveDialog1 запомненное имя файла. Это имя по умолчанию будет предложено пользователю при открытии диалога Сохранить как.... Следующий оператор открывает диалог и, если пользователь выбрал в нем файл, запоминает новое имя файла и сохраняет в файле с этим именем текст компонента Memo1.

Мы рассмотрели диалоги открытия и сохранения файлов произвольного типа. Начиная с Delphi 3 в библиотеке имеются специализированные диалоги открытия и закрытия графических файлов: OpenPictureDialog и SavePictureDialog. Диалоговые окна, открываемые этими файлами, приведены на Рисунок 8.5 и 8.6. От окон, открываемых компонентами OpenDialog и SaveDialog (Рисунок 8.1, 8.2), они отличаются удобной возможностью просматривать изображения в процессе выбора файла.


Диалог выбора цвета — компонент ColorDialog


Компонент ColorDialog вызывает диалоговое окно выбора цвета, представленное на Рисунок 8.9. В нем пользователь может выбрать цвет из базовой палитры или, нажав кнопку Определить цвет, раскрыть дополнительную панель (на Рисунок 8.9 она раскрыта), позволяющую синтезировать цвет, отличный от базовых. Синтезированный цвет можно добавить кнопкой Добавить в набор в палитру дополнительных цветов на левой панели и использовать его в дальнейшем.



Диалог выбора шрифта — компонент FontDialog


Компонент FontDialog вызывает диалоговое окно выбора атрибутов шрифта, представленное на Рисунок 8.8. В нем пользователь может выбрать имя шрифта, его стиль (начертание), размер и другие атрибуты.



Диалоги открытия и сохранения


Компоненты OpenDialog — диалог «Открыть файл» и SaveDialog — диалог «Сохранить файл как...», пожалуй, используются чаще всего, в большинстве приложений. Примеры открываемых ими диалоговых окон приведены на Рисунок 8.1 и 8.2.



Диалоги печати и установки принтера — компоненты PrintDialog и PrinterSetupDialog


Компонент PrintDialog вызывает диалоговое окно печати, представленное на Рисунок 8.10. В нем пользователь может выбрать принтер и установить его свойства, указать число копий и последователъность их печати, печатать в файл или непосредственно на принтер, выбрать печатаемые страницы или печатать только выделенный фрагмент.



Диалоги поиска и замены текста — компоненты FindDialog и ReplaceDialog


Компоненты FindDialog и ReplaceDialog, вызывающие диалоги поиска и замены фрагментов текста (Рисунок 8.12 и 8.13), очень похожи и имеют одинаковые свойства, кроме одного, задающего заменяющий текст в компоненте ReplaceDialog. Такое сходство не удивительно, поскольку ReplaceDialog — производный класс от FindDialog.





Диалоговое окно настройки печати


Компонент PrintDialog не осуществляет печать. Он только позволяет пользователю задать атрибуты печати. А сама печать должна осуществляться программно с помощью объекта Printer или иным путем (о способах печати см. ).

Рассмотренные ранее диалоговые компоненты возвращали одно свойство — имя файла, цвет, или один объект — Font, содержащий множество свойств. В отличие от них компонент PrintDialog возвращает ряд свойств, характеризующих выбранные пользователем установки. Это следующие свойства:

PrintRangeПоказывает выбранную пользователем радиокнопку из группы Печатать: prAllPages — выбрана кнопка Все страницы, prSelection — выбрана кнопка Страницы с ... по ..., prPageNums — выбрана кнопка Страницы FromPageПоказывает установленную пользователем начальную страницу в окне Страницы с ... по ... ToPageПоказывает установленную пользователем конечную страницу в окне Страницы с ... по ... PrintToFileПоказывает, выбран ли пользователем индикатор Печать в файл CopiesПоказывает установленное пользователем число копий CollateПоказывает, выбран ли пользователем индикатор Разобрать

Перед вызовом диалога желательно определить, сколько страниц в печатаемом тексте, и задать параметры MaxPage и MinPage — максимальный и минимальный номера страниц. В противном случае пользователю в диалоговом окне не будет доступна кнопка Страницы с ... по .... Кроме того следует определить множество опций в свойстве Options:

poDisablePrintToFileЗапретить доступ к индикатору Печать в файл. Эта опция работает только при включенной опции poPrintToFile poHelpОтображать в диалоговом окне кнопку Справка. Опция может не работать для некоторых версий Windows 95/98 poPageNumsСделать доступной радиокнопку Страницы, позволяющую пользователю задавать диапазон печатаемых страниц poPrintToFileОтображать в диалоговом окне кнопку Печать в файл poSelectionСделать доступной кнопку Выделение, позволяющую пользователю печатать только выделенный текст poWarningВыдавать замечания, если пользователь пытается послать задачу на неустановленный принтер

Теперь остановимся на компоненте PrinterSetupDialog, вызывающем диалоговое окно установки принтера, представленное на Рисунок 8.11. Это единственный диалоговый компонент, не имеющий никаких специфических свойств, которые надо было бы устанавливать или читать. Диалог выполняет операции по установке принтера, на котором будет производиться печать, и задании его свойств. Этот диалог не возвращает никаких параметров.

Диалоговое окно сохранения файла

Все свойства этих компонентов одинаковы, только их смысл несколько различен для открытия и закрытия файлов. Основное свойство, в котором возвращается в виде строки выбранный пользователем файл, — FileName. Значение этого свойства можно задать и перед обращением к диалогу. Тогда оно появится в диалоге как значение по умолчанию в окне Имя файла (см. Рисунок 8.1, 8.2).

Типы искомых файлов, появляющиеся в диалоге в выпадающем списке Тип файла (Рисунок 8.1, 8.2), задаются свойством Filter. В процессе проектирования это свойство проще всего задать с помощью редактора фильтров, который вызывается нажатием кнопки с многоточием около имени этого свойства в Инспекторе Объектов. При этом открывается окно редактора, вид которого представлен на Рисунок 8.3. В его левой панели Filter Name вы записываете тот текст, который увидит пользователь в выпадающем списке Тип файла диалога. А в правой панели Filter записываются разделенные точками с запятой шаблоны фильтра. В примере Рисунок 8.3 задано два фильтра: текстовых файлов с расширениями .txt и .doc и любых файлов с шаблоном *.*.


Диалоговое окно сохранения файла изображения


Свойства компонентов OpenPictureDialog и SavePictureDialog ничем не отличаются от свойств компонентов OpenDialog и SaveDialog. Единственное отличие — заданное значение по умолчанию свойства Filter в OpenPictureDialog и SavePictureDialog. В этих компонентах заданы следующие фильтры:

All (*.jpg; *.jpeg; *.bmp; *.ico; *.emf; *.wmf)*.jpg; *.jpeg; *.bmp; *.ico; *.emf; *.wmf JPEG Image File (*.jpg)*.jpg JPEG Image File (*.jpeg)*.jpeg Bitmaps (*.bmp)*.bmp Icons (*.ico)*.ico Enhanced Metafiles (*.emf)*.emf Metafiles (*.wmf)*.wmf

В этих фильтрах перечислены все типы графических файлов, с которыми может работать диалог. Так что вам остается удалить, если хотите, фильтры тех файлов, с которыми вы не хотите работать, добавить, может быть, фильтр «Все файлы (*.*)» и перевести на русский язык названия типов.

Диалоговое окно выбора атрибутов шрифта


Основное свойство компонента — Font типа TFont (см. ), в котором вы можете задать при желании начальные установки атрибутов шрифта и в котором вы можете прочесть значения атрибутов, выбранные пользователем в процессе диалога.

Свойства MaxFontSize и MinFontSize устанавливают ограничения на максимальный и минимальный размеры шрифта. Если значения этих свойств равны 0 (по умолчанию), то никакие ограничения на размер не накладываются. Если же значения свойств заданы (обычно это целесообразно делать исходя из размеров компонента приложения, для которого выбирается шрифт), то в списке Размер диалогового окна (см. Рисунок 8.8) появляются только размеры, укладывающиеся в заданный диапазон. При попытке пользователя задать недопустимый размер ему будет выдано предупреждение вида «Размер должен лежать в интервале ...» и выбор пользователя отменится. Свойства MaxFontSize и MinFontSize действуют только при включенной опции fdLimitSize (см. ниже).

Свойство Device определяет, из какого списка возможных шрифтов будет предложен выбор в диалоговом окне: fdScreen — из списка экрана (по умолчанию), fdPrinter — из списка принтера, fdBoth — из обоих.

Свойство Options содержит множество опций:

fdAnsiOnlyОтображать только множество шрифтов символов Windows, не отображать шрифтов со специальными символами fdApplyButtonОтображать в диалоге кнопку Применить независимо от того, предусмотрен ли обработчик события OnApply fdEffectsОтображать в диалоге индикаторы специальных эффектов (подчеркивание и др.) и список Цвет fdFixedPitchOnlyОтображать только шрифты с постоянной шириной символов fdForceFontExistПозволять пользователю выбирать шрифты только из списка, запрещать ему вводить другие имена fdLimitSizeРазрешить использовать свойства MaxFontSize и MinFontSize, ограничивающие размеры шрифта fdNoFaceSelОткрывать диалоговое окно без предварительно установленного имени шрифта fdNoOEMFontsУдалять из списка шрифтов шрифты OEM fdScalableOnlyОтображать только масштабируемые шрифты, удалять из списка не масштабируемые (шрифты bitmap) fdNoSimulationsОтображать только шрифты и их начертания, напрямую поддерживаемые файлами, не отображая шрифты, в которых жирный стиль и курсив синтезируется fdNoSizeSelОткрывать диалоговое окно без предварительно установленного размера шрифта fdNoStyleSelОткрывать диалоговое окно без предварительно установленного начертания шрифта fdNoVectorFontsУдалять из списка векторные шрифты (типа Roman или Script для Windows 1.0) fdShowHelpОтображать в диалоговом окне кнопку Справка fdTrueTypeOnlyПредлагать в списке только шрифты TrueType fdWysiwygПредлагать в списке только шрифты, доступные и для экрана, и для принтера, удаляя из него аппаратно зависимые шрифты

По умолчанию все эти опции, кроме fdEffects, отключены.

Если установить опцию fdApplyButton, то при нажатии пользователем кнопки Применить возникает событие OnApply, в обработчике которого вы можете написать код, который применит выбранные пользователем атрибуты, не закрывая диалогового окна.

Приведем примеры применения компонента FontDialog. Пусть ваше приложение включает окно редактирования Memo1, шрифт в котором пользователь может выбирать командой меню Шрифт. Вы ввели в приложение компонент FontDialog, имя которого по умолчанию FontDialog1. Тогда обработчик команды Шрифт может иметь вид: if FontDialog1.Execute then Memo1.Font.Assign(FontDialog1.Font);

Приведенный оператор вызывает диалог выбора атрибутов шрифта и, если пользователь произвел выбор, то значения всех выбранных атрибутов, содержащиеся в свойстве FontDialog1.Font, присваиваются атрибутам окна редактирования, содержащимся в свойстве Memo1.Font. Шрифт в окне редактирования немедленно изменится.

Если вы установите в компоненте FontDialog1 опцию fdApplyButton, то можете написать обработчик события OnApply: Memo1.Font.Assign(FontDialog1.Font);

Тогда пользователь может наблюдать изменения в окне Memo1, нажимая в диалоговом окне кнопку Применить и не прерывая диалога. Это очень удобно, так как позволяет пользователю правильно подобрать атрибуты шрифта.

Если в качестве окна редактирования в вашем приложении вы используете RichEdit, то можете предоставить пользователю выбирать атрибуты шрифта для выделенного фрагмента текста или для вновь вводимого текста. Тогда выполнение команды меню Шрифт может осуществляться операторами: if FontDialog1.Execute then RichEdit1.SelAttributes.Assign(FontDialog1.Font);

Вы можете разрешить пользователю изменять шрифт не только отдельных компонентов, но и всех компонентов и надписей на форме. Это осуществляется оператором: if FontDialog1.Execute then Font.Assign(FontDialog1.Font);

В этом операторе свойство Font без ссылки на компонент подразумевает шрифт формы.

Диалоговое окно выбора цвета


Основное свойство компонента ColorDialog — Color. Это свойство соответствует тому цвету, который выбрал в диалоге пользователь. Если при вызове диалога желательно установить некоторое начальное приближение цвета, это можно сделать, установив Color предварительно во время проектирования или программно. Свойство CustomColors типа TStrings позволяет задать заказные цвета дополнительной палитры. Каждый цвет определяется строкой вида <Имя цвета>=<шестнадцатиричное представление цвета>;

Имена цветов задаются от ColorA (первый цвет) до ColorP (шестнадцатый, последний). Например, строка ColorA=808022 задает первый заказной цвет. При задании цвета 2 младших разряда описывают интенсивность красного цвета, следующие 2 — зеленого, старшие — синего.

Свойство Options содержит множество следующих опций:

cdFullOpenОтображать сразу при открытии диалогового окна панель определения заказных цветов cdPreventFullOpenЗапретить появление в диалоговом окне кнопки Определить цвет, так что пользователь не сможет определять новые цвета cdShowHelpДобавить в диалоговое окно кнопку Справка cdSolidColorУказать Windows использовать сплошной цвет, ближайший к выбранному (это обедняет палитру) cdAnyColorРазрешать пользователю выбирать любые не сплошные цвета (такие цвета могут быть не ровными)

По умолчанию все опции выключены.

Приведем пример применения компонента ColorDialog. Если вы хотите, чтобы пользователь мог задать цвет какого-то объекта, например, цвет фона компонента Memo1, то это можно реализовать оператором if ColorDialog1.Execute then Memo1.Color := ColorDialog1.Color;

Диалоговое окно замены фрагмента текста


Компоненты имеют следующие основные свойства:

FindTextТекст, заданный пользователем для поиска или замены. Программно может быть установлен как начальное значение, предлагаемое пользователю ReplaceTextТолько в компоненте ReplaceDialog — текст, который должен заменять FindText PositionПозиция левого верхнего угла диалогового окна, заданная типом TPoint — записью, содержащей поля X (экранная координата по горизонтали) и Y (экранная координата по вертикали) LeftКоордината левого края диалогового окна, то же, что Position.X TopКоордината верхнего края диалогового окна, то же, что Position.Y OptionsМножество опций

Последний параметр Options — может содержать следующие свойства:

frDisableMatchCaseДелает недоступным индикатор С учетом регистра в диалоговом окне frDisableUpDownДелает недоступными в диалоговом окне кнопки Вверх и Вниз группы Направление, определяющие направление поиска frDisableWholeWordДелает недоступным индикатор Только слово целиком в диалоговом окне frDownВыбирает кнопку Вниз группы Направление при открытии диалогового окна. Если эта опция не установлена, то выбирается кнопка Вверх frFindNextЭта опция включается автоматически, когда пользователь в диалоговом окне щелкает на кнопке Найти далее, и выключается при закрытии диалога frHideMatchCaseУдаляет индикатор С учетом регистра из диалогового окна frHideWholeWordУдаляет индикатор Только слово целиком из диалогового окна frHideUpDownУдаляет кнопки Вверх и Вниз из диалогового окна frMatchCaseЭтот флаг включается и выключается, если пользователь включает и выключает опцию С учетом регистра в диалоговом окне. Можно установить эту опцию по умолчанию во время проектирования, чтобы при открытии диалога она была включена frReplaceПрименяется только для ReplaceDialog. Этот флаг устанавливается системой, чтобы показать, что текущее (и только текущее) найденное значение FindText должно быть заменено значением ReplaceText frReplaceAllПрименяется только для ReplaceDialog. Этот флаг устанавливается системой, чтобы показать, что все найденные значения FindText должны быть заменены значениями ReplaceText frShowHelpЗадает отображение кнопки Справка в диалоговом окне frWholeWordЭтот флаг включается и выключается, если пользователь включает и выключает опцию Только слово целиком в диалоговом окне. Можно установить эту опцию по умолчанию во время проектирования, чтобы при открытии диалога она была включена

Сами по себе компоненты FindDialog и ReplaceDialog не осуществляют ни поиска, ни замены. Они только обеспечивают интерфейс с пользователем. А поиск и замену надо осуществлять программно. Для этого можно пользоваться событием OnFind, происходящим, когда пользователь нажал в диалоге кнопку Найти далее, и событием OnReplace, возникающим, если пользователь нажал кнопку Заменить или Заменить все. В событии OnReplace узнать, какую именно кнопку нажал пользователь, можно но значениям флагов frReplace и frReplaceAll.

Поиск заданного фрагмента легко проводить, пользуясь функцией Object Pascal Pos, которая определена в модуле System следующим образом: function Pos(Substr: string; S: string): Byte; где S — строка, в которой ищется фрагмент текста, a Substr — искомый фрагмент. Функция возвращает позицию первого символа первого вхождения искомого фрагмента в строку. Если Substr в S не найден, возвращается 0.

Для организации поиска нам потребуется еще две функции: Сору и AnsiLowerCase. Первая из них определена как: function Copy(S: string; Index, Count: Integer): string;

Она возвращает фрагмент строки S, начинающийся с позиции Index и содержащий число символов, не превышающее Count. Функция AnsiLowerCase, определенная как function AnsiLowerCase(const S: string): string; возвращает строку символов S, переведенную в нижний регистр.

Теперь мы можем рассмотреть пример организации поиска. Пусть в вашем приложении имеется компонент Memo1 и при выборе раздела меню MFind вы хотите организовать поиск в тексте, содержащемся в Memo1. Для упрощения задачи исключим опцию поиска только целых слов и опцию поиска вверх от положения курсора.

Программа, реализующая поиск, может иметь следующий вид:

var SPos: integer; procedure TForm1.MFindClick(Sender: TObject); begin {запоминание позиции курсора} SPos := Memo1.SelStart; with FindDialog1 do begin {начальное значение текста поиска — текст, выделенный в Memo1} FindText := Memo1.SelText; {позиционирование окна диалога внизу Memo1} Position := Point(Form1.Left, Form1.Top + Memo1.Top + Memo1.Height); {удаление из диалога кнопок «Вверх», «Вниз», «Только слово целиком»} Options := Options + [frHideUpDown, frHideWholeWord]; {выполнение} Execute; end; end; procedure TForm1.FindDialog1Find(Sender: TObject); begin with FindDialog1 do begin if frMatchCase in Options {поиск с учетом регистра} then Memo1.SelStart := Pos(FindText, Copy(Memo1.Lines.Text, SPos + 1, Length(Memo1.Lines.Text))) + Spos - 1 {поиск без учета регистра} else Memo1.SelStart := Pos(AnsiLowerCase(FindText), AnsiLowerCase(Copy(Memo1.Lines.Text, SPos + 1, Length(Memo1.Lines.Text)))) + Spos - 1; if Memo1.SelStart >= Spos then begin {выделение найденного текста} Memo1.SelLength := Length(FindText); {изменение начальной позиции поиска} SPos := Memo1.SelStart + Memo1.SelLength + 1; end else if MessageDlg( 'Текст "'+FindText+'" не найден. Продолжать диалог?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then CloseDialog; end; Memo1.SetFocus; end;

В программе вводится переменная SPos, сохраняющая позицию, начиная с которой надо проводить поиск.

Процедура MFindClick вызывает диалог, процедура FindDialog1Find обеспечивает поиск с учетом или без учета регистра в зависимости от флага frMatchCase. После нахождения очередного вхождения искомого текста этот текст выделяется в окне Memo1 и управление передается этому окну редактирования. Затем при нажатии пользователем в диалоговом окне кнопки Найти далее, поиск продолжается в оставшейся части текста. Если искомый текст не найден, делается запрос пользователю о продолжении диалога. Если пользователь не ответил на этот запрос положительно, то диалог закрывается методом CloseDialog.

В дополнение к приведенному тексту полезно в обработчики событий OnClick и OnKeyUp компонента Memo1 ввести операторы SPos := Memo1.SelStart;

Это позволяет пользователю во время диалога изменить положение курсора в окне Memo1. Это новое положение сохранится в переменной SPos и будет использовано при продолжении поиска.

При реализации команды Заменить приведенные выше процедуры можно оставить теми же самыми, заменив в них FindDialog1 на ReplaceDialog1. Дополнительно можно написать процедуру обработки события OnReplace компонента ReplaceDialog1: procedure TForm1.ReplaceDialog1Replace(Sender: TObject); begin if Memo1.SelText <> '' then Memo1.SelText := ReplaceDialog1.ReplaceText; if frReplaceAll in ReplaceDialog1.Options then ReplaceDialog1Find(Self); end;

Этот код производит замену выделенного текста и, если пользователь нажал кнопку Заменить все, то продолжается поиск вызовом уже имеющейся процедуры поиска ReplaceDialog1Find*. Если же пользователь нажал кнопку Заменить, то производится только одна замена и для продолжения поиска пользователь должен нажать кнопку Найти далее.

* Предлагаемый автором алгоритм принажатии на кнопку Заменить все заменяет только одно значение и находит следующее. На наш взгляд такия действия более логично было бы задать кнопке Заменить, а для Заменить все организовать цикл. Причем такой цикл проще осуществить в процедуре ReplaceDialog1Find. В приведенном ниже коде кроме того введена локальная переменная ss, так как свойству SelStart нельзя присваивать отрицательные значения.
procedure TForm1.ReplaceDialog1Find(Sender: TObject); var ss: integer; last: Boolean; st: string; begin with ReplaceDialog1 do begin if (frFindNext in Options) then {изменение начальной позиции поиска} SPos := Memo1.SelStart + Memo1.SelLength + 1; last := not (frReplaceAll in Options); repeat if frMatchCase in Options {поиск с учетом регистра} then ss := Pos(FindText, Copy(Memo1.Lines.Text, SPos + 1, Length(Memo1.Lines.Text))) + Spos - 1 {поиск без учета регистра} else ss := Pos(AnsiLowerCase(FindText), AnsiLowerCase(Copy(Memo1.Lines.Text, SPos + 1, Length(Memo1.Lines.Text)))) + Spos - 1; if ss >= Spos then begin {выделение найденного текста} Memo1.SelStart := ss; Memo1.SelLength := Length(FindText); if (frReplaceAll in Options) then begin {замена} Memo1.SelText := ReplaceDialog1.ReplaceText; {изменение начальной позиции поиска} SPos := Memo1.SelStart + Memo1.SelLength + 1; end; end else begin if (frReplaceAll in Options) or (frReplace in Options) then st := 'Замена "' + FindText + '" на "' + ReplaceText + '" закончена' else st := 'Текст "' + FindText + '" не найден'; if MessageDlg(st + '. Продолжать диалог?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then CloseDialog; last:=true; end; until last; end; end; procedure TForm1.ReplaceDialog1Replace(Sender: TObject); begin if (frReplace in ReplaceDialog1.Options) and (Memo1.SelText <> '') then Memo1.SelText := ReplaceDialog1.ReplaceText; ReplaceDialog1Find(Self); end; - Примечание разработчика электронной версии.

Фрагменты диалогов — компоненты


Помимо законченных диалогов работы с файлами, в Delphi имеется ряд компонентов, представляющих собой фрагменты диалогов: выпадающие списки дисков (драйверов) — DriveComboBox и фильтров (масок) файлов — FilterComboBox, списки каталогов — DirectoryListBox и файлов — FileListBox, дерево каталогов — DirectoryOutline. Внешний вид этих компонентов вы можете увидеть на Рисунок 8.7. Компоненты работы с файловой системой облегчают вам создание собственных диалоговых окон, что нередко требуется. Например, вы можете захотеть включить в диалоговое окно отображение каких-то характеристик файлов (размера, даты создания и т.д.) или оперативный просмотр содержания текстовых файлов. Тогда вам очень пригодятся готовые компоненты работы с файлами. Правда, все они, кроме DirectoryOutline, предназначены в основном для Delphi 1 и в последующих версиях Delphi расположены на странице Win3.1 палитры компонентов. Это значит, что они не рекомендуются для 32-разрядных приложений. Но, во-первых, у вас остается компонент DirectoryOutline. Кроме того, никто не запрещает вам все-таки использовать и остальные компоненты в любых приложениях Delphi. И, наконец, если уж вы хотите четко следовать рекомендации не использовать первые четыре фрагмента диалогов в 32-разрядных приложениях, вы можете разработать свои аналогичные компоненты, используя обычный компонент ComboBox.



Компоненты — фрагменты диалогов

Начнем рассмотрение компонентов работы с файловой системой с компонента DriveComboBox — выпадающего списка дисков (драйверов). При размещении на форме этот компонент автоматически отображает список имеющихся на компьютере дисков. Во время выполнения приложения вы можете прочитать имя выбранного пользователем диска в свойстве Drive, а строку, содержащуюся в окне списка — в свойстве Text.

Свойство TextCase задает регистр отображения: tcUpperCase — в верхнем регистре, tcLowerCase — в нижнем.

Связать компонент DriveComboBox со списком каталогов, отображаемых компонентом DirectoryListBox, можно во время проектирования через свойство DirList компонента DriveComboBox. Это свойство может указывать на компонент типа DirectoryListBox. Можно обеспечить связь этих двух типов компонентов и программно, включив в обработчик события OnChange компонента DriveComboBox оператор DirectoryListBox1.Drive := DriveComboBox1.Drive;

Этот оператор задает имя диска, выбранное пользователем в компоненте DriveComboBox1, свойству Drive списка каталогов DirectoryListBox1.

Аналогичным оператором можно обеспечить связь компонента DriveComboBox с деревом каталогов и файлов в компоненте DirectoryOutline: DirectoryOutline1.Drive := DriveComboBox1.Drive;

Рассмотрим теперь выпадающий список фильтров — компонент FilterComboBox. Его основное свойство — Filter, которое задается так же, как в описанных ранее диалогах. К отдельным частям фильтра — тексту и маске, можно получить доступ через свойства Text и Mask соответственно. Связь компонента со списком файлов типа TFileListBox можно установить, задав свойство FileList.

Компонент DirectoryListBox отображает список каталогов диска, заданного свойством Drive. Значение этого свойства можно установить программно во время выполнения. Как уже говорилось выше, связь этого свойства с выбранным пользователем диском в компоненте DriveComboBox устанавливается или программно, или с помощью свойства DirectoryListBox компонента DriveComboBox.

Связь списка каталогов с компонентом типа TFileListBox, отображающим список файлов, осуществляется с помощью свойства FileList. Можно также использовать результаты выбора пользователем каталога, читая свойство Directory в обработчике события OnChange.

С компонентом DirectoryListBox можно также связать метку типа Label. В этой метке будет отображаться путь к текущему каталогу. Если путь не умещается в метке, он автоматически отображается в сокращенном виде (см. Рисунок 8.7) с помощью функции MinimizeName. Метка, отображающая каталог, указывается в свойстве DirLabel.

Список файлов содержится в компоненте FileListBox. Его свойства Drive, Directory и Mask определяют соответственно диск, каталог и маску файлов. Эти свойства можно устанавливать программно или связывая описанным ранее способом компонент FileListBox с компонентами DriveComboBox, DirectoryListBox и FilterComboBox. Свойство FileType позволяет включать в список не все файлы, а только те, которые имеют соответствующие атрибуты. Свойство FileType представляет собой множество, указывающее типы включаемых файлов. Элементы этого множества могут иметь значения: ftReadOnly — только для чтения, ftHidden — невидимые, ftSystem — системные, ftVoluimeID — обозначения дисков, ftDirectory — каталоги, ftArchive — архивные, ftNormal — не имеющие особых атрибутов.

Свойство ShowGlyphs разрешает или исключает показ пиктограмм файлов (в примере Рисунок 8.7 это свойство = true).

Свойство MultiSelect разрешает выбор нескольких файлов.

Основное свойство, в котором можно прочитать имя выбранного пользователем файла — FileName.

Со списком файлов может быть связано окно редактирования Edit, в котором отображается выбранный файл (см. окно над списком файлов на Рисунок 8.7). На этот список указывает устанавливаемое во время проектирования свойство FileEdit.

Теперь рассмотрим компонент DirectoryOutline, содержащий дерево каталогов. В этом компоненте значение диска устанавливается свойством Drive. Текущий каталог, выбранный пользователем, можно прочитать в свойстве Directory. Свойство TextCase определяет стиль отображения имен каталогов: tcLowerCase — преобразование к нижнему регистру, tcUpperCase — к верхнему, tcAsIs — без преобразования (этот режим использован в примере Рисунок 8.7). Остальные свойства идентичны компоненту OutLine, на основе которого построен данный пример. Вы можете найти исходный текст этого примера в каталоге ...\source\samples.

Общая характеристика компонентов-диалогов


В приложениях часто приходится выполнять стандартные действия: открывать и сохранять файлы, задавать атрибуты шрифтов, выбирать цвета палитры, производить контекстный поиск и замену и т.п.

Разработчики Delphi позаботились о том, чтобы включить в библиотеку простые для использования компоненты, реализующие соответствующие диалоговые окна. Они размещены на странице Dialogs. В таблице 8.1 приведен перечень этих диалогов.

Таблица 8.1. Системные диалоги и их фрагменты
Пикто-
грамма
КомпонентСтраницаОписание
OpenDialog
«Открыть файл»
DialogsПредназначен для создания окна диалога «Открыть файл».
SaveDialog
«Сохранить файл»
DialogsПредназначен для создания окна диалога «Сохранить файл как».
OpenPictureDialog
«Открыть рисунок»
DialogsПредназначен для создания окна диалога «Открыть рисунок», открывающего графический файл. Начиная с Delphi 3.
SavePictureDialog
«Сохранить рисунок»
DialogsПредназначен для создания окна диалога «Сохранить рисунок» — сохранение изображения в графическом файле. Начиная с Delphi 3.
FontDialog
«Шрифты»
DialogsПредназначен для создания окна диалога «Шрифты» — выбор атрибутов шрифта.
ColorDialog
«Цвет»
DialogsПредназначен для создания окна диалога «Цвет» — выбор цвета.
PrintDialog
«Печать»
DialogsПредназначен для создания окна диалога «Печать».
PrinterSetupDialog
«Установка принтера»
DialogsПредназначен для создания окна диалога «Установка принтера».
FindDialog
«Найти»
DialogsПредназначен для создания окна диалога «Найти» — контекстный поиск в тексте.
ReplaceDialog
«Заменить»
DialogsПредназначен для создания окна диалога «Заменить» — контекстная замена фрагментов текста.
FileListBox
(список файлов)
Win3.1Отображает список всех файлов каталога.
DirectoryListBox
(структура каталогов)
Win3.1Отображает структуру каталогов диска.
DriveComboBox
(список дисков)
Win3.1Выпадающий список доступных дисков.
FilterComboBox
(список фильтров)
Win3.1Выпадающий список фильтров для поиска файлов.
DirectoryOutline
(дерево каталогов)
SamplesПример компонента, используемого для отображения структуры каталогов выбранного диска.

Последние четыре компонента в таблице 8.1 являются не законченными диалогами, а их фрагментами, позволяющими строить свои собственные диалоговые окна.

Все диалоги являются невизуальными компонентами, так что место их размещения на форме не имеет значения. При обращении к этим компонентам вызываются стандартные диалоги, вид которых зависит от версии Windows и настройки системы. Так что при запуске одного и того же приложения на компьютерах с разными системами диалоги будут выглядеть по-разному. Например, при русифицированной версии Windows все их надписи будут русскими, а при англоязычной версии надписи будут на английском языке.

Основной метод, которым производится обращение к любому диалогу, — Execute. Эта функция открывает диалоговое окно и, если пользователь произвел в нем какой-то выбор, то функция возвращает true. При этом в свойствах компонента-диалога запоминается выбор пользователя, который можно прочитать и использовать в дальнейших операциях. Если же пользователь в диалоге нажал кнопку Отмена или клавишу Esc, то функция Execute возвращает false. Поэтому стандартное обращение к диалогу имеет вид: if <имя компонента-диалога>.Execute then <операторы, использующие выбор пользователя>;



Окно редактора фильтров


После выхода из окна редактирования фильтров заданные вами шаблоны появятся в свойстве Filter в виде строки вида: текстовые (*.txt, *.doc)|*.txt; *.doc|все файлы|*.*

В этой строке тексты и шаблоны разделяются вертикальными линиями. В аналогичном виде, если требуется, можно задавать свойство Filter программно во время выполнения приложения.

Свойство FilterIndex определяет номер фильтра, который будет по умолчанию показан пользователю в момент открытия диалога. Например, значение FilterIndex = 1 задает по умолчанию первый фильтр.

Свойство InitialDir определяет начальный каталог, который будет открыт в момент начала работы пользователя с диалогом. Если значение этого свойства не задано, то открывается текущий каталог или тот, который был открыт при последнем обращении пользователя к соответствующему диалогу в процессе выполнения данного приложения.

Свойство DefaultExt определяет значение расширения файла по умолчанию. Если значение этого свойства не задано, пользователь должен указать в диалоге полное имя файла с расширением. Если же задать значение DefaultExt, то пользователь может писать в диалоге имя без расширения. В этом случае будет принято заданное расширение.

Свойство Title позволяет вам задать заголовок диалогового окна. Если это свойство не задано, окно открывается с заголовком, определенным в системе (например, «Открытие файла» в окне на Рисунок 8.1). Но вы можете задать и свой заголовок, подсказывающий пользователю ожидаемые действия. Например, «Укажите имя открываемого файла».

Свойство Options определяет условия выбора файла. Множество опций, которые вы можете установить программно или во время проектирования, включает:

ofAllowMultiSelectПозволяет пользователю выбирать несколько файлов ofCreatePromptВ случае, если пользователь написал имя несуществующего файла, появляется замечание и запрос, надо ли создать файл с заданным именем ofEnableIncludeNotifyРазрешает посылать в диалог сообщения ofEnableSizingРазрешает пользователю изменять размер диалогового окна ofExtensionDifferentЭтот флаг, который можно прочитать после выполнения диалога, показывает, что расширение файла, выбранного пользователем, отличается от DefaultExt ofFileMustExistВ случае, если пользователь написал имя несуществующего файла, появляется сообщение об ошибке ofHideReadOnlyУдаляет из диалога индикатор Открыть только для чтения ofNoChangeDirПосле щелчка пользователя на кнопке OK восстанавливает текущий каталог, независимо от того, какой каталог был открыт при поиске файла ofNoDereferenceLinksЗапрещает переназначать клавиши быстрого доступа в диалоговом окне ofNoLongNamesОтображаются только не более 8 символов имени и трех символов расширения ofNoNetworkButtonУбирает из диалогового окна кнопку поиска в сети. Действует только если флаг ofOldStyleDialog включен ofNoReadOnlyReturnЕсли пользователь выбрал файл только для чтения, то генерируется сообщение об ошибке ofNoTestFileCreateЗапрещает выбор в сети защищенных файлов и не доступных дисков при сохранении файла ofNoValidateНе позволяет писать в именах файлов неразрешенные символы, но не мешает выбирать файлы с неразрешенными символами ofOldStyleDialogСоздает диалог выбора файла в старом стиле (см. Рисунок 8.4) ofOverwritePromptВ случае, если при сохранении файла пользователь написал имя существующего файла, появляется замечание, что файл с таким именем существует, и запрашивается желание пользователя переписать существующий файл ofPathMustExistГенерирует сообщение об ошибке, если пользователь указал в имени файла несуществующий каталог ofReadOnlyПо умолчанию устанавливает индикатор Открыть только для чтения при открытии диалога ofShareAwareИгнорирует ошибки нарушения условий коллективного доступа и разрешает, несмотря на них, производить выбор файла ofShowHelpОтображает в диалоговом окне кнопку Справка

По умолчанию все перечисленные опции, кроме ofHideReadOnly, выключены. Но, как видно из их описания, многие из них полезно включить перед вызовом диалогов.

Если вы разрешаете с помощью опции ofAllowMultiSelect множественный выбор файлов, то список выбранных файлов можно прочитать в свойстве Files типа TStrings.

В приведенной таблице даны опции, используемые в 32-разрядных версиях Delphi. В Delphi 1 диалоговое окно имеет вид, представленный на Рисунок 8.4. Аналогичный вид имеет диалог и в 32-разрядных версиях Delphi при включении опции ofOldStyleDialog. В примере Рисунок 8.4 диалог открыт с заданным значением свойства Title и заданный текст отображается в заголовке окна. Кроме того, в этом примере выключена опция ofHideReadOnly (в Delphi 1 она выключена по умолчанию), что привело к появлению индикатора «Только чтение».