Практически любое Windows-приложение имеет меню, строку состояния, панель инструментов и прочие необходимые атрибуты. Эти стандартные элементы пользовательского интерфейса приходится разрабатывать каждому, кто решает с помощью компьютера любую более или менее серьезную проблему. Мы решили совместить приятное с полезным и рассмотреть технологию создания меню и других жизненно важных элементов программы в процессе создания простого, но очень полезного в практике приложения для просмотра графических файлов (точечных рисунков BMP, значков ICO, метафайлов WMF).

МЕНЮ

ИДЕЯ МЕНЮ

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

Различают два типа меню:

• главное меню формы;

• вспомогательные всплывающие меню.

Главное меню обычно расположено под заголовком формы. Выбор пункта главного меню вызывает появление на экране выпадающего меню.

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

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

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

Для главного и всплывающего меню Delphi имеет два разных компонента: MainMenu и PopupMenu. Установка этих компонентов происходит одинаково, но результат будет разным. В первом случае мы получим стандартную строку главного меню, а во втором окно всплывающего меню.

ГЛАВНОЕ МЕНЮ

Шаг 1. Приступая к практической работе, начните в Delphi новое приложение. Для этого выберите в меню File команду New Application. На экране появится чистая форма. Пока она имеет банальный заголовок Form1, который желательно заменить. Поскольку в качестве примера мы решили разработать приложение для просмотра графических файлов, давайте назовем форму Picture Viewer. Выберите в Инспекторе Объектов свойство Caption и впишите там эту строку (рис. 3).

Шаг 2. Еще форме нужно дать подходящий программный идентификатор. Отыщите в Инспекторе Объектов свойство Name и впишите значение PictureForm.

Шаг 3. Теперь сохраните модуль главной формы и весь проект, выполнив команду меню File | Save. Модуль назовите Main.pas, а проект — PicView. dpr. Вот теперь можно приступать к изучению и меню, и всего остального.

 Отображение в форме главного меню (main menu) обеспечивает компонент MainMenu, расположенный в Палитре Компонентов на странице Standard. Поместите компонент на форму и дайте ему имя MainMenu

Компонент MainMenu имеет небогатый набор свойств, подробно мы на них останавливаться не будем, а обозначим лишь самые важные:

AutoMerge Определяет, сливается ли главное меню вторичной формы с главным меню главной формы. Способ слияния определяется значением свойства Grouplndex каждого пункта меню верхнего уровня.

Items Обеспечивает доступ к пунктам меню верхнего уровня.

Значок компонента MainMenu, который вы видите на форме, отображается лишь на этапе разработки. Он нужен для того, чтобы вы могли быстро активизировать компонент и перейти к установке его свойств в Инспекторе Объектов. Однако компонент MainMenu является невизуальным и на этапе выполнения приложения его значок не отображается. Пользователь видит результат работы компонента — строку меню с пунктами.

Пока в меню нет пунктов, нет и самого меню. Добавление новых пунктов выполняется в специальном окне Дизайнера Меню.

ДИЗАЙНЕР МЕНЮ

Вызов Дизайнера Меню осуществляется из локального меню компонента MainMenu (команда Menu Designer…)  или двойным щелчком мыши по пиктограмме компонента.

 Шаг 4. Выполните указанную выше команду, и на экране появится окно с заголовком PictureForm. MainMenu. Это и есть Дизайнер Меню.

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

Шаг 5. Пока строка главного меню состоит из одного безымянного пункта. Дайте пункту программный идентификатор Fileltem (значение свойства Name) и впишите в значении свойства Caption его текст: &file. Символ & обеспечивает подчеркивание следующего за ним символа при отображении текста, поэтому пункт меню будет виден как File. Подчеркнутая буква используется в комбинации с клавишей Alt для прямого доступа к пункту меню с клавиатуры. В данном случае активизация пункта File будет происходить по комбинации клавиш Alt+ F (рис. 7).

 Шаг 6. Сейчас под пунктом File нужно создать выпадающее меню. Для этого просто щелкните в Дизайнере Меню на пункте File, Delphi все сделает за вас. Под пунктом File появится пустая ячейка — заготовка первого пункта выпадающего меню. Дайте пункту программный идентификатор Openltem и в свойстве Caption впишите текст &0pen.... Вместо пустой ячейки появится текст Open... и пустая ячейка переместится ниже.

