TPrintDialog — Тип Delphi


TPrintDialog — Тип Delphi

Почему, при смене имени принтера в PrintDialog или PrinterSetupDialog, программа все равно печатает на том принтере, который установлен в системе по умолчанию?

Скорее всего после запуска PrintDialog или PrinterSetupDialog ты не получаешь настройки принтера и имя и не используешь их при печати.

Спасибо, но как имя и настройки получить от PrintDialog(PrinterSetupDialog) после вызова метода PrintDialog1.Execute?

Ты свойства посмотрел в справке?
Там все очень просто, имена говорят за себя и есть описание.

Посмотрел, но так и не понял, что надо написать после PrintDialog.Execute, чтобы отчет печатался на том принтере, который выбрал пользователь в PrintDialog-е (Принтер/Имя)?

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

Ситуация такая: у меня в системе установлено три принтера (1-струйка(по умолчанию), 2-термоплоттер и 3-матричный) и все на LPT1. Если мне из моего приложения надо напечатать цветные графики, я вставляю шнур из LPT1 в 1-струйку и все отлично печатается, а если не надо цветные, то вытаскиваю шнур из струйки и вставляю его в термоплотер, в PrintDialogе выбираю соответствующее имя принтера, нажимаю ОК, и ничего не печатается либо печатается абракадабра. Чтобы печаталось все правильно, недостаточно установить в системе термоплоттер исполбзуемый по умолчанию, надо закрыть мое приложение, поставить плоттер как используемый по умолчанию и снова запустить мое приложение. А это, как вы понимаете, очень плохо.
А печатаю я
Printer.BeginDoc
.
Printer.EndDoc

Так, как победить-то эту ситуацию, уважаемый Anatoly Podgoretsky?

А не знаю, у меня все работает, твою ситуации мне не воспроизвести, попробуй сменить индекс принтера

Ладно, тогда такой вопрос: какой обработчик события OnClick кнопки на моей форме написать, чтобы происходило все тоже самое, что и при нажатии на кнопке «Свойства» в PrintDialog-е?

выбрать принтер:
Printer.PrinterIndex:=новый индекс;

а получить строковые названия можно из массива (i=от 0 до Printer.Printers.Count)
Printer.Printers.Strings[i] — тут пользователь может выбрать в ComboBoxe(например) или ты распознаешь название принтера по контексту и установишь соотв. ему индекс

уточненьице: Printer.Printers.Count — число принтеров, следовательно лучше
i:=0; while i

(это избавит от вылета при отсутствии принтеров)

Спасибо Tano. Теперь еще надо сделать кнопку, при нажатии на которую будет появляться окно свойств выбранного в ComboBoxe принтера. Что надо написать в OnClick этой кнопки, чтобы это окно со свойствами принтера появилось?

Обнаружилась еще одна беда: если попытаться обойтись без PrintDialoga,то на операторе NewPage или EndDoc возникает ошибка. Если вызвать PrintDialog.Execute, то все работает.

Обнаружилась еще одна беда: если попытаться обойтись без PrintDialoga,то на операторе NewPage или EndDoc возникает ошибка. Если вызвать PrintDialog.Execute, то все работает. Как такое победить?

Так можно обойтись без PrintDialoga или надо обязательно его использовать?

>выбрать принтер:
>Printer.PrinterIndex:=новый индекс;

Согласен с Tano, но нужно учесть что при установке (деустановке) принтера — индексы у принтеров МЕНЯЮТСЯ.

Пример работающего кода (принтер в текстовом режиме):
<==============================================>
var
InText,OutText:TextFile;
.
Printer.PrinterIndex:=PrintDialog.Index;//индекс твоего принтера
<$i->
AssignFile(InText,»Out.tmp»);
AssignPrn(OutText);
Reset(InText);
If IOResult=0 then
begin
Rewrite(OutText);
While Not Eof(InText) do
begin
ReadLn(InText,Tmp);
WriteLn(OutText,Tmp);
end;
CloseFile(OutText);
end;
CloseFile(InText);

Не могу подсказать. Я и настраивал вручную и вызывал диалог печати — и так и так работает (например кнопка на форме «Напечатать два бланка» — кидает на принтер по умолчанию пару копий, а в меню — печать с запросом). Детальнее не разбирался Sorry.

TPrintDialog — Тип Delphi

Before printing from your application, it is wise to display a print dialog. This allows the user to select the desired printer and attributes, along with control over how the document is printed. Such as multiple copies and pages to be printed.

You first use the class by creating an object from it, and then setting the required dialog attributes from the following list:

Collate Whether to preset the Collate option
Copies How many copies to print
FromPage Selected page in page range
ToPage Selected page in page range
MinPage Earliest selectable page
MaxPage Latest selectable page
PrintRange Starting page selection type
Options Various multi-selectable options
PrintToFile If false, we print to paper

The PrintRange values are:

prAllPages All pages to print
prSelection Page selection to print
prPageNums Page number range to print

You choose one before the dialog starts — and check to see if the user has changed it when the dialog ends.

The Options values may be one of the following:

poPrintToFile Print to file
poPageNums Print by page range
poSelection Print by page selection
poWarning Warning if bad printer
poHelp Disply help
poDisablePrintToFile Print to file disallowed

Some of these options may also be set by the dialog user. Always check their values afterwards.

After setting these options, use the Execute method to display the dialog, checking the Boolean outcome after it runs to know whether to proceed with the printing. Notes Used in conjunction with the Printer object. Related commands

Printer Returns a reference to the global Printer object
TObject The base class type that is ancestor to all other classes
Example code : A relatively simple example
// Full Unit code.
// ————————————————————
// You must store this code in a unit called Unit1 with a form
// called Form1 that has an OnCreate event called FormCreate.

unit Unit1;

uses
Printers, SysUtils, Graphics,
Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;

var
Form1: TForm1;

implementation
<$R *.dfm>// Include form definitions

TPrintDialog, TPrinter — как печатать на принтер выбранный в диалоге?

собственно сабж.
я использовал и TPrinterSetupDialog и TPrintDialog, но печать всё время происходит на default’ный принтер.

как мне изменить принтер [COLOR=DimGray](но не ставить его по default’у для системы)[/COLOR] на тот, который выбрал пользователь в этих диалогах?

PS: ясно дело, что можно выбрать принтер по имени, но я имени выбранного принтера не знаю :(

6 ответов

Lists all printers installed in Windows.

The list of installed printers is found in the Printers property. The value of the PrinterIndex property is the currently selected printer. The list of fonts supported by the current printer is found in the Fonts property.

По идее принтер меняет система (через TPrintDialog), странно.

Изменить принтер:
TPrinter* printer = Printer();
int printerIndex = printer->Printers->IndexOf(PrinterName);
printer->PrinterIndex = printerIndex;
но опять же надо знать имя принтера

да, но что-то я вот не заметил что так происходит.
вызываю диалог, создаю объект TPrinter, по индексу выбранного принтера находится default’ный.

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

PS: nikipelovav, а ничего так у тебя получается справку копи-пастить :) спасибо конечно, но это я и сам в состоянии найти и прочитать.

Что вызывается первым Printer() или PrintDialog->Execute()?

Уважаемый, Тень Пса

Читать справку ещё никому не мешало.

Попробуй этот код! Может тебе поможет ;)

Специально, чтобы проверить, установил два принтера HP и Epson.
В диалоге PrintDialog выбираю принтер, и
как написано в справке! . о чюдо, сообщение ShowMessage отображает
выбранное имя принтера! Просто оболдеть!

Неужели в справке правда написана

спасибо всем ) проблему решил.

в общем ситуация такая была и есть, прога работает с 2мя типами шаблонов: RTF и TIFF(JPEG, BMP, GIF — в общем картинки).

с RTF всё хорошо, принтер выбрал, на него идёт печать посредством либы, всё окей! (в этом месте всё работает, как и написано в справке, которую я всё-таки прочитал. я это имел в виду nikipelovav, чего ты разкричался о чуде и тд я не понял ;) лана не в обиду)

но с графическими шаблонами всё было ужасно, во-первых надо получить корректную картинку чтобы вывести её на принтер. ну а во-вторых, нужно выводить на ВЫБРАННЫЙ принтер :)
тут всё было довольно убого и не правильно, я пытался рисовать на канву принтера.

что ж. принтер оказывался не тем, что выбрал пользователь (как раз подобный кусок кода №1, nikipelovav, я и использовал), да и печать собссна не происходила.

проблему решил, запихерив печать шаблонов в саму библиотеку.

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

Компоненты Delphi для работы с файлами

