Тема 7. Системные диалоги
1.
Общая характеристика компонентов – диалогов
2.
Диалоги открытия и сохранения файлов - компоненты OpenDialog и SaveDialog
3.
Диалог выбора шрифта - компонент FontDialog
4.
Диалоги поиска и замены текста -компоненты FindDialog и ReplaceDialog
5.
Диалоги выбора цвета -компоненты ColorDialog
6.
Диалоги печати и установки принтера -компоненты PrintDialog и PrinterSetupDialog
1. Общая характеристика компонентов – диалогов
В приложениях часто приходится выполнять
стандартные действия: открывать и сохранять файлы, задавать атрибуты шрифтов,
выбирать цвета палитры, производить контекстный поиск и замену и т.п.
Разработчики C++Builder
позаботились о том, чтобы включить в библиотеку простые для использования
компоненты, реализующие соответствующие диалоговые окна. Они размещены на
странице Dialogs. В C++Builder
имеются компоненты, которые можно рассматривать как фрагменты диалоговых окон.
Из них вы можете создавать собственные диалоги.
В табл. 9 приведен перечень компонентов, реализующих
стандартные диалоги, и компонентов, на основе которых можно создавать
собственные специализированные диалоговые окна.
Таблица 1.. Системные диалоги и их фрагменты
Компонент |
Страница |
Описание |
OpenDialog |
Dialogs |
Предназначен
для создания окна диалога «Открыть файл». |
SaveDialog |
Dialogs |
Предназначен
для создания окна диалога «Сохранить файл». |
OpenPictureDialog |
Dialogs |
Предназначен
для создания окна диалога «Открыть рисунок», открывающего графический файл. |
SavePictureDialog |
Dialogs |
Предназначен для создания окна диалога
«Сохранить рисунок» - сохранение изображения в графическом файле. |
FontDialog |
Dialogs |
Предназначен для создания окна диалога «Шрифты» - выбор атрибутов шрифта. |
ColorDialog |
Dialogs |
Предназначен для создания окна диалога
«Цвет» - выбор цвета. |
ColorBox |
Additional |
Выпадающий список для выбора пользователем цвета. |
PrintDialog |
|
Предназначен для создания окна диалога
«Печать» |
PrinterSetupDialog |
|
Предназначен для создания окна диалога
«Установка принтера» |
FindDialog |
|
Предназначен для создания окна диалога
«Найти» |
ReplaceDialog |
|
Предназначен для создания окна диалога
«Заменить» |
CustomizeDlg |
Additional |
Настраиваемый диалог, связанный со
стандартными действиями. |
Все диалоги являются невизуальными компонентами. При
обращении к этим компонентам вызываются стандартные диалоги, вид которых
зависит от версии Windows и настройки системы.
Основной метод, которым производится обращение к
любому диалогу - Execute. Эта функция открывает
диалоговое окно и, если пользователь произвел в нем какой-то выбор, то функция
возвращает true. При этом в свойствах компонента - диалога
запоминается выбор пользователя, который можно прочитать и использовать в
дальнейших операциях. Если же пользователь в диалоге нажал кнопку Отмена или
клавишу Esc, то функция Execute возвращает false. Поэтому стандартное обращение к диалогу имеет вид:
if (<имя
компонента - диалога> -> Execute ()) <оператор,
использующий выбор пользователя>.
2. Диалоги открытия и сохранения файлов - компоненты OpenDialog, SaveDialog
Компоненты OpenDialog и SaveDialog используются чаще всего,
в большинстве приложений.
Все свойства этих компонентов одинаковы, только
их смысл несколько различен для открытия и сохранения файлов.
Основное свойство этих компонентов - FileName, в котором возвращается
в виде строки имя выбранного
пользователем файла. Значение этого свойства можно задать и перед обращением к
диалогу. Тогда оно появится в диалоге как значение по умолчанию в окне Имя файла.
Типы искомых файлов, появляющиеся в диалоге Тип файла, задаются свойством Filter. В процессе
проектирования это свойство проще всего задать с помощью редактора фильтров,
который вызывается нажатием кнопки с многоточием около имени этого свойства в
Инспекторе Объектов. При этом открывается окно редактора. В его левой панели Filter Name записывается тот текст, который увидит пользователь в выпадающем
списке Тип файла диалога. А в правой
панели Filter записываются разделенные точками с запятой
шаблоны фильтра. Например, текстовых файлов с расширениями .txt и
.doc и любых файлов с шаблоном "*.*".
После выхода из окна редактирования фильтров заданные шаблоны
появятся в свойстве Filter в виде строки вида:
текстовые (*.txt,
*.doc) | *.txt; *.doc|Bce файлы|*.*
В этой строке тексты и шаблоны разделяются
вертикальными линиями. В аналогичном виде, если требуется, можно задавать
свойство Filter программно во время
выполнения приложения.
Свойство FilterIndex определяет номер фильтра, который будет по умолчанию показан
пользователю в момент открытия диалога. Например, значение FilterIndex=1 задает по умолчанию первый фильтр.
Свойство InitialDir определяет начальную папку, которая будет открыта в момент начала
работы пользователя с диалогом. Если значение этого свойства не задано, то
открывается текущая папка или та, которая была открыта при последнем обращении
пользователя к соответствующему диалогу в процессе выполнения данного
приложения.
Свойство DefaultExt определяет значение расширения файла по умолчанию. Если значение
этого свойства не задано, пользователь должен указать в диалоге полное имя
файла с расширением. Если же задать значение DefaultExt, то пользователь может писать в диалоге имя без
расширения. В этом случае будет принято заданное расширение.
Свойство Title позволяет задать заголовок диалогового окна. Если это свойство не
задано, окно открывается с заголовком, определенным в системе.
Свойство Options определяет условия выбора
файла. Множество опций, которые вы можете установить программно или во время
проектирования, включает:
ofAllowMultiSelect |
Позволяет пользователю
выбирать несколько файлов. |
|
ofCreatePrompt |
В случае, если пользователь
написал имя несуществующего файла, появляется замечание и запрос, надо ли
создать файл с заданным именем. |
|
ofEnablelncludeNotify |
Разрешает посылать в диалог
сообщения. |
|
ofEnableSizing |
Разрешает пользователю
изменять размер диалогового окна. |
|
ofExtensionDifferent |
Этот флаг, который можно
прочитать после выполнения диалога, показывает, что расширение файла,
выбранного пользователем, отличается от DefaultExt. |
|
ofFileMustExist |
В случае, если пользователь
написал имя несуществующего файла, появляется сообщение об ошибке. |
|
offlideReadOnly |
Удаляет из диалога
индикатор Открыть только для чтения. На рис. 3.51 эта опция выключена. |
|
ofNoChangeDir |
После щелчка пользователя
на кнопке ОК восстанавливает текущий каталог, независимо от того, какой
каталог был открыть при поиске файла. |
|
ofNoDereferenceLinks |
Запрещает переназначать
клавиши быстрого доступа в диалоговом окне. |
|
ofNoLongNames |
Отображаются только не
более 8 символов имени и трех символов расширения. |
|
ofNoNetworkButton |
Убирает из диалогового окна
кнопку поиска в сети. Действует только если флаг ofOldStyleDialog включен. |
|
ofNoReadOnlyReturn |
Если пользователь выбрал
файл только для чтения, то генерируется сообщение об ошибке. |
|
ofNoTestFileCreate |
Запрещает выбор в сети
защищенных файлов и не доступных дисков при сохранении файла. |
|
ofNoValidate |
Не позволяет писать в
именах файлов неразрешенные символы, но не мешает выбирать файлы с
неразрешенными символами. |
|
ofOldStyleDialog |
Создает диалог выбора файла
в старом стиле. |
|
ofOverwritePrompt |
В случае, если при
сохранении файла пользователь написал имя существующего файла, появляется
замечание, что файл с таким именем существует. |
|
ofPathMustExist |
Генерирует сообщение об
ошибке, если пользователь указал в имени файла несуществующий каталог. |
|
ofReadOnly |
По умолчанию включает
индикатор Открыть только для
чтения при открытии диалога. |
|
ofShareAware |
Игнорирует ошибки нарушения
условий коллективного доступа и разрешает, несмотря на них, производить выбор
файла. |
|
ofShowHelp |
Отображает в диалоговом
окне кнопку Справка. |
|
По умолчанию все перечисленные опции в свойствах Options, кроме ofHldeReadOnly, выключены. Но, как видно
из их описания, многие из них полезно включить перед вызовом диалогов.
Если вы разрешаете с помощью опции ofAllowMultiSelect множественный выбор файлов, то список выбранных
файлов можно прочитать в свойстве Files типа TStrings.
В компонентах диалогов открытия и сохранения
файлов предусмотрена возможность обработки ряда событий. Такая обработка может
потребоваться, если рассмотренных опций, несмотря на их количество, не хватает,
чтобы установить все диктуемые конкретным приложением ограничения на выбор
файлов.
Событие OnCanClose возникает при нормальном закрытии пользователем
диалогового окна после выбора файла. При отказе пользователя от диалога -
нажатии кнопки Отмена, клавиши Esc и т.д. событие OnCanClose не наступает. В
обработке события OnCanClose можете произвести
дополнительные проверки выбранного пользователем файла и, если по условиям задачи
этот выбор недопустим, можете известить об этом пользователя и задать значение false передаваемому в
обработчик параметру CanClose. Это не позволит пользователю закрыть диалоговое окно.
Можно также написать обработчики событий OnFolderChange - изменение папки, OnSelectionChange - изменение имени файла, OnTypeChange - изменение типа файла.
В этих обработчиках можете предусмотреть какие-то сообщения пользователю.
Теперь приведем пример использования диалогов OpenDialog и SaveDialog. Пусть приложение включает
окно редактирования RichEdit1, в которое по команде
меню MainMenu Открыть хотите загружать текстовый файл и после каких-то изменений,
сделанных пользователем, - сохранять текст по команде Сохранить в том же файле, а по команде Сохранить как - в файле с другим именем.
Введите на форму компоненты - диалоги OpenDialog и SaveDialog. Поскольку после чтения
файла надо запомнить его имя, определим для него переменную, например, MyFName и объявим ее в модуле формы как
глобальную переменную:
AnsiString MyFName ="";
Тогда обработка команды Открыть может сводиться к следующему
оператору:
if (OpenDialog1->Execute() )
{
MyFName = OpenDialog1->FileName;
RichEdit1->Lines->LoadFromFile(OpenDialog1->FileName);
}
Этот оператор вызывает диалог, проверяет, выбрал
ли пользователь файл (если выбрал, то функция Execute возвращает true),
после чего имя выбранного файла (OpenDialog1->FileName) сохраняется в переменной MyFName и файл загружается в
текст RichEdit1 методом LoadFromFile.
Обработка команды Сохранить как выполняется операторами:
SaveDialog1->FileName = MyFName;
if (SaveDialog1->Execute())
{
MyFName = SaveDialog1->FileName;
RichEdit1->Lines->SaveToFile(SaveDialog1->FileName);
}
Первый из этих операторов присваивает свойству FileName компонента SaveDialog1 запомненное имя файла. Это имя по умолчанию будет предложено
пользователю при открытии диалога Сохранить
как. Следующий оператор открывает диалог и, если пользователь выбрал в нем
файл, запоминает новое имя файла и сохраняет в файле с этим именем текст
компонента RichEdit1.
Обработка команды Сохранить выполняется операторами
if(MyFName!=
"")
RichEdit1->Lines->SaveToFile(MyFName)
;
else
if (SaveDialog1->Execute())
{
MyFName = SaveDialog1->FileName;
RichEdit1->Lines->SaveToFile(SaveDialog1->FileName);
}
Если имя файла MyFName не равно пустой строке,
т.е. известно, то нет необходимости обращаться к какому-то диалогу. Текст
сохраняется методом SaveToFile. Если же имя файла
неизвестно, то текст сохраняется с помощью диалога SaveDialog1 так же, как было
рассмотрено выше.
В библиотеке C++Builder
имеются также специализированные диалоги открытия и закрытия графических
файлов: OpenPictureDialog и SavePictureDialog.. От окон, открываемых компонентами OpenDialog и SaveDialog, они отличаются удобной возможностью просматривать изображения в
процессе выбора файла.
Свойства компонентов OpenPictureDialog и SavePictureDialog такие же, как у компонентов OpenDialog и SaveDialog. Единственное отличие - заданное значение по умолчанию свойства Filter в OpenPictureDialog и SavePictureDialog. В этих компонентах
заданы следующие фильтры:
All
(*.jpg;*.jpeg;*.bmp;*.ico;*.emf) |
*.jpg;*,jpeg;*.bmp;*.ico;*.emf |
JPEG Image File (*.jpg) |
*-iP9 |
JPEG Imoge File (*.|ред) |
*.ipeg |
Bitmaps (*.bmp) |
*.bmp |
Icons (*.ico) |
*.ico |
Enhanced Metafiles (*.em() |
*.emf |
Metafiles f.wmf) |
*.wmf |
В этих фильтрах перечислены все типы графических файлов, с
которыми может работать диалог. Так что вам остается удалить, если хотите,
фильтры тех файлов, с которыми вы не хотите работать, добавить, может быть,
фильтр «Все файлы (*.*)» и перевести на русский язык названия типов.
3. Диалог
выбора шрифта - компонент FontDialog
Компонент FontDialog вызывает диалоговое окно
выбора атрибутов шрифта. В нем пользователь может выбрать имя шрифта, его стиль
(начертание), размер и другие атрибуты.
Основное свойство компонента - Font типа TFont, в котором можете задать при желании начальные установки
атрибутов шрифта и в котором вы можете прочесть значения атрибутов, выбранные
пользователем в процессе диалога.
Свойства MaxFontSize и MinFontSize устанавливают ограничения на максимальный и
минимальный размеры шрифта. Если значения этих свойств равны 0 (по умолчанию),
то никакие ограничения на размер не накладываются. Если же значения свойств
заданы (обычно это целесообразно делать исходя из размеров компонента
приложения, для которого выбирается шрифт), то в списке Размер диалогового окна
появляются только размеры, укладывающиеся в заданный диапазон. При попытке
пользователя задать недопустимый размер ему будет выдано предупреждение вида
«Размер должен лежать в интервале ...» и выбор пользователя отменится. Свойства
MaxFontSize и MinFontSize действуют только при включенной опции fdLimitSize.
Свойство Device определяет, из какого
списка возможных шрифтов будет предложен выбор в диалоговом окне: fdScreen - из списка экрана (по умолчанию), fdPrinter - из списка принтера, fdBoth - из обоих.
Свойство Options содержит множество опций:
fdAnsiOnly |
Отображать только множество
шрифтов символов Windows, не отображать шрифтов со специальными символами. |
|
fdApplyButton |
Отображать в диалоге кнопку
Применить независимо от того, предусмотрен ли обработчик события OnApply. |
|
fdEffects |
Отображать в диалоге
индикаторы специальных эффектов (подчеркивание и др.) и список Цвет. |
|
fdFixedPitchOnly |
Отображать только шрифты с
постоянной шириной символов. |
|
fdForceFontExist |
Позволять пользователю
выбирать шрифты только из списка, запрещать ему вводить другие имена. |
|
fdLimitSize |
Разрешить использовать
свойства MaxFontSize и MinFont-Size, ограничивающие размеры шрифта. |
|
fdNoFaceSel |
Открывать диалоговое окно
без предварительно установленного имени шрифта. |
|
fdNoOEMFonts |
Удалять из списка шрифтов
шрифты OEM. |
|
fdScalableOnly |
Отображать только
масштабируемые шрифты, удалять из списка не масштабируемые (шрифты bitmap). |
|
fdNoSimulations |
Отображать только шрифты и
их начертания, напрямую поддерживаемые файлами, не отображая шрифты, в
которых жирный стиль и курсив синтезируется. |
|
fdNoSizeSel |
Открывать диалоговое окно
без предварительно установленного размера шрифта. |
|
fdNoStyleSel |
Открывать диалоговое окно
без предварительно установленного начертания шрифта. |
|
fdNoVectorFonts |
Удалять из списка векторные
шрифты (типа Roman или Script для Windows 1.0). |
|
fdShowHelp |
Отображать в диалоговом
окне кнопку Справно. |
|
fdTrueTypeOnly |
Предлагать в списке только
шрифты TrueType. |
|
fd Wysiwyg |
Предлагать в списке только
шрифты, доступные и для экрана, и для принтера, удаляя из него аппаратно
зависимые шрифты. |
По умолчанию все эти
опции, кроме fdEffects, отключены.
Если установить опцию fdApplyButton, то при нажатии пользователем
кнопки Применить возникает
событие OnApply, в обработчике которого вы
можете написать код, который применит выбранные пользователем атрибуты, не закрывая диалогового окна.
Приведем примеры применения компонента FontDialog. Пусть приложение
включает окно редактирования Memo1, шрифт в котором
пользователь может выбирать командой меню Шрифт.
Вы ввели в приложение компонент FontDialog1. Тогда обработчик
команды Шрифт может иметь вид:
if (FontDialog1->Execute())
Memo1->Font->Assign (FontDialog1->Font);
Приведенный оператор вызывает диалог выбора
атрибутов шрифта и, если пользователь произвел выбор, то значения всех
выбранных атрибутов, содержащиеся в свойстве FontDialog1->Font, присваиваются атрибутам
окна редактирования, содержащимся в свойстве Memo1->Font. Шрифт в окне
редактирования немедленно изменится.
Если вы установите в компоненте FontDialog1 опцию fdApplyButton, то можете написать
обработчик события OnApply:
Memo1->Font->Assign(FontDialog1->Font);
Тогда пользователь может наблюдать изменения в
окне Memo1, нажимая в диалоговом окне кнопку Применить и не прерывая диалога. Это
очень удобно, так как позволяет пользователю правильно подобрать атрибуты
шрифта.
Если в качестве окна редактирования в приложении
используется RichEdit, то можете предоставить пользователю выбирать атрибуты шрифта для
выделенного фрагмента текста или для вновь вводимого текста. Тогда выполнение
команды меню Шрифт может осуществляться операторами:
if
(FontDialog1->Execute() )
RichEdit1->SelAttributes->Assign(FontDialog1->Font);
Вы можете разрешить пользователю изменять шрифт не только
отдельных компонентов, но и всех компонентов и надписей на форме. Это
осуществляется оператором:
if
(FontDialog1->Execute() )
Font->Assign(FontDialog1->Font)
;
В этом операторе свойство Font без ссылки на компонент
подразумевает шрифт формы.
4. Диалоги
поиска и замены текста - компоненты FindDialog и ReplaceDialog
Компоненты FindDialog и ReplaceDialog, вызывающие диалоги поиска и замены фрагментов текста, очень
похожи и имеют одинаковые свойства, кроме одного, задающего заменяющий текст в
компоненте ReplaceDialog. Такое сходство не
удивительно, поскольку ReplaceDialog - производный класс от FindDialog.
Компоненты имеют
следующие основные свойства:
FindText |
Текст, заданный пользователем для поиска или замены.
Программно может быть установлен как начальное значение, предлагаемое
пользователю. |
ReplaceText |
Только в компоненте ReplaceDialog - текст, который
должен j заменять FindText. |
Position |
Позиция левого верхнего угла диалогового окна, заданная
типом TPoint - записью, содержащей поля X (экранная координата по
горизонтали) и Y (экранная координата по вертикали). |
Left |
Координата левого края диалогового окна, то же, что
Position.X. |
Top |
Координата верхнего края диалогового окна, то же, что
Position.Y. |
Options |
Множество опций. |
Последний параметр Options
- может содержать следующие свойства:
frDisableMatchCase |
Делает недоступным
индикатор С учетом регистра в диалоговом окне. |
frDisableUpDown |
Делает недоступными в
диалоговом окне кнопки Вверх и Вниз группы Напровление, определяющие
направление поиска. |
frDisableWholeWord |
Делает недоступным
индикатор Только слово целиком в диалоговом окне. |
frfiown |
Выбирает кнопку Вниз группы
Напровление при открытии диалогового окна. Если эта опция не установлена, то
выбирается кнопка Вверх. |
frFindNext |
Эта опция включается
автоматически, когда пользователь в диалоговом окне щелкает на кнопке Найти
далее, и выключается при закрытии диалога. |
frHideMatchCase |
Удаляет индикатор С учетом
регистра из диалогового окна. |
frHideWholeWord |
Удаляет индикатор Только
слава целикам из диалогового окна. |
frHideUpDown |
Удаляет кнопки Вверх и Вниз
из диалогового окна. |
frMatchCase |
Этот флаг включается и
выключается, если пользователь включает и выключает опцию С учетам регистра в
диалоговом окне. Можно установить эту опцию по умолчанию во время
проектирования, чтобы при открытии диалога она была включена. |
frReplace |
Применяется только для
ReplaceDialog. Этот флаг устанавливается системой, чтобы показать, что
текущее (и только текущее) найденное значение FindText должно быть заменено
значением ReplaceText. |
frReplaceAU |
Применяется только для
ReplaceDialog. Этот флаг устанавливается системой, чтобы показать, что все
найденные значения FindText должны быть заменены значениями ReplaceText. |
frShowHelp |
Задает отображение кнопки
Справка в диалоговом окне. |
frWholeWord |
Этот флаг включается и
выключается, если пользователь включает и выключает опцию Только слово
целиком в диалоговом окне. Можно установить эту опцию по умолчанию во время
проектирования, чтобы при открытии диалога она была включена. |
Сами по себе компоненты FindDialog и ReplaceDialog не осуществляют ни поиска, ни замены. Они только обеспечивают
интерфейс с пользователем. А поиск и замену надо осуществлять программно. Для
этого можно пользоваться событием OnFind, происходящим, когда пользователь нажал в диалоге кнопку Найти далее, и событием OnReplace, возникающим, если пользователь нажал кнопку Заменить или Заменить все. В событии OnReplace узнать, какую именно кнопку нажал пользователь,
можно по значениям флагов frReplace и frReplaceAll
Поиск заданного фрагмента в компоненте RichEdit легко проводить,
используя его метод FindText, объявленный следующим образом:
int _fastcall FindText(const System::Ansistring SearchStr, int StartPos, int Length,
TSearchTypes Options);
Этот метод ищет в тексте RichEdit фрагмент, заданный
параметром SearchStr. Поиск производится,
начиная с позиции StartPos (позиция первого символа текста считается нулевой), на протяжении
Length символов. Параметр Options является множеством,
которое может содержать элементы stWholeWord (поиск только целого
слова) и stMatchCase (поиск с учетом регистра). Метод
возвращает позицию найденного вхождения. Если заданный фрагмент не найден,
возвращается -1.
Ниже приведен код, осуществляющий поиск заданного фрагмента в
тексте компонента RichEdit1. Вызвать диалог поиска
можно операторами:
Начальное значение
текста поиска - текст, выделенный вRichEdit1
FindDialog1->FindText
= RichEdit1->SelText;
FindDialog1->Execute();
Они задают в качестве начального значения для поиска текст,
выделенный в окне RichEdit1, и затем вызывают диалог
поиска FindDialog1.
Обработчик события OnFind компонента FindDialog1 может иметь вид:
void _fastcall
TForm1::FindDialog1Find(TObject *Sender)
{
int FoundAt, StartPos, ToEnd;
TSearchTypes Option;
/* если было выделение
'то поиск идет, начиная с его
последнего символа, иначе - с позиции курсора */
StartPos = RichEdit1->SelStart;
if (RichEdit1->SelLength)
StartPos += RichEdit1->SelLength;
// ToEnd - длина текста, начиная с первой позиции поискаи до
конца
ToEnd = RichEdit1->Text.Length ()
- StartPos;
/* поиск целого слова
или нет в зависимости от установки пользователя
if (FindDialog1->Options.Contains(frWholeWord)
)
Option << stWholeWord;
else
Option >> stWholeWord;
/* поиск с учетом или
без учета регистра в зависимости от
установки пользователя */
if
(FindDialog1->Options.Contains(frMatchCase))
Option << stMatchCase;
else Option >> stMatchCase;
FoundAt = RichEdit1->FindText(FindDialog1->FindText, StartPos,
ToEnd, Option);
if (FoundAt != -1) // если найдено
{
RichEdit1->SetFocus() ;
RichEdit1->SelStart = FoundAt;
RichEdit1->SelLength =
FindDialog1->FindText.Length();
}
else
ShowMessage("Текст " + FindDialog1->FindText +" не найден");
}
Функция FindDialog1Find срабатывает, когда
пользователь нажал в диалоге кнопку Найти
далее. Комментарии в тексте этой функции поясняют этапы поиска. Сначала
производится установка области текста (переменные StartPos и ToEnd),
в которой проводится поиск. Затем устанавливаются атрибуты поиска - формируется
множество Option в зависимости от установленных пользователем
опций. Затем методом FindText проводится сам поиск. Если нового вхождения искомого текста не найдено
(метод FindText вернул -1), то пользователю выдается
сообщение об этом с помощью функции ShowMessage.
Приведенный пример относился к поиску в
компоненте RichEdit. Для организации поиска в тексте
компонента Memo удобно использовать метод Pos
класса AnsiString, который объявлен следующим образом:
int
_fastcall Pos (const AnsiStringk subStr) const;
Метод возвращает индекс первого символа первого
вхождения подстроки subStr в строку, к которой применяется этот
метод. Индексы начинаются с 1. Если subStr не содержится в строке,
то возвращается 0.
Для организации поиска потребуются еще две
функции класса AnsiString: SubString и LowerCase. Первая из них определена как:
AnsiString _fastcall SubString(int
index, int count) const;
Она возвращает подстроку, начинающуюся с символа
в позиции Index и содержащую count символов.
Функция LowerCase, определенная как
AnsiString
_fastcall LowerCase() const;
возвращает строку
символов S, переведенную в нижний регистр.
Теперь мы можем рассмотреть пример организации
поиска. Пусть в вашем приложении имеется компонент Memo1 и при выборе раздела
меню MFind вы хотите организовать поиск в тексте,
содержащемся в Memo1. Для упрощения задачи исключим опцию
поиска только целых слов и опцию поиска вверх от положения курсора.
Программа, реализующая
поиск, может иметь следующий вид:
void __ _fastcall
TForm1::MFindClick(TObjeet *Sender)
{
/* начальное значение
текста поиска - текст, выделенный в Memo1 */
FindDialog1->FindText = Memo1->SelText;
FindDialog1->Execute();
}
void fastcall
TForm1::FindDialog1Find(TObject "Sender)
{
int FoundAt, StartPos, ToEnd;
StartPos = Memo1->SelStart;
if (Memo1->SelLength)
StartPos += Memo1->SelLength;
/* ToEnd - длина текста, начиная
с первой позиции поиска и до конца */
ToEnd = Memo1->Text.Length() - StartPos;
/* поиск с учетом или без
учета регистра в зависимости от
установки пользователя */
if
(FindDialog1->Options.Contains(frMatchCase) )
FoundAt = StartPos
+Memo1->Text.Substring(StartPos+1, ToEnd) .Pos (FindDialog1->FindText) ;
else
FoundAt = StartPos +
Memo1->Text.Substring(StartPos+1, ToEnd) .LowerCase()
.Pos(FindDialog1->FindIext.LowerCase();
if (FoundAt != StartPos) // если найдено
{
Memo1->SetFocus();
Memo1->SelStart = FoundAt-1;
Memo1->SelLength = FindDialog1->FindText.Length();
}
else
ShowMessage("Текст '" + FindDialog1->FindText +
"' не найден");
}
Программа аналогична приведенной ранее для компонента RichEdit и отличается только несколькими операторами, осуществляющими
непосредственно поиск.
При реализации команды Заменить приведенные выше процедуры можно оставить теми же самыми,
заменив в них FindDialog1 на ReplaceDialog1. Дополнительно можно
написать процедуру обработки события OnReplace компонента ReplaceDialog1. Кроме того желательно
обеспечить, чтобы при нажатии пользователем в диалоге клавиши Заменить все программа просматривала бы
весь текст и проводила все замены без дополнительных вопросов пользователю. Для
этого можно в конце обработчика события OnFind вставить оператор,
который в случае, если пользователь нажал в диалоге клавишу Заменить все, вызывал бы обработчик
события OnReplace. В итоге текст,
обеспечивающий замену в компоненте RichEdit, может иметь вид:
void _fastcall TForm1::ReplaceDialog1Find(TObject *Sender)
{
…
// Если нажата кнопка
"Заменить все", то уход на замену
if(ReplaceDialog1->Options.Contains(frReplaceAll))
ReplaceDialog1Replace(Sender);
}
void _fastcall
TForm1::ReplaceDialog1Replace(TObject *Sender)
{
if (RichEdit1->SelText
!= "") // Если есть выделенный
текст Замена выделенного текста
RichEdit1->SelText = ReplaceDialog1->ReplaceText;
else
if (ReplaceDialog1->Options.Contains(frReplace))
{
ShowMessage("Текст " + ReplaceDialog1->FindText
+' не найден");
return;
}
// Если нажата кнопка "Заменить все", то уход на поиск
if (ReplaceDialog1->Options.Contains(frReplaceAll))
ReplaceDialog1Find(Sender);
}
В функции ReplaceDialog1Find в конце поиска
очередного вхождения искомого фрагмента в текст проверяется нажатие
пользователем кнопки Заменить все.
Если она нажата, то происходит обращение к функции ReplaceDialog1Replace, в которой
осуществляется замена текста, после чего сразу автоматически опять вызывается
функция ReplaceDialog1Find. Таким образом без остановок просматриваются и заменяются все
вхождения искомого фрагмента в текст. Если же кнопка Заменить все не нажата, то программа останавливается и ждет, пока
пользователь нажмет в диалоге кнопку Найти
далее или Заменить. Если нажимается кнопка Найти далее, то производится следующий вызов ReplaceDialog1Find. А при нажатии кнопки Заменить вызывается функция ReplaceDialog1Replace, которая заменяет выделенный текст.
Приведенные коды рассчитаны на компонент RichEdit. Для компонента Memo в них просто надо
заменить RichEdit1 на Memo1.
5. Диалоги
выбора цвета - компоненты ColorDialog и ColorBox
Компонент ColorDialog вызывает диалоговое окно
выбора цвета. В нем пользователь может выбрать цвет из базовой палитры или,
нажав кнопку Определить цвет,
раскрыть дополнительную панель, позволяющую синтезировать цвет, отличный от
базовых.
Основное свойство компонента ColorDialog – Color - соответствует тому цвету, который выбрал в диалоге пользователь.
Если при вызове диалога желательно установить начальное приближение цвета, это
можно сделать, установив Color предварительно во время проектирования или программно.
Свойство CustomColors типа TStrings позволяет задать
заказные цвета дополнительной палитры или прочитать заказной цвет,
сформированный пользователем в диалоге. Каждый цвет определяется строкой вида
<Имя
цвета>=<шестнадцатеричное
представление цвета>
Имена цветов задаются от ColorA (первый цвет) до ColorP (шестнадцатый, последний). Например, строка
ColorA=808022
задает первый заказной
цвет.
Свойство Options
содержит множество следующих опций:
cdFullOpen |
Отображать сразу при
открытии диалогового окна панели определения заказных цветов. |
cdPreventFullOpen |
Запретить появление в
диалоговом окне кнопки Определить цвет, так что пользователь не сможет
определять новые цвета. |
cdShowHelp |
Добавить в диалоговое окно
кнопку Справке. |
cdSolidColor |
Указать Windows
использовать сплошной цвет, ближайший к выбранному (это обедняет палитру). |
cdAnyColor |
Разрешать пользователю
выбирать любые не сплошные цвета (такие цвета могут быть не ровными). |
По умолчанию все опции
выключены.
Приведем пример применения компонента ColorDialog. Если хотите, чтобы пользователь мог задать цвет какого-то
объекта, например, цвет фона компонента Memo1, то это можно
реализовать оператором
if(ColorDialog1->Execute())
Memo1->Color = ColorDialog1->Color;
Рассмотренный компонент ColorDialog вызывает стандартный
диалог Windows. Однако нередко его возможности избыточны, и
пользователю удобнее выбирать цвет с помощью выпадающего списка. Такую
возможность предоставляет компонент ColorBox (страница Additional).
Свойство Style является множеством, элементы которого определяют, какие именно
категории цвета представлены в списке. Элементы множества означают следующее:
ebStandardColors |
16 стандартных цветов типа
clRed, clBlack и т.п. ; |
cbExtendedColors |
Набор дополнительных цветов
clMoneyGreen, clSkyBlue, clCream, clMedGray. |
cbSystemColors |
Системные цвета,
установленные в Windows. |
cblncludeNone |
Список включает в себя
строку «сЩопе». Какой именно цвет будет отображаться в квадратике этой
строки, определяется свойством NoneColorColor компонента Color-Box, а
истинный цвет определяется компонентом, воспринимающим этот цвет. Эта опция
влияет только при включенной опции cbSystemColors. |
blncludeDefault |
Список включает в себя
строку «clDefault» - цвет по умолчанию. Какой именно цвет будет отображаться
в квадратике этой строки, определяется свойством DefaultColorColor компонента
ColorBox, а истинный цвет определяется компонентом, воспринимающим этот цвет.
Эта опция влияет только при включенной опции cbSystemColors. |
aCustomColor |
Первой строкой в списке
появляется * Custom...». При выборе пользователем этой строки открывается
диалог, показанный на рис. 3.57, в котором пользователь может определить
заказной (нестандартный) цвет. |
aPrettyNames |
Строки в списке обозначают
цвета, а не их имена: например, «Black», а не «clBlack». |
Как видно из приведенной таблицы, в список, помимо различных
цветов, могут включаться строки «clDefault» - цвет компонента по умолчанию, и «clNone» - цвет, зависящий от версии Windows.
Если присвоить цвет clDefault какому-то компоненту, то
компонент будет рисоваться цветом, который заложен в него по умолчанию.
Аналогично, присваивание clNone тоже приведет к тому, что
истинный цвет будет определяться самим компонентом.
Свойство DefaultColorColor определяет, квадратиком
какого цвета будет помечена в списке строка «clDefault».
Свойство NoneColorColor определяет, квадратиком
какого цвета будет помечена в списке строка «clNone». При этом, как сказано
выше, в действительности присваиваемые цвета будут определяться теми
компонентами, в которые они передаются.
Узнать цвет, выбранный пользователем в списке, позволяет
свойство Selected. Для этого можно
воспользоваться событием компонента OnSelect, наступающим в момент
выбора пользователем цвета. Например, оператор
Memo1->Color = ColorBoxl->Selected;
помещенный
в обработчик этого события, задаст фону окна Memo1 цвет, выбранный
пользователем.
Свойство только времени выполнения Colors является индексированным массивом цветов в списке (индексы
начинаются с 0). Свойство ColorNames - аналогичный массив
строк с именами цветов.
Большинство остальных Свойств, методов, событий компонента ColorBox подобны компоненту ComboBox. В частности, список
всех строк содержится в свойстве Items типа TStrings. Индекс строки цвета, которая будет показана пользователю в момент
начала выполнения приложения, определяется свойством только времени выполнения Itemlndex, Если вам желательно в первый момент показать пользователю
определенный цвет, это можно сделать в обработчике события формы OnCreate, определив в нем Itemlndex с помощью метода IndexOf. Например, следующий оператор в первый момент показывает
пользователю строку «clDefault»:
ColorBoxl->ItemIndex =
ColorBoxl->Items->IndexOf("clDefault");
6 Диалоги
печати и установки принтера - компоненты PrintDialog и PrinterSetupDialog
Компонент PrintDialog вызывает диалоговое окно
печати. В нем пользователь может выбрать принтер и установить его свойства,
указать число копий и последовательность их печати, печатать в файл или
непосредственно на принтер, выбрать печатаемые страницы или печатать только
выделенный фрагмент.
Компонент PrintDialog только позволяет
пользователю задать атрибуты печати. А сама печать должна осуществляться
программно с помощью объекта Printer или иным путем.
Рассмотренные ранее диалоговые компоненты возвращали одно
свойство - имя файла, цвет, или один объект - Font, содержащий множество
свойств. В отличие от них компонент PrintDialog возвращает ряд свойств,
характеризующих выбранные пользователем установки. Это следующие свойства:
PrintRange Показывает выбранную
пользователем радиокнопку из группы Печатать: prAllPages - выбрана кнопка Все
страницы, prSelection - выбрана кнопка Страницы
с ... по .,., prPageNums - выбрана кнопка
Страницы.
FVisPage Показывает установленную пользователем
начальную страницу в окне Страницы с ... по .... |
|
Wage |
Показывает установленную
пользователем конечную страницу в окне Страницы с ... по .... |
PrintToFile |
Показывает, выбран ли
пользователем индикатор Печать в файл. |
Copies |
Показывает установленное
пользователем число копий. |
Collate |
Показывает, выбран лн пользователем
индикатор Разобрать. |
Перед вызовом диалога желательно определить, сколько страниц
в печатаемом тексте, и задать параметры MaxPage и MinPage - максимальный и минимальный номера страниц. В
противном случае пользователю в диалоговом окне не будет доступна кнопка
Страницы с ... по .... Кроме того, следует определить множество опций в
свойстве Options.
Компонент PrinterSetupDialog вызывает
диалоговое
окно установки принтера. Это единственный диалоговый компонент, не
имеющий никаких специфических свойств, которые надо было бы устанавливать.
Диалог выполняет операции по установке принтера, на котором будет производиться печать, и задании его свойств. Этот
диалог не возвращает никаких параметров.