Шаг 7. Действуя по аналогии, добавьте еще три пункта: Save As... , Close и Exit. В программе они должны называться SaveAsltem, Closeltem и Exitltem соответственно.

Согласитесь, что добавление новых пунктов сделано в Delphi очень удобно. Но для создания сложного меню одной этой возможности явно недостаточно — нужны средства вставки и удаления пунктов, создания вложенных меню и прочие. Поэтому в Дизайнере Меню для каждого пункта предусмотрено локальное меню с необходимым команд:

Команда

Описание

Insert

Вставляет в позиции курсора новый пункт.

Delete

Удаляет пункт в позиции курсора.

Create Submenu

Создает в позиции пункта выпадающее меню.

Select Menu

Предлагает выбрать для работы другой компонент меню.

Save As Template

Сохраняет текущую структуру меню в списке шаблонов.

Insert From Template

Вставляет в позиции курсора меню, взятое из списка шаблонов.

Delete Templates

Удаляет шаблон(ы) меню.

Insert From Resource

Вставляет в позиции курсора меню, взятое из файла ресурсов.

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

ПУНКТЫ МЕНЮ

Нетрудно догадаться, что пункты меню, как и все элементы интерфейса Delphi, являются компонентами. Класс пункта меню называется TMenultem, его самые характерные свойства:

Свойство

Описание

Break

Если равно mbBreak или mbBarBreak, то пункт меню начинает новую колонку. Значение mbBarBreak обеспечивает отделение новой колонки от старой вертикальной чертой.

Caption

Текст пункта меню.

Checked

Если равно True, то пункт меню содержит метку: “птичку” или жирную точку в зависимости от значения свойства Radioltem.

Enabled Enabled

Определяет, доступен ли пункт меню пользователю.

Grouplndex

Работает по-разному в зависимости от того, находится пункт в выпадающем меню или в строке главного меню. Пункты выпадающего меню с одинаковым положительным значением Grouplndex согласованно переключают “птичку” или жирную точку (вид метки определяется свойством Radioltem). Пункты строки главного меню, находящиеся в дочерней форме MDI, сливаются с пунктами главного меню обрамляющей формы MDI при активизации дочерней формы. При этом, если в строке главного меню обрамляющей формы существуют пункты с таким же значением свойства Grouplndex, то новый пункт со своим списком пунктов полностью заменяет старый; в противном случае новый пункт со своим списком пунктов вставляется в строку главного меню.

Hint

Подсказка для пользователя, отображаемая в строке состояния.

Radioltem

Если равно True, то метка пункта имеет вид жирной точки и несколько пунктов с одинаковым значением Grouplndex работают как зависимые переключатели - установка у одного пункта свойства Checked в True снимает метку с другого пункта.

Visible

Определяет, виден ли пункт меню пользователю.

ShortCut

Комбинация клавиш для выполнения команды, не открывая меню.

По аналогии с остальными классами компонентов можно было бы предположить, что в Палитре Компонентов существует компонент Menultem. Однако его там нет, поскольку пункты меню не существуют сами по себе, а работают только в составе строки главного меню или окна всплывающего меню. Тем не менее они во многом ведут себя как настоящие компоненты, например настраиваются в Инспекторе Объектов и наряду с остальными компонентами помещаются в исходный текст формы в виде отдельных полей. Чтобы в этом убедиться, активизируйте Редактор Кода и найдите определение класса формы. Оно будет таким, как на рисунке (рис. 10).

РАЗДЕЛИТЕЛЬНЫЕ ЛИНИИ

Шаг 8. Логически связанные между собой команды принято разделять горизонтальной линией. Например, пункт Exit хорошо бы отделить от остальных. Для этого вставьте новый пункт и запишите в значении свойства Caption символ минуса (-) (рис. 11).

Delphi знает, что одиночный символ минуса в имени пункта меню означает разделитель и нарисует для пункта горизонтальную линию. Кстати это не запрещает вам создавать пункты, имена которых начинаются со знака минус. Если вы запишете что-нибудь после знака минус, то в имени пункта отобразится весь введенный текст.

Иногда список команд выпадающего меню бывает таким большим, что все они не умещаются в одном столбце на экране. Эта проблема решается с помощью нескольких колонок. Для организации колонок компоненты Menultem имеют свойство Break. Если в некотором пункте оно равно mbBreak или mbBarBreak, то этот пункт начинает новую колонку. Значение mbBarBreak отличается от mbBreak тем, что обеспечивает отделение колонок вертикальной чертой. Колонки в меню применяются редко, поэтому пример с ними мы опускаем.