Читайте также:

  1. II. Основные направления социально-медицинской работы с семьями детей ограниченными возможностями
  2. III. Лекционный материал по теме: ПРАВИЛА РАБОТЫ НА ЛЕКЦИИ
  3. IX. Лекционный материал: ОРГАНИЗАЦИЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
  4. N В условиях интенсивной мышечной работы, при гипоксии (например, интенсивный бег на 200м в течении 30 с) распад углеводов временно протекает в анаэробных условиях
  5. VIII. Принципы работы вычислительной системы
  6. XIII. Файловая структура ОС. Операции с файлами
  7. Автоматизация группы работы приточных систем
  8. Алгоритм работы при соединении двух FTP-серверов, ни один из которых не расположен на локальном хосте пользователя.
  9. Алгоритм работы с группами общественности.
  10. Алюминиевые сплавы, их свойства и особенности работы
  11. Анализ ритмичности и сезонности работы предприятия
  12. Анализ стратегий работы с сопротивлением

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


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

Компонент Страница Описание
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 Пример компонента, используемого для отображения структуры каталогов выбранного диска.

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

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

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

if .Execute then ;

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

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

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

После выхода из окна редактирования фильтров заданные вами шаблоны появятся в свойстве Filter в виде строки вида:

текстовые (*.txt, *.doc)|*.txt; *.doc|все файлы|*.*

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

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

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

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

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

Свойство 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.

В компонентах диалогов открытия и сохранения файлов предусмотрена возможность обработки ряда событий. Такая обработка может потребоваться, если рассмотренных опций, несмотря на их количество, не хватает, чтобы установить все диктуемые конкретным приложением ограничения на выбор файлов. Событие 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.

Обработка команды Сохранить выполняется оператором

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

Обработка команды Сохранить как. выполняется операторами:

SaveDialog1.FileName := FName;if SaveDialog1.Execute then begin FName := SaveDialog1.FileName; Memo1.Lines.SaveToFile(FName); end;

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

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

Свойства компонентов 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

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

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

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

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

Если в качестве окна редактирования в вашем приложении вы используете RichEdit, то можете предоставить пользователю выбирать атрибуты шрифта для выделенного фрагмента текста или для вновь вводимого текста. Тогда выполнение команды меню Шрифт может осуществляться операторами:

if FontDialog1.Execute then RichEdit1.SelAttributes.Assign(FontDialog1.Font);

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

if FontDialog1.Execute then Font.Assign(FontDialog1.Font);

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

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

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

Имена цветов задаются от ColorA (первый цвет) до ColorP (шестнадцатый, последний). Например, строка

задает первый заказной цвет. При задании цвета 2 младших разряда описывают интенсивность красного цвета, следующие 2 — зеленого, старшие — синего.

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

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

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

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

if ColorDialog1.Execute then Memo1.Color := ColorDialog1.Color;

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


Компонент 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, вызывающем диалоговое окно установки принтера. Это единственный диалоговый компонент, не имеющий никаких специфических свойств, которые надо было бы устанавливать или читать. Диалог выполняет операции по установке принтера, на котором будет производиться печать, и задании его свойств. Этот диалог не возвращает никаких параметров.

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

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

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; Position := Point(Form1.Left, Form1.Top + Memo1.Top + Memo1.Height); <удаление из диалога кнопок «Вверх», «Вниз»,«Только слово целиком»> Options := Options + [frH >= 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 ввести операторы

Это позволяет пользователю во время диалога изменить положение курсора в окне 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 нельзя присваивать отрицательные значения.

| следующая лекция ==>
Пожарная профилактика при проектировании и строительстве зданий | Процесс планирования состоит из

Дата добавления: 2014-01-07 ; Просмотров: 1768 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

TPrintDialog Class

Unit Edit

Hierarchy Edit

(Please provide a description in your own words. It is illegal to use the wording from the Delphi Help.)

Technical Comments Edit

(Known issues / Documentation clarifications / Things to be aware of)

Examples Edit

(Please provide links to articles/source code that show how to use this item.)

See Also Edit

(Please provide links to items specifically related to this item.)

User Comments/Tips Edit

(Please leave your name with your comment.)

Вопрос в Delphi 7. Проблема с компонентом PrintDialog !

Проблема с компонентом PrintDialog !

Помогите !
Как сделать так , чтобы при нажатии строки меню (N17) выводились свойства печати и выбор принтера, после чего можно было отправить на печать? (На печать необходимо подать либо полностью содержимое «Form10» )
Вообщем необходимо чтобы печатался «Список» текста который дан либо в «Memo» либо в ещё каких-либо компонениах .
если честно, для меня это сложновато!

p.s. на форумах очень сложно понять, т.к. сам не ахти в Delphi 7

Подскажите как и напишите процедуру и всё остальное .

Параметр ориентации TPrintDialog и ориентации считывания — delphi

Есть ли возможность читать с TPrintDialog ориентацию страницы (горизонтальной/вертикальной), выбранной пользователем?

В классическом решении:

Я не могу найти ориентацию в TPrintDialog .

    2 1
  • 24 окт 2020 2020-10-24 23:56:52
  • Artik

1 ответ

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

Когда вы показываете TPrintDialog , пользователь имеет возможность устанавливать свойства для своего выбранного принтера, включая ориентацию страницы. Затем вы должны прочитать эту информацию из объекта TPrinter , который вы используете для выполнения печати. ​​

TPrintDialog, TPrinter — как печатать на принтер выбранный в диалоге?

собственно сабж.
я использовал и TPrinterSetupDialog и TPrintDialog, но печать всё время происходит на default’ный принтер.

как мне изменить принтер [COLOR=DimGray](но не ставить его по default’у для системы)[/COLOR] на тот, который выбрал пользователь в этих диалогах?


PS: ясно дело, что можно выбрать принтер по имени, но я имени выбранного принтера не знаю :(

6 ответов

Lists all printers installed in Windows.

The list of installed printers is found in the Printers property. The value of the PrinterIndex property is the currently selected printer. The list of fonts supported by the current printer is found in the Fonts property.

По идее принтер меняет система (через TPrintDialog), странно.

Изменить принтер:
TPrinter* printer = Printer();
int printerIndex = printer->Printers->IndexOf(PrinterName);
printer->PrinterIndex = printerIndex;
но опять же надо знать имя принтера

да, но что-то я вот не заметил что так происходит.
вызываю диалог, создаю объект TPrinter, по индексу выбранного принтера находится default’ный.

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

PS: nikipelovav, а ничего так у тебя получается справку копи-пастить :) спасибо конечно, но это я и сам в состоянии найти и прочитать.

Что вызывается первым Printer() или PrintDialog->Execute()?

Уважаемый, Тень Пса

Читать справку ещё никому не мешало.

Попробуй этот код! Может тебе поможет ;)

Специально, чтобы проверить, установил два принтера HP и Epson.
В диалоге PrintDialog выбираю принтер, и
как написано в справке! . о чюдо, сообщение ShowMessage отображает
выбранное имя принтера! Просто оболдеть!

Неужели в справке правда написана

спасибо всем ) проблему решил.

в общем ситуация такая была и есть, прога работает с 2мя типами шаблонов: RTF и TIFF(JPEG, BMP, GIF — в общем картинки).

с RTF всё хорошо, принтер выбрал, на него идёт печать посредством либы, всё окей! (в этом месте всё работает, как и написано в справке, которую я всё-таки прочитал. я это имел в виду nikipelovav, чего ты разкричался о чуде и тд я не понял ;) лана не в обиду)

но с графическими шаблонами всё было ужасно, во-первых надо получить корректную картинку чтобы вывести её на принтер. ну а во-вторых, нужно выводить на ВЫБРАННЫЙ принтер :)
тут всё было довольно убого и не правильно, я пытался рисовать на канву принтера.

что ж. принтер оказывался не тем, что выбрал пользователь (как раз подобный кусок кода №1, nikipelovav, я и использовал), да и печать собссна не происходила.

проблему решил, запихерив печать шаблонов в саму библиотеку.

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

Компоненты Delphi для работы с файлами

Читайте также:

  1. II. Основные направления социально-медицинской работы с семьями детей ограниченными возможностями
  2. III. Лекционный материал по теме: ПРАВИЛА РАБОТЫ НА ЛЕКЦИИ
  3. IX. Лекционный материал: ОРГАНИЗАЦИЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
  4. N В условиях интенсивной мышечной работы, при гипоксии (например, интенсивный бег на 200м в течении 30 с) распад углеводов временно протекает в анаэробных условиях
  5. VIII. Принципы работы вычислительной системы
  6. XIII. Файловая структура ОС. Операции с файлами
  7. Автоматизация группы работы приточных систем
  8. Алгоритм работы при соединении двух FTP-серверов, ни один из которых не расположен на локальном хосте пользователя.
  9. Алгоритм работы с группами общественности.
  10. Алюминиевые сплавы, их свойства и особенности работы
  11. Анализ ритмичности и сезонности работы предприятия
  12. Анализ стратегий работы с сопротивлением

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

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

