Глава 11. Объекты диалоговых блоков

             Блоки диалога,  или просто диалоги,  являются  интерфейсными
        объектами, инкапсулирующими поведение диалоговых блоков.  Это до-
        черние окнам, которые обычно выводятся для выполнения специфичес-
        ких  задач  (например,  конфигурирования принтера или организации
        ввода текста).  Объект TDialog обеспечивает инициализацию, созда-
        ние и исполнение всех типов блоков диалога. Для каждого типа диа-
        лога вашего приложения, как и в случае оконных объектов, вы може-
        те определить производные от TDialog диалоговые блоки.

             ObjectWindows всегда  предоставляет два типа диалогов наибо-
        лее общего типа,  ввод текста  и  диалог  файла.  Кроме  того,  в
        ObjectWindows имеется тип TDlgWindow,  который позволяет вам соз-
        давать диалоги, поведение которых более похоже на окно.

             Данная глава охватывает следующие темы:

             * Использование объектов диалоговых блоков.
             * Работа с управляющими элементами в диалоговых блоках.
             * Связь объектов с управляющими элементами.
             * Связь окон с ресурсами.

                       Использование объектов диалоговых блоков
        -----------------------------------------------------------------

             Использование объектов  диалоговых блоков аналогично исполь-
        зованию объектов всплывающего окна.  Диалоги  являются  дочерними
        окнами своего  порождающего окна.  Для простых диалоговых блоков,
        которые появляются на короткое время, вся обработка диалога может
        быть выполнена  одним  методом объекта порождающего окна.  Диалог
        может быть сконструирован,  выполнен и удален в одном  методе,  и
        нет необходимости хранить диалог в поле объекта.  Для более слож-
        ных диалогов может потребоваться записать диалоговый блок в  поле
        оконного объекта вашего диалогового блока.

             Подобно всплывающим окнам и управляющим элементам,  диалого-
        вые блоки являются дочерними окнами и при конструировании  добав-
        ляются к списку ChildList порождающих окон.

             Использование объекта диалогового блока предусматривает сле-
        дующие шаги:

             * Построение объекта.

             * Выполнение диалогового окна.

             * Закрытие диалогового окна.


                                  Построение объекта
        -----------------------------------------------------------------

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

             Каждый ресурс диалогового блока имеет идентификатор, который
        может быть  номером  идентификатора  (Word)  или строкой (PChar).
        Этот идентификатор позволяет объекту диалогового блока  задавать,
        какой ресурс используется для определения его внешнего вида.

                                  Вызов конструктора
        -----------------------------------------------------------------

             Чтобы построить объект диалогового блока, вызовите конструк-
        тор Init.  Init воспринимает в качестве своих  параметров  указа-
        тель на порождающее окно и параметр  типа  PChar,  представляющий
        имя ресурса диалога:

             ADlg:=New(PSampleDialog, Init(@Self, 'EMPLOYEEINFO'));

             Если идентификатор задается номером,  его требуется привести
        с помощью MakeIntResource к PChar:

             Dlg := New(PSampleDialog, Init(@Self, PChar(120)));

             Так как диалоговые блоки обычно строятся внутри метода окон-
        ного объекта,  порождающее окно почти всегда задается  как  Self.
        Объекты диалоговых  блоков,  не  создаваемые  оконными объектами,
        должны иметь  в  качестве  порождающего  Applicartion^.MainWindow
        (поскольку это единственный оконный объект, всегда присутствующий
        в каждой программе ObjectWindows).

                             Выполнение диалоговых блоков
        -----------------------------------------------------------------

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


                       Режимные и безрежимные диалоговые блоки
        -----------------------------------------------------------------

             Режимные диалоговые  блоки  являются наиболее общими блоками
        диалога. Аналогично генерируемым функцией MessageBox блокам сооб-
        щений,  режимные  диалоги отображаются для специфических целей на
        короткий отрезок времени.  Слово "режимный"  означает,  что  пока
        отображается диалог,  пользователь не может выбрать или использо-
        вать его порождающее окно.  Пользователь  должен  воспользоваться
        диалогом и выбрать командную кнопку OK или Cancel для прекращения
        диалога и возвращению к работе с программой.  Режимный диалог как
        бы "замораживает" выполнение оставшейся части программы.

             Безрежимный диалоговый  блок  не приостанавливает выполнения
        программы. Как и оконный объект,  он может создаваться  и  выпол-
        няться в одном шаге с помощью MakeWindow:

             Application^.MakeWindow(ADlg);

             В любое  момент вы можете считать данные из диалогового окна
        (если объект диалогового блока еще существует).  Чаще  всего  это
        выполняется в методе OK, который вызывается при активизации поль-
        зователем командной кнопки OK.

                        Выполнения режимных диалоговых блоков
        -----------------------------------------------------------------

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

             Объекты приложения имеют режимный эквивалент MakeWindow, ко-
        торый называется ExecDialog.  Аналогично MakeWindows,  ExecDialog
        проверяет допустимость  передаваемого  объекта  диалогового блока
        (то есть успешность выполнения конструктора объекта и  отсутствие
        ситуации нехватки памяти), а затем выполняет диалоговый блок, де-
        лая его модальным.

             ExecDialog возвращает целочисленное  значение,  указывающее,
        что пользователь закрывает диалоговое окно. Возвращаемое значение
        - это идентификатор задействованного  пользователем  управляющего
        элемента, такой  как  id_Ok для командной кнопки OK или id_Cancel
        для командной кнопки Cancel. После завершения выполнения диалого-
        вого окна ExecDialog уничтожает объект диалогового окна.

             Таким образом, с помощью одного  вызова метода ExecDialog вы
        можете создать, вывести на экран и завершить диалоговый блок.

             ADlg := New(PSampleDialog, Init(@Self, 'RESOURCEID'));
             ReturnValue := Application^.ExecDialog(ADlg);
             if ReturnValue = id_OK then
                   { кодирование для выборки данных и обработки диалога }
             else
             if ReturnValue = id_Cancel then { нажата Cancel }

                       Выполнение безрежимных диалоговых блоков
        -----------------------------------------------------------------

             Безрежимные диалоги похожи на всплывающие окна и управляющие
        элементы.  Основная причина, по которой вы не можете удалять без-
        режимными диалогами сразу же после их отработки (в отличие от ре-
        жимных), состоит в том, что вы заранее не знаете, когда пользова-
        тель закроет блок диалога.  (Помните о том, что в режимных диало-
        гах метод ExecDialog не возвращает значения до закрытия диалога.)
        Следовательно  лучше  всего  конструировать безрежимные диалоги в
        конструкторе его порождающего окна и хранить в поле  порождающего
        объекта.

             В  отличие от окон и объектов управления, используемых в ка-
        честве дочерних окон,  диалоги автоматически не отображаются  при
        выводе их порождающих окон.

             constructor ParentWindow.Init(AParent: PWindowsObject;
                                           ATitle: PChar);
             begin
               TWindow.Init(AParent, ATitle);
               ADlg := New(PSampleDialog, Init(@Self, 'EMPLOYEEINFO'));
             end;

             Затем, каждый раз,  когда вы хотите отобразить диалог,  соз-
        дайте и выведите его:

             begin
               Application^.MakeWindow(ADlg)
             end;

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

                      Работа с безрежимными диалоговыми блоками
        -----------------------------------------------------------------

             Диалоговые блоки  отличаются от других дочерних окон,  таких
        как всплывающие окна и управляющие элементы, тем, что они за вре-
        мя существования своего порождающего окна создаются и уничтожают-
        ся многократно и редко выводятся на экран и уничтожаются вместе с
        порождающим окном. Обычно программа создает диалоговый блок в от-
        вет на выбор меню, щелчок кнопкой "мыши", ошибку или другое собы-
        тие.

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

                   Примечание: К режимным диалоговым блокам это не  отно-
              сится, так как они автоматически уничтожаются при закрытии.

                                 Завершение диалогов
        -----------------------------------------------------------------

             Каждый блок диалога должен иметь способ его закрытия пользо-
        вателем.  Чаще всего это кнопки OK и/или Cancel.  Потомки TDialog
        автоматически отреагируют на нажатие одной из этих кнопок вызовом
        метода EndDlg,  который заканчивает диалог. Вы можете разработать
        новые средства завершения диалога, если только они приводят к вы-
        зову EndDlg. Для изменения поведения при закрытии вы можете пере-
        определить методы OK и Cancel.

             Например, вы можете переопределить метод OK  таким  образом,
        что введенные данные будут копироваться в буфер, который находит-
        ся вне объекта блока диалога.  Если ввод был  осуществлен  некор-
        ректно, вы можете вывести блок сообщения или сгенерировать звуко-
        вой сигнал. Если ввод был сделан верно, вы можете вызвать EdnDlg.
        Переданное  в  EndDlg  значение становится возвращаемым значением
        ExecDialog.

             Как и в случае оконных  объектов,  объект  диалога  вызывает
        CanClose до закрытия блока диалога,  как это имело место для объ-
        ектов окна.  Вы можете переписать CanClose для учета условий зак-
        рытия,  как для блока диалога, который проверяет ввод пользовате-
        ля.  При переписывании CanClose нужно быть уверенным в  том,  что
        вызывается унаследованный от него метод,  т.к. он вызывает методы
        CanClose дочерних окон.


                           Работа с управляющими элементами
        -----------------------------------------------------------------

             Все блоки диалога, кроме самых простейших, имеют (как дочер-
        ние окна) несколько управляющих элементов  (например,  управления
        редактированием,  блоки списка и командные кнопки). Обратите вни-
        мание на то,  что эти управляющие элементы являются не  объектами
        управляющих  элементов,  а только управляющими интерфейсными эле-
        ментами,  без методов и полей объекта. Эта глава кроме того пока-
        зывает  альтернативные методы,  позволяющие связывать объекты уп-
        равления с элементами управления диалоговых блоков с  использова-
        нием InitResource.

                   Примечание: Использование  управляющих объектов в окне
              (но не блоков диалога) показано в Главе 12.

             Между объектом диалога и его элементами  управления  имеется
        двухсторонняя связь (можно сказать диалог).  С одной стороны диа-
        логу нужно манипулировать его управляющими элементами,  например,
        для заполнения блока списка. С другой стороны ему нужно обрабаты-
        вать и реагировать на сгенерированные сообщения управляющих собы-
        тий, например, когда пользователь выбирает элемент блока списка.

                        Взаимодействие с управляющим элементом
        -----------------------------------------------------------------

             Windows определят набор сообщений управляющих элементов, ко-
        торые посылаются от приложения к Windows.  Например, имеются сле-
        дующие сообщения  блока  списка:   lb_GetText,   lb_GetCurSel   и
        lb_AddString.  Сообщения управляющих элементов задают специфичес-
        кое управление и несут с собой информацию в аргументах  wParam  и
        lParam.  Каждый управляющий элемент в ресурсе диалога имеет номер
        идентификатора, который вы используете для  задания  управляющего
        элемента, принимающего сообщение. Для посылки сообщения управляю-
        щему элементу нужно вызвать метод TDialg  SendDlgItemMsg.  Напри-
        мер,  данный метод заполнит блок списка диалога элементами текста
        путем посылки сообщения lb_AddString:

             procedure TestDialog.FillListBox(var Msg: TMessage);
             var
               TextItem: PChar;
             begin
              TextItem := 'Item 1';
              SendDlgItemMsg(id_LB1, lb_AddString, 0, Longint(TextItem));
             end;

        где id_LB1 есть константа, равная ID блока списка.

             Если вам потребуется описатель одного из управляющих элемен-
        тов диалога, его можно получить методом GetItemHandle:

             GetItemHandle(id_LB1);


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

             TTestDialog = object(TDialog)
             procedure HandleBN1Msg(var Msg: TMessage); virtual
                                      id_First + id_BN1;
             procedure HandleListBox(var Msg: TMessage); virtual
                                      id_First + id_LB1;
             end;

             В данном примере id_BN1 - это идентификатор кнопки управляю-
        щего элемента,  а id_LB1 - это идентификатор блока списка. Щелчок
        "мышью" на командной кнопке даст сообщение, посылаемое в диалого-
        вый блок.  Объект диалогового блока реагирует через  динамический
        метод с индексом, основанным на идентификаторе кнопки IDBN1.

                   Примечание: Уведомляющие сообщения подробно поясняются
              в Главе 16 "Сообщения Windows"

             Каждое управляющее  информационное сообщение поступает с ко-
        дом уведомления - целочисленной константой, которая идентифициру-
        ет произведенное действие.  Например, результатом выбора элемента
        из блока списка будет сообщение с кодом lbn_SelChange, где lbn_ -
        уведомление блока списка (List Box Notification).  Нажатие кнопки
        "мыши" дает сообщение bn_Clicked. Ввод в управляющем элементе ре-
        дактированием  приводит  к сообщению с кодом en_Changed.  Имеются
        коды уведомления для блоков списка,  управляющих элементов редак-
        тированием,  комбинированных блоков и командных кнопок.  Код уве-
        домления передается в Msg.lParamHi сообщения.  Для восприятия уп-
        равляющих информационных сообщений напишем метод реакции для типа
        диалога, обрабатывающий важные коды уведомления:

             procedure TestDialog.HandleLB1Msg(var Msg: TMesage);
             begin
               case Msg.lParamHi of
                      lbn_SelChange:    { изменение порядка выбора };
                      lbn_DblClk:    { выбор с помощью двойного щелчка };
               end;
             end;
             Управляющие элементы, имеющие соответствующие объекты, могут
        отвечать на уведомления сами. См. Главу 16.

                                     Пример связи
        -----------------------------------------------------------------
             В файле с текстом программы DIALTEST.PAS, основное окно име-
        ет режимный диалог,  определенный типом диалога TTestDialog.  Эта
        программа обеспечивает двухстороннюю связь между объектом диалога
        и его управляющими элементами. Два метода - IDBN1 и IDLB1 - явля-
        ются методами реакции, основанными на дочерних идентификаторах, и
        вызываются при выборе пользователем управляющих элементов (дочер-
        них окон).  Например, при выборе пользователем кнопки диалога BN1
        ('Fill List Box') вызывается метод IDBN1. Аналогично, когда поль-
        зователь делает выбор в блоке списка,  вызывается IDLB1. С другой
        стороны, для заполнения блока списка элементами текста код метода
        IDBN1 посылает в диалог управляющее сообщение,  lb_AddString, ис-
        пользуя метод диалога SendDlgItemMsg,

             Эта программа также показывает как путем создания нового ти-
        па диалога и связывания его с ресурсом диалога в вызове конструк-
        тора Init метода TestWindow.RunDialog  создаются  новые  диалоги.
        Полный текст программы вы можете найти на дистрибутивных дисках.

                    Ассоциирование объектов управляющих элементов
        -----------------------------------------------------------------

             До этого момента мы имели дело с реакцией блоков диалога  на
        управляющие информационные сообщения, которая использовала методы
        реакции,  основанные на дочерних идентификаторах.  Однако, иногда
        более  предпочтительно,  чтобы управляющий элемент сам реагировал
        на сообщение.  Например, вам может потребоваться управляющий эле-
        мент редактирования,  который позволяет вводить только цифры, или
        командная кнопка,  которая меняет стиль при своем "нажатии".  Это
        можно  реализовать с помощью объектов управляющих элементов в ок-
        нах (см. Главу 12). Однако, чтобы это имело место для управляющих
        элементов диалога, созданного с файлом ресурса, вам нужно исполь-
        зовать для конструирования объекта другой конструктор.

             При организации связей вы создаете объект управляющего  эле-
        мента для представления управляющего объекта диалога. Этот объект
        управления дает вам гибкость в реакции на управляющие  сообщения.
        Он  дает вам возможность использования набор методов объектов уп-
        равляющих элементов, описанных в Главе 12.

             Для связи объекта с управляющим элементом определите сначала
        объект управляющего элемента. Он должен быть создан в конструкто-
        ре диалога.  Однако,  вместо того, чтобы использовать конструктор
        Init,   как   это  показано  в  Главе  12,  следует  использовать
        InitResource, который берет в качестве параметров порождающее ок-
        но  и  идентификатор  управляющего элемента (из ресурса диалога).
        Это приводит к вызову методов реакции на сообщения  объектов  уп-
        равляющих элементов вместо обработки элементов по умолчанию.  Для
        этого нужно определить новый тип объекта,  производный от предус-
        мотренного типа управляющего элемента.

             Обратите внимание,  что в отличие от задания оконного объек-
        та, которое предполагает два шага (Init и MakeWindow),  поскольку
        управляющий элемент  уже существует,  связь объекта с управляющим
        элементов выполняется за один шаг:  он загружается из диалогового
        ресурса. Вам нужно только сообщить InitResource,  какой управляю-
        щий элемент из ресурса вы хотите связать  с  объектом,  используя
        идентификатор управляющего элемента.

                            Использование диалоговых окон
        -----------------------------------------------------------------

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

             Одним из  подходов  размещения  управляющих элементов в окне
        является использование объектов управляющих элементов (как  пока-
        зано в Главе 12). Другой подход - это слияние возможностей диало-
        говых блоков  и  окон,  как  это  делается   в   объектном   типе
        TDlgWindow, что  позволяет получить гибридный объект,  называемый
        диалоговым окном.  Второй подход  предусматривает  более  удобный
        способ построения  и управления многими управляющими элементами в
        окне. Кроме того,  он предлагает для диалоговых блоков более гиб-
        кие средства окон.

             TDglWindow является потомком TDialog и наследует его методы,
        такие как Execute,  Create,  Ok и EndDlg. Как и диалоговые блоки,
        диалоговые окна имеют соответствующий ресурс диалогового блока. С
        другой стороны, как и окна, диалоговые окна имеют соответствующий
        класс окон,  определяющий среди всего прочего пиктограмму, курсор
        и меню. Из-за связи с оконным классом в потомке TDlgWindow следу-
        ет переопределять  методы  GetClassName  и  GetWindowClass.  Этот
        класс должен быть тем же, что и перечисленный в диалоговом ресур-
        се.

             В большинстве  случаев  вы  будете выполнять диалоговые окна
        как и другие окна или безрежимные диалоговые окна с помощью мето-
        дов Create и Show, а не метода Execute.

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


                    Использование предопределенных диалоговых окон
        -----------------------------------------------------------------

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

                        Использование диалоговых блоков ввода
        -----------------------------------------------------------------

             Диалоговые блоки ввода - это простые объекты диалоговых бло-
        ков, определяемых типом TInputDialog, которые выводят пользовате-
        лю подсказку со строкой текста.

             Вы можете запускать диалоги ввода как режимные или безрежим-
        ные диалоговые блоки, но обычно вы будете выполнять их как режим-
        ные. С объектом диалога ввода связан ресурс диалога ввода. Он на-
        ходится в файле ObjectWindows OSTDDLGS.RES.

                  Примечание: Использование модуля StdDlgs  автоматически
              включает ресурсы в OSTDDLGS.RES.

             Каждый раз при конструировании диалога ввода с использовани-
        ем метода Init,  вы задаете для диалога  заголовок,  подсказку  и
        текст по умолчанию.  Покажем вызов конструктора Init объекта диа-
        лога ввода:

             var SomeText: array[079] of Char;
             begin
               AnInputDlg.Init(@Self, 'Caption', 'Prompt', SomeText,
                     SizeOf(SomeText))
                 .
                 .
                 .
             end;

             В данном примере EditText - это текстовый буфер, который за-
        полняется вводом пользователя,  когда он  "нажимает"  кнопку  OK.
        Когда пользователь "нажимает" кнопку OK или клавишу Enter, строка
        введенного в диалоге ввода текста автоматически передается в мас-
        сив символов, который хранит текст по умолчанию. В данном примере
        конструируется и отображается блок диалога и считывается текст:

             procedure TSampleWindow.Test(var Msg: TMessage);
             var
               EditText: array[0255] of Char;
             begin
               EditText:='Frank Borland';
               if ExecDialog(New(PInputDialog, Init(@Self, 'Data Entry',
               'Введите имя:', EditText, SizeOf(EditText)))) = id_OK then
               MessageBox(HWindow, EditText, 'Имя =', mb_OK);
               else MessageBox(HWindow, EditText,
                               'Имя пока имеет значение:',mb_OK);
             end;


                              Файловые диалоговые блоки
        -----------------------------------------------------------------

             Файловые диалоговые  блоки  являются  другим типом диалогов,
        поставляемых с ObjectWindows в типе TFileDialog.  Файловый диало-
        говый блок следует использовать каждый раз,  когда вы желаете по-
        будить пользователя ввести имя файла,  например в  функциях  File
        Open и File Save во всех приложениях. См. Рис. 11.1.

             +-----------------------------------------------------+
             |#=#XXXXXXXXXXXXXXXXXXXXFile OpenXXXXXXXXXXXXXXXXXXXXX|
             +-----------------------------------------------------|
             |                                                     |
             |               +------------------+  +----------+    |
             |    Имя файла: | *.pas            |  |####OK####|    |
             |               +------------------+  +----------+    |
             |                                     +----------+    |
             |    Каталог: a:\                     |##Cancel##|    |
             |                                     +----------+    |
             |    Файлы:             Каталоги:                     |
             |    +--------------+-+ +--------------+-+            |
             |    |collect3.pas  |^| |[-a-]         |^|            |
             |    |collect4.pas  +-| |[-c-]         +-|            |
             |    |diatest.pas   |#| |[-f-]         |X|            |
             |    |edittest.pas  |X| |[-g-]         |#|            |
             |    |ewndtest.pas  |#| |[-h-]         |#|            |
             |    |helpwind.pas  |#| |[-i-]         |#|            |
             |    |lboxtest.pas  |#| |[-j-]         |#|            |
             |    |mditest.pas   +-| |[-k-]         +-|            |
             |    |paltest.pas   |v| |[-w-]         |v|            |
             |    +--------------+-+ +--------------+-+            |
             |                                                     |
             +-----------------------------------------------------+

             Рис. 11.1 Файловый диалоговый блок.

             В большинстве случаев файловые диалоговые  блоки выполняются
        как режимные. С объектом файлового диалога связан ресурс файлово-
        го  диалогового  блока,  имеющийся  в   ObjectWindows   в   файле
        OSTDDLGS.RES. Использование модуля OStdDlgs автоматически включа-
        ет файл ресурса.
                      Инициализация файлового диалогового блока
        -----------------------------------------------------------------

             TFileDialog определяет  конструктор Init,  который позволяет
        задать маску файла и буфер для считывания имени файла. Маска фай-
        ла (такая как '*.TXT') ограничивает файлы, перечисляемые в комби-
        нированном блока (аналогично тому, как это делается в команде DOS
        DIR  *.TXT).  Имя  файла  и  маска  передаются  в   записи   типа
        TFileDlgRec.  Приведем  пример вызова файлового диалогового блока
        Init:

             var
               FileRec: TFileDlgRec;
               IsOpen: Boolean;
             begin
               StrCopy(FileRec.Name, 'TEST1.TXT');
               StrCopy(FileRec.Mask, 'C:\*.TXT');
               IsOpen := True;
               AFileDlg.Init(@Self, FileRec, IsOpen);
                .
                .
                .
             end;

             Последний параметр указывает,  будет ли диалог диалогом отк-
        рытия или сохранения (как описывается в следующем разделе).

                        Выполнение файловых диалоговых блоков
        -----------------------------------------------------------------

             Существует два  вида файловых диалоговых блоков:  диалоговый
        блок открытия файла и диалоговый блок сохранения файла.  Они раз-
        личаются текстом кнопки в правом верхнем углу диалогового окна. В
        зависимости от того, запрашивает пользователь открытие или сохра-
        нение файла,  на  командной  кнопке будет написано Open или Save.
        Когда вы вызовите ExecDialog,  то получите тип диалогового блока,
        заданных в конструкторе IsOpen параметром типа Boolean. Если фай-
        ловый диалоговый блок строится с IsOpen, установленным в True, то
        диалоговый блок будет работать как диалоговый блок открытия  фай-
        ла. Если он строится с IsOpen, установленным в False, то файловый
        диалоговый блок будет блоком сохранения файла.


             Дополнительным средством    файлового    диалогового   блока
        ObjectWindows является то, что он выводит пользователю подсказку,
        хочет ли  пользователь  сохранить файл с именем уже существующего
        файла (см. Рис. 11.2). В другой раз вы можете запросить пользова-
        теля, хочет  ли  он открыть новый файл или очистить текущий текст
        без сохранения.  Поскольку это должно происходить  перед  выводом
        файлового диалогового блока, то не является частью поведения это-
        го блока.  В примере программы Steps в первой части данного руко-
        водства перед   загрузкой  рисунка  из  файла  проверяется  метод
        CanClose его основного окна.

                  +-------------------------------------------+
                  |#=#XXXXXXFile exists! Overwrite it?XXXXXXXX|
                  +-------------------------------------------|
                  |                                           |
                  |    C:\TEMP\NICELINE.PTS                   |
                  |                                           |
                  |   +----------+            +----------+    |
                  |   |###Yes####|            |###No#####|    |
                  |   +----------+            +----------+    |
                  |                                           |
                  +-------------------------------------------+

             Рис. 11.2 Предупреждение пользователя о перезаписи существу-
        ющих файлов.

             File exists! Overwrite it? - файл существует, затереть его?

             Приведем пример типичного использования диалогового окна:

             procedure TMyWindow.OpenSelectedFile;
             var FileRec: TFileDlgRec;
             begin
               StrCopy(FileRec.Name, 'HEDGEHOG.PAS');
               StrCopy(FileRec.Mask, '*.PAS');
               if ExecDialog(New(PFileDialog,
                             Init(@Self, FileRec, True))) = id_Ok then
               begin
                 Assign(AFile, StrPas(FileRec.Name));
                   .
                   .
                   .
               end;
             end; 
                              Назад | Содержание | Вперед