КЛАВИАТУРНЫЕ СОКРАЩЕНИЯ

Некоторым пунктам меню принято назначать клавиатурные сокращения. Клавиатурное сокращение (shortcut) — это комбинация клавиш на клавиатуре, дублирующая команду меню. Например, в некоторых программах команде меню File | Exit назначается сокращение Alt+X. Текст сокращения отображается в названии пункта справа от него. Сокращения ускоряют работу с приложением и популярны среди опытных пользователей.

Шаг 9. Чтобы назначить пункту сокращение, активизируйте его в Дизайнере Меню, переключитесь на Инспектор Объектов и выберите в значении свойства ShortCut требуемую комбинацию клавиш. Если ее там нет, то введите текст сокращения с клавиатуры (рис. 12).

ОБРАБОТКА КОМАНД МЕНЮ

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

Шаг 10. Итак, активизируйте в Дизайнере Меню пункт Exit и выберите в Инспекторе Объектов страницу Events. Теперь сделайте двойной щелчок мышью на значении события OnClick (рис. 13).

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

procedure TPictureForm.ExitItemClick(Sender: TObject);

begin

Close;

end;

Подключение меню к форме выполняется с помощью свойства формы Menu. Отыскав его в Инспекторе Объектов, вы обнаружите, что оно уже содержит идентификатор разработанного меню MainMenu, поэтому в данном случае для работы меню больше ничего не нужно.

Проверим, работает ли меню. Откомпилируйте и запустите проект. На экране появится форма со строкой меню под заголовком. Выбор в меню любой команды кроме Exit безрезультатен. По команде Exit или комбинации клавиш Alt+X окно закроется и приложение завершится.

ПУНКТЫ-ПЕРЕКЛЮЧАТЕЛИ

Работая в Windows, вы, наверное, замечали, что некоторые команды меню ведут себя как переключатели. Например, выбираешь в меню View команду Toolbar — в окне отображается панель инструментов и в названии пункта меню появляется метка, свидетельствующая о том, что режим включен. Выбираешь команду Toolbar еще раз - панель инструментов убирается и метка исчезает. Рассмотрим, как программируется такое поведение.

Шаг 11. В строке главного меню создайте выпадающее меню View с пунктами Toolba (программное имя Toolbarltem) и Status bar (программное имя Statusbarltem). Уста новите в последних двух пунктах свойство Checked в значение True. Пункты стану помеченными (рис. 15).

Шаг 12. В ответ на выбор пользователем пунктов Toolbar и Status bar будем переключать метку. Вы уже знаете, как определить обработчик события OnClick для пункта меню, поэтому сразу приведем то, что вы должны получить:

procedure TPictureForm.ToolbarItemClick (Sender: TObject) ;

begin

Toolbarltem.Checked := not Toolbarltem.Checked;

{ Спрятать или показать панель инструментов }

end;

procedure TPictureForm.StatusbarItemClickf Sender: TObject);

begin

Statusbarltem.Checked :=not Statusbarltem.Checked;

{ Спрятать или показать строку состояния }

end;

Готово, соберите проект и проверьте, что пункты Toolbar и Statusbar стали работать как переключатели. Позже, когда вы создадите в своем приложении строку состояния и панель инструментов, мы допишем эти обработчики событий. А сейчас рассмотрим еще один вид пунктов-переключателей.

ВЗАИМОИСКЛЮЧАЮЩИЕ ПУНКТЫ-ПЕРЕКЛЮЧАТЕЛИ

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

Шаг 13. Добавьте в меню View три пункта: Half Size (программное имя HalfSizeltem), Normal Size (программное имя NormalSizeltem) и Double Size (программное имя DoubleSizeltem), отделив их от остальных пунктов меню с помощью разделительной линии.

Шаг 14. Прежде всего сделайте метку жирной точкой, установив в каждом новом пункте свойство Radioltem в значение Тше. Теперь объедините пункты меню в одну согласованно работающую группу, для этого в каждом пункте установите одинаковый ненулевой Grouplndex (например, 1). Один из пунктов (например, Normal Size) пометьте (рис. 16).