Компонент Страница Описание
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 Пример компонента, используемого для отображения структуры каталогов выбранного диска.

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

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

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

if .Execute then ;

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

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

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

После выхода из окна редактирования фильтров заданные вами шаблоны появятся в свойстве Filter в виде строки вида:

текстовые (*.txt, *.doc)|*.txt; *.doc|все файлы|*.*

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

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

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

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

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

Свойство 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.

В компонентах диалогов открытия и сохранения файлов предусмотрена возможность обработки ряда событий. Такая обработка может потребоваться, если рассмотренных опций, несмотря на их количество, не хватает, чтобы установить все диктуемые конкретным приложением ограничения на выбор файлов. Событие 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.

Обработка команды Сохранить выполняется оператором

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

Обработка команды Сохранить как. выполняется операторами:

SaveDialog1.FileName := FName;if SaveDialog1.Execute then begin FName := SaveDialog1.FileName; Memo1.Lines.SaveToFile(FName); end;

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

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

Свойства компонентов 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

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

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

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


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

Если в качестве окна редактирования в вашем приложении вы используете RichEdit, то можете предоставить пользователю выбирать атрибуты шрифта для выделенного фрагмента текста или для вновь вводимого текста. Тогда выполнение команды меню Шрифт может осуществляться операторами:

if FontDialog1.Execute then RichEdit1.SelAttributes.Assign(FontDialog1.Font);

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

if FontDialog1.Execute then Font.Assign(FontDialog1.Font);

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

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

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

Имена цветов задаются от ColorA (первый цвет) до ColorP (шестнадцатый, последний). Например, строка

задает первый заказной цвет. При задании цвета 2 младших разряда описывают интенсивность красного цвета, следующие 2 — зеленого, старшие — синего.

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

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

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

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

if ColorDialog1.Execute then Memo1.Color := ColorDialog1.Color;

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