Шаг 15. Чтобы привести в действие механизм переключения пунктов, определите в них следующие обработчики события OnClick:

procedure TPictureForm.Half SizeItemClickfSender: TObject);

begin

HalfSizeItem.Checked := True;

{ Показать картинку половинного размера }

end;

procedure TPictureForm.NormalSizeItemClick(Sender: TObject);

begin

NormalSizeItem.Checked := True;

{ Показать картинку нормального размера }

end;

procedure TPictureForm. DoubleSizeItemClick (Sender: TObject);

begin

DoubleSizeItem.Checked := True;

{ Показать картинку двойного размера }

end;

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

ЗАПРЕЩЕННЫЕ ПУНКТЫ МЕНЮ

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

Шаг 16. Согласитесь, что легче запретить выбор отдельных пунктов меню, чем программировать логику поведения на случай, когда пользователь выбрал неправильную команду. Поэтому в нашем примере логично было бы запретить пункты Save As..., Close, а также Half Size, Normal Size и Double Size, когда нет открытого графического файла. Для этого в каждом из указанных пунктов меню установите свойство Enabled в значение False (рис. 17).

Шаг 17. Во время работы приложения нужно еще динамически разрешать и запрещать пункты меню в зависимости от того, открыт графический файл или нет. Так как эти действия достаточно универсальны, оформим их в виде частного (private) метода формы EnableCommands:

type

TPictureForm = class(TForm)

private

procedure EnableCommands(Enable: Boolean);

end;

procedure TPictureForm. EnableCommands (Enable: Boqriean);

begin

SaveAsItem.Enabled := Enable;

Closeltem.Enabled := Enable;

HalfSizeltem.Enabled := Enable;

NormalSizeItem.Enabled := Enable;

DoubleSizeItem.Enabled := Enable;

end;

Параметр Enable данного метода регулирует, что именно нужно сделать: разрешить (значение True) или запретить (значение False) множество пунктов меню.

Шаг 18. Как вы понимаете, в обработчик команды меню Open... следует поместить вызов метода EnableCommands с параметром True, а в обработчик команды Close — вызов метода EnableCommands с параметром False:

procedure TPictureForm.OpenItemClick(Sender: TObject);

begin

{ Открыть файл картинки и разрешить команды }

EnableCommands(True) ;

end;

procedure TPictureForm.CloseItemClick(Sender: TObject);

begin

{ Закрыть файл картинки и запретить команды }

EnableCommands(False);

end;

Скомпилируйте и запустите проект. Посмотрите, как изменилось меню приложения . В самом начале работы отдельные режимы выпадающих меню File и View запрещены. Выбор команды File | Open... разрешает их использование, а выбор команды File | Close — запрещает.

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

ВСПЛЫВАЮЩЕЕ МЕНЮ

'Всплывающее (локальное) меню (pop-up menu) представлено в Delphi компонентом PopupMenu. Отыщите его в Палитре Компонентов на странице Standard и поместите на форму. Дайте новому компоненту имя PopMenu.

Обозначим наиболее важные свойства компонента всплывающего меню:

Свойство

Описание

Alignment

Определяет место, в котором появляется меню относительно курсора мыши: paleft - левый верхний угол меню совпадает с позицией курсора мыши; paCenter - середина верхнего края меню совпадает с позицией курсора мыши; paRight - правый верхний угол меню совпадает с позицией курсора мыши.

AutoPopup

Если равно True, то меню всплывает автоматически после щелчка правой кнопки мыши. Если равно False, то за отображение меню “ отвечает программист.

Items

Обеспечивает доступ к пунктам меню.

Шаг 19. Всплывающее меню наполняется пунктами, как и главное меню — в Дизайнере Меню. Двойным щелчком мыши на компоненте PopMenu откройте окно Дизайнера Меню и, используя уже известные вам приемы, добавьте в меню пункты Half Size (с идентификатором PopHalfSizeltem), Normal Size (с идентификатором PopNormaISizeltem) and Double Size (с идентификатором PopDoubleSizeltem). Во всех пунктах всплывающего меню установите следующие свойства:

Enabled = False; Grouplndex = 1; Radioltem = True

Кроме этого, пометьте пункт Normal Size, установив в нем свойство Checked в значение True. Таким образом, команды всплывающего меню дублируют некоторые команды главного меню, обеспечивая пользователю дополнительные удобства.

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

Шаг 20. Активизируйте в Дизайнере Меню пункт Half Size и выберите в Инспекторе Объектов страницу Events. Теперь в значении события OnClick откройте выпадающий список и выберите обработчик HalfSizeltemClick. To же самое проделайте с пунктами Normal Size и Double Size, но установите в них обработчики NormalSizeltemClick и DoubleSizeltemClick соответственно.

Шаг 21. Для синхронной работы главного и всплывающего меню нужно еще скорректировать некоторые существующие методы:

procedure TPictureForm. Half SizeItemClick (Sender: TObject);

begin

HalfSizeltem.Checked := True;

PopHalfSizeItem.Checked := True;

{ Показать картинку половинного размера }

end;

procedure TPictureForm.NormalSizeItemClick(Sender: TObject);

begin

NormalSizeItem.Checked := True;

PopNormalSizeItem.Checked := True;

{ Показать картинку нормального размера }

end;

procedure TPictureForm. DoubleSizeItemClick (Sender: TObject);

begin

DoubleSizeItem.Checked :== True;

PopDoubleSizeItem.Checked := True;

{ Показать картинку двойного размера }

end;

procedure TPictureForm. EnableCornmands (Enable: Boolean);

begin

SaveAsItem.Enabled := Enable;

Closeltem.Enabled := Enable;

HalfSizeltem.Enabled := Enable;

NormalSizeItem.Enabled := Enable;

DoubleSizeItem.Enabled := Enable;

PopHalfSizeItem.Enabled := Enable;

PopNormalSizeItem.Enabled := Enable;

PopDoubleSizeItem.Enabled := Enable;

end;

Шаг 22. Всплывающее меню готово, осталось сделать так, чтобы оно вызывалось по щелчку правой кнопки мыши в области формы. Нет ничего проще — активизируйте форму и запишите в значении свойства PopupMenu имя разработанного ранее всплывающего меню PopMenu. Вы можете ввести это значение с клавиатуры или выбрать из выпадающего списка.

Готово, откомпилируйте и запустите проект. Щелчок правой кнопки мыши в окне приложения вызовет появление всплывающего меню. Все его пункты окажутся запрещены. Чтобы пункты всплывающего меню заработали, выполните команду главного меню File | Open. После этого удостоверьтесь, что выпадающее меню работает синхронно с главным меню.

 

ЗАКОНЧЕННОЕ ПРИЛОЖЕНИЕ ДЛЯ ПРОСМОТРА ГРАФИЧЕСКИХ ФАЙЛОВ

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

• организовать выбор файла по командам меню Open... и Save As... ;

• реализовать загрузку и отображение картинки.

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

ДИАЛОГОВЫЕ ОКНА ОТКРЫТИЯ И СОХРАНЕНИЯ ФАЙЛА

Шаг 23. Диалоговые окна для выбора открываемого или сохраняемого файла организуются с помощью компонентов OpenDialog и SaveDialog. Найдите их в Палитре Компонентов на странице Dialogs и поместите на форму. Первый компонент назовите OpenDialog, а второй — SaveDialog (рис. 23).

 

Характерные свойства этих компонентов кратко описаны в таблице:

Свойство

Описание

DefaultExt

Расширение, которое добавляется к имени файла, если пользователь его пропустил.

RIeName

Начальное имя файла.

Filter

Фильтр имени файла.

Fiiterlndex

Номер активного фильтра.

InitialDir

Начальный каталог, открываемый при первом появлении окна диалога.

Options

Параметры, определяющие внешний вид и поведение окна диалога.

Title

Заголовок окна диалога. Если значение свойства не указано, то заголовок будет стандартным - Open (Открыть) или Save (Сохранить), в зависимости от типа компонента.

Компоненты OpenDialog и SaveOialog очень схожи между собой, оба являются объектно-ориентированными оболочками стандартных диалоговых окон Windows: Open и Save. Например, на следующем рисунке показано окно Open (рис. 24).

Приблизительный сценарий работы с каждым из компонентов OpenDialog и SaveDialog таков. Компонент помещается на форму и конфигурируется для выбора тех или иных файлов. По команде меню Open... или Save As... у соответствующего компонента вызывается метод Execute. Метод Execute выполняет диалог и возвращает значение True, если пользователь выбрал файл. Полный маршрут к файлу запоминается в значении свойства FileName. Ход дальнейших действий зависит от прикладной задачи и, как правило, включает или чтение, или запись файла, в зависимости от обрабатываемой команды меню.

Придерживаясь написанного сценария, приспособим компоненты OpenDialog и SaveDialog для выбора графических файлов с расширениями BMP, ICO, EMF и WMF. Чтобы пользователь мог просматривать файлы выборочно, т.е. какого-то одного типа, в диалоговых блоках имеется набор фильтров, оформленный в виде выпадающего списка Files of type (см. рис. выше). Исходные данные для этого списка устанавливаются в свойстве Filter. Номер активного в данный момент фильтра записывается в свойстве Filterlndex.

Шаг 24. Приступим к формированию фильтров. Активизируйте на форме компонент OpenDialog и в Инспекторе Объектов сделайте двойной щелчок мыши на значении свойства Filter (рис. 25):

Шаг 25. В результате на экране появится Редактор Фильтра (см. рис. ниже). Он представляет собой список с двумя колонками. В левой колонке вводится текст, отображаемый в выпадающем списке Files of type. В правой колонке через точку с запятой записываются маски, на основании которых выполняется фильтрация файлов в окне диалога. Для того чтобы предоставить пользователю максимальное удобство при выборе графических файлов, установите в компоненте OpenDialog фильтры, показанные на рис. 26.

Шаг 26. Действуя аналогично, установите фильтр в компоненте SaveDialog, как показано на рис. 27.

Компоненты OpenDialog и SaveDialog имеют большое количество булевских параметров, организованных в виде флагов составного свойства Options. Эти параметры влияют на то, как окно диалога выглядит и работает. По умолчанию все параметры имеют значение False. Результат установки параметров в значение True прокомментирован в таблице:

Параметр

Описание

ofAllowMultiSelect

Если равно True, то пользователь может выделить сразу несколько файлов.

ofCreatePrompt

Если равно True и пользователь вводит имя несуществующего у файла, то пользователю задается вопрос, желает ли он создать новый файл с таким именем.

ofExtensionDifferent

Этот параметр устанавливается после завершения диалога, если расширение в имени файла отличается от начального расширения.

ofFileMustExist

Если равно True, то пользователь не сможет ввести имя несуществующего файла.

ofHideReadOnly

Если равно True, то переключатель Read-only отсутствует в окне диалога.

ofNoChangeDir

Если равно True, то пользователь не сможет сменить каталог в окне диалога.

ofNoDereferenceUnks

Если равно True, то ярлыки к каталогам трактуются как обычные файлы. В противном случае они трактуются как каталоги.

ofNolongNames

Если равно True, то длинные имена файлов запрещены.

ofNoNetworkButton

Если равно True, то кнопка Network отсутствует в окне диалога. Этот параметр работает только в паре с параметром ofOldStyleDialog.

ofNoReadOnlyRetum

Если равно True, то пользователь не сможет ввести файл с атрибутом read-only (только для чтения).

ofNoTestRleCreate

Если равно True, то проверка на возможность записи в каталог не выполняется.

ofNoValidate

Если равно True, то пользователь может вводить в имени файла любые символы, даже недопустимые.

ofOldStyleDialog

Если равно True, то окно диалога отображается в старом стиле Windows 3. 1.

ofOverwritePrompt

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

ofReadOnly

Если равно True, то переключатель Read-only в окне диалога включен.

ofPathMustExist

Если равно True, то пользователь не сможет ввести для файла несуществующий маршрут.

ofShareAware

Если равно True, то ошибки одновременного доступа к файлу со стороны нескольких приложений игнорируются.

ofShowHelp

Если равно True, то в окне диалога присутствует кнопка Help.

Шаг 27. В нашем простом примере ограничимся тем, что установим в обоих компонентах OpenDialog и SaveDialog параметр ofHideReadOnly, а в компоненте SaveDialog — еще и параметр ofOverwritePrompt.

ОТОБРАЖЕНИЕ КАРТИНОК

Шаг 28. Ну вот, диалоговые компоненты настроены. Теперь нужен компонент, обеспечивающий отображение картинок различных форматов. Такой компонент в Delphi есть, он называется Image и находится в Палитре Компонентов на странице Additional. Выберите его из палитры и опустите в левый верхний угол формы. Назовите новый компонент Image (рис. 28).

Характерные свойства компонента Image кратко описаны в таблице:

Свойство

Описание

AutoSize

Если равно True, то размеры компонента автоматически подгоняются под размеры картинки.

Center

Центрирует картинку в пределах компонента.

Picture

Содержит картинку, отображаемую в области компонента.

Stretch

Если равно True, то картинка масштабируется так, чтобы ее размеры совпадали с размерами компонента.

Компонент Image позволяет выводить картинки трех основных форматов: точечный рисунок (bitmap), метафайл (metafile) и значок (icon). Отображаемая картинка хранится в свойстве Picture, доступном и на этапе разработки, и на этапе выполнения приложения.

 Шаг 29. Размеры установленной картинки могут не совпадать с текущими размерами управляющего элемента. В этом случае неуместившаяся часть изображения отрезается. Чтобы подогнать размеры управляющего элемента под размеры картинки, установите свойство AutoSize в True. После этого при каждой установке свойства Picture размеры управляющего элемента будут изменяться автоматически.

Бывает и обратная ситуация, когда нужно смасштабировать картинку, подогнав её размеры под заданные размеры управляющего элемента. Для этого свойство Stretcl устанавливается в True, a AutoSize — в False. Масштабирование целесообразно применять только для метафайлов; для точечных рисунков оно не всегда дает приемлимый результат — начинает сказываться точечная природа изображения.

Сейчас компонент Image находится на своем месте и подготовлен к работе (свойств AutoSize имеет значение True). Рассмотрим, как осуществляется загрузка и сохранение картинки по командам меню Open... и Save As....

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

procedure TPictureForm. OpenItemClick (Sender: TObject);

begin

if OpenDialog. Execute then begin

Image. Picture. LoadFromFile (OpenDialog. FileName);

EnableCommands (True);

NormalSizeltem. Clicks;

end;

end;

В данном обработчике обратите внимание на вызов метода Click у компонента NormalSizeltem. Он имитирует выбор пункта меню Normal Size с тем, чтобы сразу после загрузки картинка имела нормальный размер.

Шаг 31. Пункт меню Save As... еще не имеет обработчика события OnClick, поэтому вам придется его установить (напомним, что это делается в Инспекторе Объектов на странице Events). Обработка команды Save As... состоит в выдаче стандартного диалогового окна Save с последующим сохранением картинки в файле:

procedure TPictureForm. SaveAsItemClick ( Sender: TObject);

begin

if SaveDialog. Execute then Image. Picture. SaveToFile (SaveDialog. FileName);

end;

Шаг 32. Чтобы наш пример наконец заработал, осталось дописать несколько обработчиков событий. В обработчике команды меню Close удалим картинку компонента Image и уменьшим размеры компонента до нуля, чтобы в отсутствие картинки компонент не занимал места на форме:

procedure TPictureForm. CloseItemClick (Sender: TObject);

begin

with Image do begin

Picture: = nil;

Width: = 0;

Height: = 0;

end;

NormalSizeItem. Click;

EnableCommands (False);

end;

Шаг 33. Еще остались незавершенными обработчики команд меню Half Size, Normal Size, Double Size, которые тоже нужно доработать. С ними вы легко разберетесь, читая комментарии в тексте программы:

procedure TPictureForm. HalfSizeItemClick (Sender: TObject);

begin

HalfSizeltem. Checked: = True;

PopHalfSizeItem. Checked: = True;

with Image do begin

AutoSize: = True; { восстановить нормальные размеры компонента}

Width: = Width div 2; { уменьшить ширину наполовину}

Height: = Height div 2; { уменьшить высоту наполовину}

end;

end;

procedure TPictureForm. NormalSizeItemClick ( Sender: TObject);

begin

NormalSizeItem. Checked: = True;

PopNormalSizeItem. Checked: = True;

Image. AutoSize: = True; { восстановить нормальные размеры компонента}

end;

 

procedure TPictureForm. DoubleSizeItemClick (Sender: TObject);

begin

DoubleSizeItem. Checked: = True;

PopDoubleSizeItem. Checked: = True;

with Image do begin

AutoSize: = True; { восстановить нормальные размеры компонента}

Width: = Width* 2; { удвоить ширину)

Height: = Height* 2; { удвоить высоту}

end;

end;

В первом приближении приложение для просмотра графических файлов готово. Скомпилируйте приложение и проверьте его работоспособность.

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

Вперед.