Компонент 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, вызывающем диалоговое окно установки принтера. Это единственный диалоговый компонент, не имеющий никаких специфических свойств, которые надо было бы устанавливать или читать. Диалог выполняет операции по установке принтера, на котором будет производиться печать, и задании его свойств. Этот диалог не возвращает никаких параметров.

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

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

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; Position := Point(Form1.Left, Form1.Top + Memo1.Top + Memo1.Height); <удаление из диалога кнопок «Вверх», «Вниз»,«Только слово целиком»> Options := Options + [frH >= 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 ввести операторы

Это позволяет пользователю во время диалога изменить положение курсора в окне 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 нельзя присваивать отрицательные значения.

| следующая лекция ==>
Пожарная профилактика при проектировании и строительстве зданий | Процесс планирования состоит из

Дата добавления: 2014-01-07 ; Просмотров: 1769 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

TPrintDialog — Тип Delphi

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

Диалоги работы с файлами

Все диалоги собраны на обзей закладке Dialogs палитры компонентов. Первым на ней является компонент OpenDialog, представляющий собой оболочку для функций Windows API, связанных с диалогом выбора файлов. Диалог, вызываемый при помощи компонента OpenDialog, используется для выбора (открытия) файла. Для операции сохранения следует использовать другой компонент — SaveDialog. Он показывает, в общем-то, тот же самый диалог, но в режиме сохранения.

Еще 2 компонента — OpenPictureDialog и SavePictureDialog являются частным случаем стандартных диалогов открыть-сохранить, но предназначенными для работы с графическими файлами. Визуально они отличаются от универсальных диалогов тем, что имеют область просмотра изображения. С точки зрения их использования в программе они ничем не отличаются от OpenDialog и SaveDialog.

Вообще, следует отметить, что базовым классом для всех диалогов выступает TCommonDialog, а для всех диалогов работы с файлами — класс TOpenDialog. Итак, рассмотрим общие свойства файловых диалогов на основе OpenDialog, для чего обратимся к таблице 14.1.


Таблица 14.1. Свойства файловых диалогов

Свойство Тип Описание
DefaultExt String Определяет расширение по умолчанию, которое будет добавляться к файлу, если пользователь не указал расширение явно
FileName String Определяет имя файла, включая его путь
Files TStrings Содержит список выбранных файлов, если таковых несколько (задается свойством Options путем включения флага ofAllowMultiSelect)
Filter String Определяет строку, содержащую фильтр типов файлов
FilterIndex Integer Определяет, какой из вариантов фильтра должен быть выбран по умолчанию
InitialDir String Определяет каталог, который будет отображен изначально
Options TOpenOptions Определяет вид особенности поведения диалога
OptionsEx TOpenOptionsEx Определяет дополнительные опции, актуальные для Windows Me, 2000 и более новых версий
Title String Определяет текст, который будет отображен в заголовке диалога

Наиболее востребованным свойством любого файлового диалога, разумеется, являются свойство FileName, поскольку именно оно определяет имя файла, выбранного пользователем. В то же время для настроек диалога важны и другие свойства, в частности, при помощи свойства Filter задают маску, по которой пользователь сможет фильтровать типы файлов. И хотя это свойство представляет собой строку, для его правки при посредстве инспектора объектов используется табличный редактор. Более того, для специализированных диалогов, предназначенных для работы с графическими файлами, это свойство заполняется автоматически (рис. 14.1).

Рис. 14.1. Редактор свойства Filter с данными по умолчанию для OpenPictureDialog

В столбце слева указывают название фильтра (т.е. то, что видит пользователь), а в столбце справа — собственно шаблон фильтра. Если же требуется задать фильтр программно, то строку разделяют при помощи символа вертикальной черты. В таком случае сначала указывают название, потом ставят черту, а затем — определяют шаблон. Для следующего варианта все повторяют, при этом сами варианты так же отделяются вертикальной чертой:

OpenDialog1.Filter:=’Все файлы|*.*|Текстовые файлы|*.txt’;

Здесь мы определили 2 варианта фильтра — для отображения всех файлов (шаблон *.*) и для отображения только текстовых файлов (шаблон *.txt). Если один шаблон включает в себя несколько разных расширений, то они перечисляются через точку с запятой:

OpenDialog1.Filter:=’Все файлы|*.*|Файлы Delphi|*.pas;*.dpr’;

Еще одно важное свойство файловых диалогов — это Options. Именно при помощи множества флагов этого свойства определяют особенности поведения диалога, а также устанавливают отображение дополнительных элементов его интерфейса. Значения всех актуальных флагов приведены в таблице 14.2.

Таблица 14.2. Значения флагов свойства Options компонента OpenDialog

Флаг Описание
ofReadOnly «Делает опцию «»только чтение»» включенной по умолчанию»
ofOverwritePrompt Указывает на необходимость вывода предупреждающего сообщения, если файл с указанным именем уже существует (для диалогов сохранения)
ofHideReadOnly «Удаляет из диалога переключатель «»только чтение»»»
ofNoChangeDir Возвращает исходный путь после закрытия диалога
ofShowHelp Отображает кнопку справки на диалоге
ofNoValidate Отключает проверку на недопустимые символы в имени файла
ofAllowMultiSelect Позволяет пользователю выбрать несколько файлов одновременно
ofExtensionDifferent Этот флаг включается автоматически, когда выбранный файл имеет расширение, отличное от указанного в свойстве DefaultExt
ofPathMustExist Выдает сообщение об ошибке, если указанного пользователем пути не существует
ofFileMustExist Выдает сообщение об ошибке, если указанного пользователем файла не существует (для диалогов открытия файла)
ofCreatePrompt Выдает сообщение с предупреждением о необходимости создания файла, если указанного пользователем файла не существует
ofShareAware Позволяет игнорировать ошибки доступа
ofNoReadOnlyReturn Выдает сообщение об ошибке, если пользователь выберет файл, доступный только для чтения
ofNoTestFileCreate Отключает проверку на права доступа к сетевым ресурсам
ofNoDereferenceLinks Отключает обработку ярлыков. Т.е. если этот флаг не установлен, то выбор ярлыка приведет к выбору файла, на который ярлык ссылается, в противном случае будет выбран сам файл ярлыка (lnk)
ofEnableSizing Позволяет пользователю изменять размеры диалогового окна (не действует в Windows 95 и Windows NT 4.0)
ofDontAddToRecent Не позволяет заносить выбранные файлы в список недавно открытых документов
ofForceShowHidden Позволяет пользователю увидеть скрытые файлы

По умолчанию включены только ofHideReadOnly и ofEnableSizing, т.е. скрыта редко используемая на практике опция открытия файлов в режиме «только чтение», и разрешено изменение размеров диалогового окна.

Что касается второго свойства — OptionsEx, то для него пока что доступна единственная настройка — ofExNoPlacesBar, позволяющая отключить боковую панель быстрого доступа к основным разделам компьютера, поддерживаемую в Windows Me, 2000, XP и 2003 Server.

Еще проще дела обстоят с методами. Кроме стандартных методов, доставшихся диалогам от класса TComponent, у него всего один собственный метод — Execute. Именно при помощи этого метода вызываются диалоги в коде программы. Метод Execute возвращает булевское значение — истину, если пользователь нажмет ОК, или ложь, если пользователь выберет отмену. Соответственно, типичный вызов диалога в программе выглядит следующим образом:

if OpenDialog1.Execute then begin . end;

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

procedure TForm1.OpenFileButtonClick(Sender: TObject); begin if not OpenDialog1.Execute then exit; Form1.Caption:=OpenDialog1.FileName; Memo1.Lines.LoadFromFile(OpenDialog1.FileName); end;

Такой подход позволяет избежать лишнего блока begin-end, поскольку если диалог не выполнен (т.е. пользователь передумал открывать файл), то можно сразу же выйти из подпрограммы, предназначенной для обработки загрузки файла.

Диалоги печати

Для взаимодействия со средствами Windows по подготовке к печати в VCL предусмотрено 3 компонента: PrintDialog, PrintSetupDialog и PageSetupDialog. Первый из них реализует доступ к стандартному диалогу печати, второй — к диалогу настройки печати, а третий — к диалогу параметров страницы.

Свойства, которыми обладают данные компоненты, в основном, предназначены для непосредственного обмена информацией между приложением и окном диалога, вернее, даже с его составными элементами. Так, для диалога печати (PrintDialog, рис. 14.2), это будут свойства, отвечающие за диапазон печати и число копий. В частности, за число копий отвечает свойство Copies, за тип диапазона, который может принимать одно из 3 значений — все (prAllPages), указанные страницы (prPageNums), или выделенный фрагмент (prSelection) — отвечает свойство PrintRange. При этом, если выбран диапазон по страницам, то его границы будут определяться свойствами FromPage и ToPage. Ограничить границы выбора этих значений пользователем во время его работы с диалогом можно при помощи свойств MaxPage и MinPage.

Рис. 14.2. Диалог печати

Как и у большинства других диалогов, диалог печати имеет свойство Options, при помощи которого можно настроить вид и поведение диалога. Приведем описание значений его флагов:

  • poDisablePrintToFile — Отключает (делает недоступной) опцию печати в файл, актуально только если включен флаг poPrintToFile;
  • poHelp — Отображает кнопку справки на окне диалога;
  • poPageNums — Делает доступной опцию печати диапазона страниц;
  • poPrintToFile — Отображает переключатель вывода в файл;
  • poSelection — Делает доступной опцию печати выделенного фрагмента;
  • poWarning — Производит проверку на доступность выбранного принтера, и выдает предупреждение, если устройство не доступно.

Важно осознавать, что сам по себе диалог печати ничего не делает. Фактически он лишь предоставляет пользовательский интерфейс для выбора диапазона печати и указания числа копий. Дальнейшую обработку полученной информации должно выполнять само приложение, для чего используется объект Printer (см. главу 9). В частности, объект «принтер» имеет свойство Copies, обозначающее количество копий, так что с этой точки зрения все просто, надо лишь не забыть включить модуль Printers в блок Uses, дальше останется лишь присвоить соответствующее свойство:

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

Еще один диалог, имеющий отношение к печати — это диалог настройки параметров страницы, PageSetupDialog, появившийся в Delphi 7. С его помощью пользователь может указать ориентацию страницы (портретную или ландшафтную), установить размер листа и источник подачи, а также задать поля. Иначе говоря, этот диалог предоставляет больше возможностей для выбора параметров страницы, чем PrinterSetupDialog. Впрочем, при помощи свойства Options можно отключить те или иные настройки, как-то выбор размера листа, его ориентации, полей, или устройства подачи:

  • psoDefaultMinMargins — Учитывает минимальные значения, заданные в свойствах для полей страницы;
  • psoDisableMargins — Отключает элементы интерфейса, относящиеся к установке полей;
  • psoDisableOrientation — Отключает элементы интерфейса, относящиеся к выбору ориентации страницы;
  • psoDisablePagePainting — Отключает вывод демонстрационного рисунка;
  • psoDisablePaper — Отключает элементы интерфейса, относящиеся к размеру и подаче бумаги;
  • psoDisablePrinter — Делает недоступной кнопку выбора принтера;
  • psoMargins — Устанавливает начальные значения полей в значения, заданные при помощи свойств диалога. В противном случае использует значения по умолчанию;
  • psoMinMargins — Устанавливает минимальные значения полей в значения, заданные при помощи свойств диалога. В противном случае использует значения по умолчанию;
  • psoShowHelp — Делает доступной кнопку вызова справки;
  • psoWarning — Выводит предупреждение, если в системе не выбран принтер по умолчанию.

Что касается тех параметров, которые не назначаются принтеру автоматически (в частности, поля), то как раз они и представлены свойствами компонента PageSetupDialog. Это свойства MarginLeft, MarginTop, MarginRight и MarginBottom, отвечающие за поля слева, сверху, справа и снизу, соответственно. При этом существует еще и возможность ограничить минимальный размер полей, что делается путем включения флага psoDefaultMinMargins, а сами значения задаются при помощи свойств MinMarginLeft, MinMarginTop, MinMarginRight и MinMarginBottom. Типом данных для всех этих свойств является целое, однако вопрос состоит в том, что за единицы измерения они представляют. За этот вопрос отвечает свойство Units, которое может принимать 3 значения:

  • pmDefault — используются единицы измерения, принятые в системе по умолчанию;
  • pmInches — значения интерпретируются как сотые доли дюйма;
  • pmMillimeters — значения интерпретируются как сотые доли миллиметра.

Эти же единицы применяются не только к полям, но и еще к 2 свойствам — PageWidth и PageHeight, представляющими собой размеры страницы в ширину и в высоту. Так, если свойство Units установлено в pmMillimeters, а в качестве носителя пользователь выберет лист размером A4, эти свойства примут значения 21000 и 29700, т.е. 210 мм и 297 мм.

Подобно диалогам для работы с файлами, диалоги печати имеют в своем распоряжении единственный собственный метод — Execute, который следует использовать для вызова окна диалога по ходу выполнения программы.

Диалог шрифта

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

Основным свойством этого диалога можно назвать свойство Font, при помощи которого данный диалог обменивается информацией о шрифте с программой. С типом TFont мы уже отчасти знакомы, в частности, с его свойствами Color, Name, Size, и Style. Так же имеются свойства Charset и Height, определяющие набор символов и высоту, соответственно. При этом значение высоты напрямую зависит от размера шрифта, задаваемого свойством Size. Вместе с тем, для диалога параметров шрифта важно именно свойство Size, поскольку в самом диалоге пользователь указывает именно это свойство. Что касается свойства Charset, то его возможные значения определяются выбранным шрифтом. Для шрифтов OpenType, основанных на Unicode и используемых в новейших версиях Windows, допустимо наличие множества наборов символов, для обычных же TrueType шрифтов наборов бывает не более 2, обычно это основной латинский (127 символов ANSI) и один из дополнительных — греческий, восточноевропейский, кириллический и т.д. Значение набора символов задается при помощи констант, определенных в модуле Graphics, или непосредственно числами. Так, для ANSI это будет 0, для символьных шрифтов — 2, а для кириллических — 204.

Подобно другим диалогам, диалог параметров шрифта имеет свойство Options. В данном случае оно имеет следующий набор флагов:

  • fdAnsiOnly — Делает доступными для выбора только шрифты, поддерживающие ANSI-символы. Символьные шрифты будут исключены;
  • fdApplyButton — Отображает кнопку «Применить», действие для которой можно задать при помощи обработчика события onApply;
  • fdEffects — Отображает группу видоизменения (эффекты зачеркивания, подчеркивания и цвет шрифта);
  • fdFixedPitchOnly — Делает доступными только моноширинные шрифты;
  • fdForceFontExist — Выполняет проверку на существование шрифта, введенного пользователем и выводит сообщение об ошибке, если такового нет;
  • fdLimitSize — Включает проверку на границы размеров шрифта, задаваемых при помощи свойств MaxFontSize и MinFontSize;
  • fdNoFaceSel — Диалог появляется без предварительно выбранного шрифта;
  • fdNoOEMFonts — Исключает OEM-шрифты из списка доступных шрифтов;
  • fdScalableOnly — Исключает не масштабируемые (битовые, или Type 1) шрифты из списка;
  • fdNoSimulations — Отображает только те варианты начертания, которые явно определены в файлах шрифта. Генерируемые наклонные и полужирные начертания не предлагаются;
  • fdNoSizeSel — Диалог появляется без предварительно выбранного размера;
  • fdNoStyleSel — Диалог появляется без предварительно выбранного стиля;
  • fdNoVectorFonts — Исключает векторные («плоттерные») шрифты;
  • fdShowHelp — Отображает кнопку справки на диалоге;
  • fdTrueTypeOnly — Делает доступными только шрифты типа TrueType;
  • fdWysiwyg — Отображает только шрифты, доступные для экрана и принтера (кроме TrueType).

Чаще всего диалог шрифта используют совместно с текстовым редактором. Допустим, если у нас имеется приложение, состоящее из многострочного редактора (компонент Memo) и предназначенное для просмотра текстовых файлов. Как минимум, такое приложение будет иметь 2 визуальных компонента — редактор и кнопку для вызова диалога открытия файла, а так же 1 невизуальный, представляющий собой собственно диалог открытья файла. Мы можем предоставить пользователю возможность изменять шрифт, которым отображаются файлы в редакторе, для чего нам потребуется компонент FontDialog и кнопка для обращения к этому диалогу. Не помешает добавить еще одну кнопку — для выхода из программы. Таким образом, мы получим приложение, вид которого в Delphi IDE будет примерно таким, как показано на рис. 14.3.

Рис. 14.3. Приложение для просмотра текстовых файлов

Из свойств, назначенных использованным компонентам, отметим лишь свойства Caption для всех 3 кнопок, а так же свойство Filter для диалога открытия файла. Пусть оно будет определено следующим образом:

В данном случае фильтр будет иметь 2 варианта: «текстовые» (для файлов с расширениями txt, bat, ini, pas и dpr), а так же «все», для файлов с любым расширением. После этого остается добавить обработчики события OnClick для всех 3 кнопок, в результате чего мы получим программу, код которой приведен в листинге 14.1.

Листинг 14.1. Исходный код программы просмотра файлов с выбором шрифта

unit Unit1; interface uses Windows, >

Как видно из процедуры, обрабатывающей нажатие кнопки «Шрифт», для того, чтобы изменить все параметры шрифта сразу, достаточно присвоить свойству Font компонента-редактора значение одноименного свойства диалога. Если бы нам требовалось присвоить лишь часть атрибутов (например, только название гарнитуры и размер кегля), то следовало бы присваивать соответствующие свойства типа TFont по отдельности:

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

Диалог цвета

Диалог параметров шрифта позволяет установить любые его параметры, включая цвет. Но он не предназначен для того, чтобы изменять цвет заднего плана. Для этих целей следует использовать специальный диалог выбора цвета, в VCL он представлен компонентом ColorDialog. С точки зрения свойств он аналогичен диалогу параметров, с той лишь разницей, что вместо свойства Font, определяющем шрифт, у него имеется свойство Color, определяющее цвета.

Что касается типичного для диалогов свойства Options, то оно у ColorDialog имеет всего 5 флагов:

  • cdFullOpen — Отображает диалог в развернутом виде, с палитрой выбора произвольных цветов;
  • cdPreventFullOpen — Запрещает пользователю раскрывать диалог для выбора произвольных цветов;
  • cdShowHelp — Отображает кнопку справки на диалоге;
  • cdSolidColor — Указывает ОС на необходимость использования ближайшего системного цвета (из фиксированной палитры Windows) взамен выбранного пользователем:
  • cdAnyColor — Позволяет пользователю выбрать цвет, который может быть отображен только путем смешивания нескольких цветов (что актуально, если глубина цветопередачи меньше 24 бит).

По умолчанию предлагается палитра, состоящая всего лишь из 48 цветов, кроме того, еще 16 цветов могут быть заданы разработчиком при помощи свойства CustomColors. Это свойство имеет тип TStrings и должно состоять из строк типа имя=значение, где в качестве имени используется слово Color и буква, от a до p по алфавиту (итого 16 вариантов максимум), а в качестве значения — цвет, заданный при помощи RGB-триплета:

ColorA=00CCDD ColorB=DFCA72 . ColorP=234567

Если же пользователь раскроет диалог (если это не запрещено флагом cdPreventFullOpen), или же диалог изначально открывается в полном виде (флаг cdFullOpen), то либо визуально, используя палитру, либо указывая числовые значения в формате HSB или RGB, пользователь сможет выбрать любой цвет (рис. 14.4).

Рис. 14.4. Диалог выбора цвета в свернутом (слева) и в развернутом (справа) режиме

Чтобы проиллюстрировать работу этого диалога, добавим к приведенному в листинге 14.1 приложению компонент ColorDialog и еще одну кнопку, которую назовем «Фон». При этом код для события OnClick получится следующим:

procedure TForm1.Button4Click(Sender: TObject); begin ColorDialog1.Color:=Memo1.Color; if not ColorDialog1.Execute then exit; Memo1.Color:=ColorDialog1.Color; end;

Здесь вначале диалогу присваивается цвет фона редактора, после чего диалог вызывается, и, в случае положительного срабатывания, фону редактора назначается новый цвет. Модернизированное таким образом приложение можно посмотреть в каталоге Demo\Part3\Dlg2.

Редактор RTF

Рассмотренные выше диалоги для работы со шрифтами и с цветом представляют наибольшую ценность для форматирования текста. Для этих целей в Windows имеется специальный компонент — редактор форматированного текста, представленный в библиотеке VCL компонентом RichEdit, относящимся к компонентам Win32. Этот компонент фактически делает то же, что и все остальные компоненты этой группы — предоставляет простой и удобный доступ к одному из стандартных системных элементов управления, причем в данном случае таковой представлен отдельным системным файлом — richedit32.dll.

В иерархии классов VCL компонент RichEdit является наследником класса TCustomMemo, на основе которого построен «обычный» многострочный редактор. Вместе с тем, этот компонент обладает рядом свойств и методов, позволяющих, с одной стороны, форматировать текст, а с другой — обеспечивающих ряд сервисных функций, вроде поиска совпадений или вывода на печать. Всего в распоряжении редактора форматированного текста имеется свыше 100 свойств. Впрочем, непосредственно у класса TCustomRichEdit, на основе которого и создан рассматриваемый компонент, определено только 12, при этом ряд из них — HideSelection, Lines, SelLength, SelStart и SelText являются лишь переопределение одноименных свойств уже рассмотренных нами разновидностей редакторов. В итоге нам остается рассмотреть не так уж и много новых свойств этого компонента — см. таблицу 14.3.

Таблица 14.3. Собственные свойства редактора RTF

Свойство Тип Описание
DefAttributes TTextAttributes Определяет характеристики текста по умолчанию
DefaultConverter TConversionClass Определяет класс того объекта, который будет использоваться для преобразования формата текста. Автоматически используются преобразователи простого текста из и в RTF
HideScrollBars Boolean Определяет, должны ли полосы прокрутки появляться только при необходимости
PageRect TRect Определяет размеры страницы (в пикселях), которые будут использоваться для вывода на печать
Paragraph TParaAttributes Определяет параметры форматирования абзаца
PlainText Boolean Определяет тип текста – форматированный (false) или простой (true)
SelAttributes TTextAttributes Определяет характеристики текста выделенного фрагмента

Свойство DefAttributes типа TTextAttributes, задающее параметры шрифта, по своей сути похоже на свойство Font, имеющееся у многих других компонент, но доступно только во время выполнения. В то же время, в момент инициализации приложения, именно на основе параметров, указанных для свойства Font, и назначаются значения для свойства DefAttributes. Что касается типа TTextAttributes, то он имеет одно важное отличие от типа TFont, а именно — свойство ConsistentAttributes, которое показывает отличия выбранного фрагмента текста по отношению к остальному тексту. Впрочем, такая информация является более полезной для другого свойства редактора, а именно — для SelAttributes. Именно это свойство позволяет изменять параметры выделенной части текста, или же той его части, где находится каретка ввода. Поскольку текст может быть выделенным только в работающем приложении, то и это свойство доступно только во время выполнения.

Чтобы лучше представить себе суть свойств DefAttributes и SelAttributes, создадим небольшое приложение, которое выводило бы информацию о состоянии обоих этих свойств для компонента RichEdit. Для этого, помимо самого компонента RichEdit, нам понадобятся так же 2 компонента типа Memo — для вывода информации, а так же кнопка, по нажатию на которую интересующие нас сведения будут выводиться.

Кроме того, нам понадобится готовый файл в формате RTF, который будет содержать предварительно отформатированный различными способами текст. Подготовить его можно в любом текстовом процессоре, включая Word или WordPad, надо только будет при сохранении указать соответствующий формат файла. Для загрузки такого файла разместим на форме еще одну кнопку. В результате у нас получится форма с редактором RTF, 2 кнопками и 2 обычными редакторами (рис. 14.5).


Рис. 14.5. Приложение для тестирования DefAttributes и SelAttributes

Для обработчика события OnClick кнопки «Загрузить» достаточно будет написать следующий код:

Здесь подразумевается, что файл с примером текста называется simple.rtf и расположен в том же каталоге, что и исполняемый файл приложения.

Что касается кода, выводящего информацию о значениях исследуемых свойств, то, учитывая, что нам оба раза придется выводить сведения об объекте одного и того же типа — TtextAttribuitrs, то имеет смысл предварительно создать процедуру, которая могла бы получить нужные данные на обработку и вывести их в указанное место. Назовем ее PrintAttrInfo, и определим как публичную процедуру класса TForm1:

type TForm1 = class(TForm) . public procedure PrintAttrInfo(a: TTextAttributes; m: TMemo); end;

Реализация же этой процедуры будет заключаться в последовательном добавлении в указанный в качестве 2-го аргумента редактор строк со значениями атрибутов:

procedure TForm1.PrintAttrInfo(a: TTextAttributes; m: TMemo); var s: string; begin m.Lines.Clear; //предварительно очищаем содержимое m.Lines.Add(‘Charset: ‘+IntToStr(a.Charset)); //набор символов m.Lines.Add(‘Colour: ‘+IntToStr(a.Color)); //цвет m.Lines.Add(‘Name: ‘+a.Name); //гарнитура < для текстового вывода информации о типе шрифта определим, какой из 3 возможных вариантов используется >case a.Pitch of fpDefault: m.Lines.Add(‘Pitch: fpDefault’); fpVariable: m.Lines.Add(‘Pitch: fpVariable’); fpFixed: m.Lines.Add(‘Pitch: fpFixed’); end; m.Lines.Add(‘Size: ‘+IntToStr(a.Size)); //размер < поскольку шрифт может одновременно иметь сразу несколько признаков свойства Style, то проверим их все >if fsBold in a.Style then s:=’fsBold ‘; if fsItalic in a.Style then s:=s+’fsItalic ‘; if fsUnderline in a.Style then s:=s+’fsUnderline ‘; if fsStrikeOut in a.Style then s:=s+’fsStrikeOut ‘; m.Lines.Add(‘Style: [ ‘+s+’]’); end;

Наконец, для кнопки «Показать» остается написать 2 вызова определенной нами процедуры PrintAttrInfo:

PrintAttrInfo(RichEdit1.DefAttributes, Memo1); PrintAttrInfo(RichEdit1.SelAttributes, Memo2);

Если теперь запустить это приложение и нажать на кнопку «Показать», то можно будет увидеть, что для обоих свойств отображаются одни и те же значения. Если же загрузить файл с форматированным текстом, то значения свойства SelAttributes изменятся. Более того, если в загруженном файле применены различные шрифты или стили оформления, то, изменяя текущую позицию каретки, можно будет видеть текущие атрибуты шрифта. В то же время, если изменить значение свойства Font, то изменятся не только значение свойства DefAttributes, но и параметры всего текста. Чтобы в этом убедиться, можно добавить еще одну кнопку, которая будет вызывать компонент FontDialog и написать для нее следующий код:

FontDialog1.Font:=RichEdit1.Font; if FontDialog1.Execute then RichEdit1.Font:=FontDialog1.Font;

Таким образом, после обращения к диалогу шрифта и назначению новых данных свойству Font, изменится оформление всего текста. Готовый пример можно найти в каталоге Demo\Part3\Rich1.

Еще одно свойство, специфическое для редактора RTF — это Paragraph. Оно позволяет задать ряд параметров текста, относящихся к форматированию абзацев, включая выравнивание, стиль списка, размер отступов и табуляции. Оно имеет тип TParaAttributes, который, в свою очередь, содержит следующие свойства:

  • Alignment — определяет выравнивание, может принимать значения taLeftJustify, taRightJustify, taCenter для выравнивания по левому краю, по правому краю и по центру, соответственно;
  • FirstIndent — определяет размер «красной строки» в пикселях;
  • LeftIndent и RightIndent — определяют, соответственно, отступы от левого и правого полей в пикселях;
  • Numbering — отвечает за стиль «нумерации», должен ли параграф оформляется как пункт списка (nsBullet) или нет (nsNone).

При работе с редактором форматированного текста следует учитывать, что в разных версиях Windows поддерживаются разные версии редактора. Так, в Windows 95 это версия 1.0, в Windows 98 — 2.0, а в Windows 2000 и XP — 3.0. Вместе с тем, если в системе с Windows 95 установлен Office 97 или MSIE 4.0, то компонент будет обновлен до версии 2.0. Разумеется, новые версии имеют обратную совместимость с предыдущими, однако на практике программа, использующая этот компонент, и запущенная под Windows 95 будет вести себя не совсем так, как та же программа, работающая в Windows XP. В основном, это связано с ошибками, допущенными при разработке первой редакции этого элемента управления для Windows 95. И хотя вряд ли вы найдете сейчас компьютер, работающий под этой версией ОС, да еще и без установленного Office, требования к обратной совместимости заставляют Borland от версии к версии Delphi оставлять свой компонент RichEdit привязанным к версии 1.0 данного элемента Windows. Поэтому, если вам придется на практике разрабатывать приложение, построенное вокруг этого компонента (т.е. приложение, в котором текстовый редактор является одной из важнейших составляющих), то используете сторонние компоненты, ориентированные на более новые версии этого системного элемента, например, RichEdit98. В частности, помимо более предсказуемого поведения и отсутствия специфических «особенностей», новые версии имеют более широкую функциональность, например, возможность выравнивания текста по ширине, а так же куда большие возможности оформления. В то же время, если RichEdit нужен лишь как обычный блокнот с готовыми функциями поиска и печати, то функциональности стандартного компонента будет вполне достаточно.

Пример текстового редактора

Все рассмотренные нами стандартные диалоги, совместно с компонентом RTF, могут быть использованы в рамках одного приложения — текстового редактора. Поэтому для того, чтобы лучше разобраться с их использованием, а заодно задействовать ряд иных, рассмотренных ранее в этой части книги компонент, создадим приложение, являющееся простым текстовым редактором — немного упрощенным аналогом входящего в состав Windows редактора WordPad.

Но прежде, чем браться за разработку приложения, хотелось бы остановиться на таком аспекте, как правила именования компонент. По умолчанию, как мы знаем, Delphi присваивает им имена, убирая первую букву (T) и добавляя порядковый номер (1,2,3). Но на практике это не очень удобно, поскольку в достаточно большой программе трудно будет понять, что такое Button22 или CheckBox17. По этой причине существуют некие общие правила наименования компонентов. Сводятся они к тому, что используется 2-3-4 буквенный префикс (или, по желанию — суффикс), идентифицирующий принадлежность объекта к классу, в сочетании со словом, отражающем суть данного объекта. Например, текстовое поле (класс TEdit), предназначенное для ввода имени пользователя, согласно таким правилам может называться, скажем, EdtUserName или UserNameEd, а кнопка (TButton) запуска чего-либо — BtnStart или StartBtn.

Итак, для текстового редактора нам понадобится создать новое приложение, после чего разместить на его форме ряд компонент, необходимых для его работы. Прежде всего, это главное меню (MainMenu) и, разумеется, сам RichEdit. Очевидно, что нам пригодятся и стандартные диалоги, включая диалоги для работы с файлами (OpenDialog и CloseDialog), диалоги печати (PrintDialog и PrintSetupDialog), а так же диалоги для работы с цветом и шрифтами (FontDialog и ColorDialog). Теперь для компонента RichEdit установим свойство Align в AlClient, чтобы область редактора заняла все свободное место на форме (рис. 14.6).

Рис. 14.6. Окно текстового редактора в начале разработки

Разместив нужные нам компоненты на форме, установим имена следующим образом:

  • Форма — MainFrm;
  • Главное меню — MainMenu;
  • Редактор — RichEd;
  • Диалоги — OpenDlg, SaveDlg, PrintDlg, PrintSetupDlg, FontDlg и ColorDlg;

Теперь можно заняться обустройством главного меню. Предусмотрим в нем 3 раздела: Файл, Правка и Формат. Для этого откроем редактор меню (двойным щелчком по компоненту MainMenu) и создадим эти 3 основных пункта главного меню. Они автоматически получат названия N1, N2 и N3, но изменять их мы не будем по той простой причине, что эти пункты — лишь заголовки для самих меню, и в программном коде обращаться к ним нам не придется.

Далее заполним меню «Файл», создав в нем пункты «Открыть…», «Сохранить…», «Печать…», «Принтер…» и «Выход». Назовем их OpenFileM, SaveFileM, PrintFileM, PrintSetupFileM и ExitFileM. Общие суффиксы FileM в будущем, будут нам подсказывать, что мы имеем дело с меню файловых операций. А многоточия после слова в подписи первых 4 пунктов меню будут подсказывать пользователю, что данные пункты выполняются не сами по себе, а вызывают диалоговое окно. Внешний вид конструктора меню на данном этапе будет таким, как показано на рис. 14.7. Само меню в программе будет выглядеть практически так же, что может навести нас на мысль о необходимости добавить разделители перед пунктами «Печать» и «Выход». Для этого следует выбрать в конструкторе нужный пункт и нажать клавишу Ins на клавиатуре, после чего в появившемся новом пункте в качестве значения свойства Caption указать символ «-«.

Следующим пунктом у нас идет меню «Правка». Разместим в нем стандартные пункты «Отменить», «Вырезать», «Копировать», «Вставить» и «Выделить все», присвоив им имена UndoEdM, CutEdM, CopyEdM, InsertEdM и SelAllEdM, соответственно. При этом после отмены не помешает поместить разделитель. Наконец, в последнюю группу — «Формат» — внесем пункты «Шрифт…» и «Цвет…», назвав их FontFmtM и ColorFmtM.

Теперь подготовим к работе файловые диалоги. Поскольку мы имеем дело с текстовым редактором типа RTF, то основным типом файла будет как раз RTF. Тем не менее, не помешает предусмотреть возможность открытия файлов другого типа, в частности обычных текстовых (TXT). Таким образом, для свойства Filter в инспекторе объекта следует указать следующее значение:

Файлы RTF|*.rtf|Текстовые файлы ASCII|*.txt|Все файлы|*.*

Что касается свойства DefaultExt, то для диалога сохранения было бы целесообразным указать rtf.

Для начала подготовительной работы уже сделано достаточно, впору приступать к разработке собственно рабочих функций программы. В частности, для пункта «Открыть» из меню «Файл» для события OnClick достаточно написать следующий код:

if OpenDlg.Execute then RichEd.Lines.LoadFromFile(OpenDlg.FileName);

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

if if OpenDlg.FileName<>» then SaveDlg.FileName:=OpenDlg.FileName; if SaveDlg.Execute then RichEd.Lines.SaveToFile(SaveDlg.FileName);

Подобным образом выполняются и обращения к остальным диалогам в программе. Что касается элементов меню «Правка», то там так же не должно быть проблем: достаточно обращаться к соответствующим методам самого редактора для выполнения соответствующих операций. При этом, правда, было бы полезным предварительно проверять операцию на допустимость. Например, перед выполнением отмены (метод Undo) не помешает проверить состояние свойства-флага CanUndo:

if RichEd.CanUndo then RichEd.Undo;

То же самое относится и к операциям работы с буфером обмена — не к чему пытаться копировать в буфер выделенный текст, если такового нет:

if RichEd.SelText<>» then RichEd.CutToClipboard;

Пояснить следует, разве что, операцию вставки из буфера обмена: здесь было бы полезным предварительно убедиться, что в нем действительно находится текст. Для этого в список используемых модулей (uses) следует добавить модуль Clipbrd, сама же процедура проверки будет выглядеть следующим образом:

if Clipboard.HasFormat(CF_TEXT) then .

Здесь мы обратились к глобальному объекту Clipboard (он создается автоматически, подобно Screen или Application) и воспользовались его методом HasFormat, чтобы убедиться, что информация, находящаяся в буфере обмена, является текстом.

После создания обработчиков событий для всех пунктов меню, остается сохранить проект, выбрав в качестве имени файла формы «main», а файла проекта — «myedit». Таким образом, полный исходный код модуля main получится примерно таким, как показано в листинге 14.2.

Листинг 14.2. Исходный код редактора MyEdit

unit main; interface uses Windows, Messages, SysUtils, Variants, >» then SaveDlg.FileName:=OpenDlg.FileName; if SaveDlg.Execute then RichEd.Lines.SaveToFile(SaveDlg.FileName); end; procedure TMainFrm.PrintMClick(Sender: TObject); begin if PrintDlg.Execute then RichEd.Print(»); end; procedure TMainFrm.PrintSetupMClick(Sender: TObject); begin PrintSetupDlg.Execute; end; procedure TMainFrm.ExitFileMClick(Sender: TObject); begin close; end; procedure TMainFrm.FontFmtMClick(Sender: TObject); begin FontDlg.Font.Name:=RichEd.SelAttributes.Name; FontDlg.Font.Color:=RichEd.SelAttributes.Color; FontDlg.Font.Charset:=RichEd.SelAttributes.Charset; FontDlg.Font.Size:=RichEd.SelAttributes.Size; FontDlg.Font.Style:=RichEd.SelAttributes.Style; if not FontDlg.Execute then exit; RichEd.SelAttributes.Name:=FontDlg.Font.Name; RichEd.SelAttributes.Color:=FontDlg.Font.Color; RichEd.SelAttributes.Charset:=FontDlg.Font.Charset; RichEd.SelAttributes.Size:=FontDlg.Font.Size; RichEd.SelAttributes.Style:=FontDlg.Font.Style; end; procedure TMainFrm.ColorFmtMClick(Sender: TObject); begin ColorDlg.Color:=RichEd.SelAttributes.Color; if not ColorDlg.Execute then exit; RichEd.SelAttributes.Color:=ColorDlg.Color; end; procedure TMainFrm.UndoEdMClick(Sender: TObject); begin if RichEd.CanUndo then RichEd.Undo; end; procedure TMainFrm.CutEdMClick(Sender: TObject); begin if RichEd.SelText<>» then RichEd.CutToClipboard; end; procedure TMainFrm.CopyEdMClick(Sender: TObject); begin if RichEd.SelText<>» then RichEd.CopyToClipboard; end; procedure TMainFrm.InsertEdMClick(Sender: TObject); begin if Clipboard.HasFormat(CF_TEXT) then RichEd.PasteFromClipboard; end; procedure TMainFrm.SelAllEdMClick(Sender: TObject); begin RichEd.SelectAll; end; end.

Если теперь запустить программу (готовый исходный код находится в каталоге Demo\Part3\Editor), то можно будет убедиться, что она действительно работает — открывает файлы, позволяет вводить и редактировать текст, изменяя его оформление. Из недостатков можно сходу выделить лишь надпись «RichEd», которую редактор содержит изначально и отсутствие полос прокрутки, если текста будет больше, чем помещается в окне. Первый недостаток исправляется правкой свойства Lines, путем удаления ненужного текста, а второй — путем назначения свойству ScrollBars значения ssBoth. Отметим, что если при этом свойство HideScrollBars оставить в значении истины, то полосы прокрутки будут появляться лишь при необходимости.

Более серьезный недостаток кроется в заложенной нами возможности работать не только с файлами RTF, но и с обычными текстовыми. Дело в том, что если при сохранении вы даже выберите тип текстовых файлов и укажете расширение txt, то программа все равно сохранит файл с разметкой. Но, как нам известно, у компонента RichEdit существует свойство PlainText, отвечающее за текущий формат. Таким образом, остается лишь установить нужное значение для этого свойства в момент перед сохранением файла. А для того, чтобы определить, какой формат выбрал пользователь, используем свойство FilterIndex диалога сохранения:

if SaveDlg.Execute then begin RichEd.PlainText:=(SaveDlg.FilterIndex>1); RichEd.Lines.SaveToFile(SaveDlg.FileName); RichEd.PlainText:=false; end;

Отметим, что после сохранения выполняется принудительная установка формата RTF. Это необходимо с той точки зрения, что следующим шагом пользователя может быть попытка открытия файла RTF, который не сможет быть обработан, если включен режим PlainText.

Диалоги поиска и замены

Работа с текстом не ограничивается изменением параметров шрифта. Часто гораздо более полезными операциями являются такие, как поиск подстроки с возможной заменой ее на иной текст. Для этих целей так же предусмотрены стандартные диалоговые окна — FindDialog и ReplaceDialog. Свойства этих компонентов включают в себя стандартное для диалогов Options, а так же группу свойств, определяющих положение диалога на экране — Left, Top и Position. Но наиболее важным, безусловно, является свойство FindText, которое собственно и содержит строку для поиска. У диалога замены предусмотрено еще одно свойство — ReplaceText, которое определяет строку для замены.

Но рассмотрим для начала свойство Options. Применительно к диалогам поиска и замены оно имеет следующий набор флагов:

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

По умолчанию включен только флаг frDown, что делает выбранным направление поиска к концу документа.

Использование данных диалогов подразумевает применение самостоятельно разработанных функций поиска и замены. В то же время, у такого компонента, как редактор RTF, имеется метод FindText, который существенно упрощает задачу. Он определен следующим образом:

function FindText(const SearchStr: string; StartPos, Length: Integer; Options: TSearchTypes): Integer;

Здесь в качестве SearchStr указывается строка для поиска, StartPos обозначает место, с которого следует начинать поиск, а Length — место, до которого следует производить поиск. В качестве Options можно указать флаги stWholeWord и stMatchCase, включающие распознавание слов целиком и регистра. Таким образом, мы можем модернизировать наш текстовый редактор таким образом, чтобы он поддерживал поиск текста (модернизированный вариант находится в каталоге Demo\Part3\Editor2).

Прежде всего, поместим на форму оба рассматриваемых компонента — FindDialog и ReplaceDialog, присвоив им имена FindDlg и ReplaceDlg. Затем откроем конструктор меню и в раздел «Правка» добавим разделитель и 2 новых пункта — «Найти…» и «Заменить. «, назвав их, соответственно, SearchEdM и ReplaceEdM. Теперь для пункта «Найти» определим процедуру вызова диалога поиска:

procedure TMainFrm.SearchEdMClick(Sender: TObject); begin FindDlg.Execute; end; Таким способом мы лишь отображаем диалог. Саму процедуру поиска следует разместить в обработчике события OnFind самого диалога. В простейшем случае она должна лишь определять место начала и конца поиска, а в случае нахождения искомого — выделять найденный фрагмент. Таким образом, мы можем получить примерно следующую процедуру: procedure TMainFrm.FindDlgFind(Sender: TObject); var StartPos, ToPos, FoundPos: Integer; begin StartPos:=RichEd.SelStart+RichEd.SelLength; ToPos:=Length(RichEd.Text)-StartPos; FoundPos:=RichEd.FindText(FindDlg.FindText, StartPos, ToPos, []); if FoundPos<>-1 then begin RichEd.SelStart:=FoundPos; RichEd.SelLength:=Length(FindDlg.FindText); RichEd.SetFocus; end else ShowMessage(‘Текст не найден!’); end;

Здесь вначале вычисляется точка начала поиска — StartPos, затем определяется длина поиска — ToPos, в типичном случае она должна равняться размеру текста от точки начала поиска до конца документа, после чего вызывается собственно метод FindText, а результат его работы присваивается переменной FoundPos. Затем, если результат не равен -1 (т.е. если вхождение подстроки найдено), фрагмент текста выделяется, и фокус ввода передается окну редактора, в противном случае выводится сообщение «Текст не найден».

Недостатком процедуры в таком виде является то, что она не учитывает возможных изменений, сделанных пользователем в окне поиска. В частности, не определяется ни варианты учета регистра символов, ни вариант поиска по словам. Для того чтобы задействовать эти опции, нам необходимо определить переменную типа TSearchTypes, которую надо будет установить в то или иное значение, в зависимости от состояния флагов диалога поиска. Инициализацию этой переменной (назовем ее Opt) следует проводить перед обращением к методу FindText, так что в начало процедуры добавим следующие строки кода:

if frMatchCase in FindDlg.Options then Opt:=[stMatchCase]; if frWholeWord in FindDlg.Options then Opt:=Opt+[stWholeWord];

Теперь наша функция поиска распознает заданные пользователем установки, так что можно перейти к реализации процедуры замены. Собственно вызов диалога замены производится точно таким же способом — путем обращения к методу Execute. При этом процедура поиска, реализуемая диалогом замены, будет в точности такой же, как и у диалога поиска — достаточно будет изменить имя компонента (см. так же листинг 14.3).

Что касается процедуры обработки события OnReplace, которое возникает, когда пользователь нажимает на кнопку «Заменить» или «Заменить все», то она, в простейшем случае будет выглядеть аналогичным образом, с той лишь разницей, что к ней добавляется замена вхождения на указанный пользователем текст. А именно после выделения найденного текста следует добавить еще одну строку кода:

Таким образом, одиночную замену можно считать реализованной. Однако если пользователь нажмет кнопку «Заменить все», то произойдет лишь одна замена. Следовательно, необходимо использовать цикл с постусловием. При этом цикл должен прерываться после первой же итерации, если пользователь нажал кнопку «Заменить», а не «Заменить все», либо в том случае, если искомой строки не найдено. Таким образом, мы получаем следующее условие:

repeat . until (FoundPos=-1) or not(frReplaceAll in ReplaceDlg.Options);

Если теперь заключить весь блок операций процедуры в этот цикл, за исключением, разве что, первых 2 строк, которые определяют параметры поиска, запустить программу и попытаться произвести замену по всем вхождениям, то можно будет убедиться, что все замечательно работает. Единственная проблема состоит в том, что по окончании работы, вне зависимости от того, были ли произведены замены или нет, вы получите сообщение «Текст не найден». Это объясняется тем, что при последней итерации в любом случае будет выполнен блок else условного оператора, проверяющего наличие вхождения искомого текста. Таким образом, необходимо вынести эту проверку за пределы цикла, а для того, чтобы определить, было ли что-либо найдено, используем переменную-счетчик, которую перед началом выполнения цикла установим в 0, а при каждой выполненной замене будем увеличивать на 1. Таким образом, мы сможем не только выдавать сообщение о том, что текст не найден, но и показывать количество произведенных замен, если пользователь нажимал на кнопку «Заменить все». Итоговый вариант процедуры замены приведен в листинге 14.3.

Листинг 14.3. Процедуры поиска и замены для редактора RTF и ReplaceDialog

procedure TMainFrm.ReplaceDlgFind(Sender: TObject); var StartPos, ToPos, FoundPos: Integer; Opt: TSearchTypes; begin if frMatchCase in ReplaceDlg.Options then Opt:=[stMatchCase]; if frWholeWord in ReplaceDlg.Options then Opt:=Opt+[stWholeWord]; StartPos:=RichEd.SelStart+RichEd.SelLength; ToPos:=Length(RichEd.Text)-StartPos; FoundPos:=RichEd.FindText(ReplaceDlg.FindText, StartPos, ToPos, Opt); if FoundPos<>-1 then begin RichEd.SelStart:=FoundPos; RichEd.SelLength:=Length(ReplaceDlg.FindText); RichEd.SetFocus; end else ShowMessage(‘Текст не найден!’); end; procedure TMainFrm.ReplaceDlgReplace(Sender: TObject); var i, StartPos, ToPos, FoundPos: Integer; Opt: TSearchTypes; begin if frMatchCase in ReplaceDlg.Options then Opt:=[stMatchCase]; if frWholeWord in ReplaceDlg.Options then Opt:=Opt+[stWholeWord]; i:=0; repeat StartPos:=RichEd.SelStart+RichEd.SelLength; ToPos:=Length(RichEd.Text)-StartPos; FoundPos:=RichEd.FindText(ReplaceDlg.FindText, StartPos, ToPos, Opt); if FoundPos<>-1 then begin RichEd.SelStart:=FoundPos; RichEd.SelLength:=Length(ReplaceDlg.FindText); RichEd.SelText:=ReplaceDlg.ReplaceText; RichEd.SetFocus; inc(i); end; until (FoundPos=-1) or not(frReplaceAll in ReplaceDlg.Options); if i=0 then ShowMessage(‘Текст не найден!’) else if frReplaceAll in ReplaceDlg.Options then ShowMessage(‘Произведено ‘+IntToStr(i)+’ замен’); end;

Таким образом, мы создали редактор, который, в принципе, может делать все необходимые в повседневной работе вещи. Для удобства остается только определить сочетания горячих клавиш для основных действий, прежде всего — для открытия и сохранения файлов, а так же для поиска и замены (горячие клавиши для редактирования текста типа Ctrl+Z или Ctrl+C поддерживаются автоматически). Чтобы назначить сочетания, в конструкторе меню для меню «Открыть» в свойстве ShortCut выберем Ctrl+O, для «Сохранить» — Ctrl+S, для «Найти» — Ctrl+F, а для «Заменить» — Ctrl+H. Все эти сочетания являются стандартными для данных действий в Windows, а изобретать собственные варианты для стандартных действий крайне не рекомендуется.

Илон Маск рекомендует:  Как получить hinstance консольного приложения
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL