Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

DiVM / OOP / 12_116608_1_51491

.pdf
Скачиваний:
27
Добавлен:
11.05.2015
Размер:
6.45 Mб
Скачать

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

Hint

Краткая подсказка для пользователя, отображаемая

 

в строке состояния.

 

 

 

ImageIndex

Номер значка в списке Images компонента

 

MainMenu. Значок отображается рядом с текстом

 

пункта меню (см. параграф 8.1.12). Отрицательное

 

значение свойства ImageIndex говорит о том, что

 

для пункта меню значок не задан. Свойство

 

ImageIndex имеет приоритет над свойством Bitmap.

RadioItem

Если равно значению True, то метка имеет вид

 

жирной точки.

 

 

 

 

ShortCut

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

 

открывая меню.

 

 

 

SubMenuImages

Список значков, отображаемых рядом с пунктами

 

подчиненного меню. Свойство SubMenuImages

 

используется совместно со свойством ImageIndex

 

компонентов MenuItem (см. параграф 8.1.12).

 

Visible

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

OnAdvancedDrawIt

Происходит при рисовании отдельно взятого пункта

em

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

 

случае, если

соответствующий

компонент

меню

 

(MainMenu или PopupMenu) содержит значение

 

True в свойстве OwnerDraw. Предоставляет более

 

широкие возможности по сравнению с событием

 

OnDrawItem.

 

 

 

 

OnClick

Происходит

при

выборе

пункта

меню

 

пользователем.

 

 

 

 

OnDrawItem

Происходит при рисовании отдельно взятого пункта

 

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

 

случае, если

соответствующий

компонент

меню

(MainMenu или PopupMenu) содержит значение True в свойстве OwnerDraw.

OnMeasureItem Происходит при расчете размеров отдельно взятого пункта меню перед его рисованием на экране. Событие происходит только в том случае, если соответствующий компонент меню (MainMenu или PopupMenu) содержит значение True в свойстве

261

OwnerDraw.

Таблица 8.3. Важнейшие свойства и события компонента MenuItem

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

Рисунок 8.7. Пункты меню в программном коде

8.1.5. Разделительные линии

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

262

Рисунок 8.8. Разделительная линия в меню

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

8.1.6. Комбинации клавиш

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

назначается комбинация клавиш Ctrl+O.

Шаг 8. Чтобы назначить пункту комбинацию клавиш, активизируйте пункт в дизайнере меню, перейдите к окну свойств и выберите в списке значений свойства ShortCut требуемую комбинацию клавиш (рисунок 8.9). Если ее там нет, то введите название комбинации клавиш вручную.

263

Рисунок 8.9. Комбинация клавиш для активизации пункта меню

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

8.1.7. Обработка команд меню

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

Шаг 9. Итак, активизируйте в дизайнере меню пункт Exit и выберите в окне свойств вкладку Events. Теперь сделайте двойной щелчок мышью на значении события OnClick (рисунок

8.10).

264

Рисунок 8.10. Создание обработчика команды меню

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

procedure TPictureForm.ExitMenuItemClick(Sender: TObject); begin

Close; end;

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

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

265

Рисунок 8.11. Проверка работы команды Exit

8.1.8. Пункты-переключатели

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

Шаг 10. В строке главного меню создайте выпадающее меню View с пунктами Toolbar

(программное имя ToolBarMenuItem) и Status bar (программное имя StatusBarMenuItem).

Установите в последних двух пунктах свойство Checked в значение True. В пунктах меню появятся метки (рисунок 8.12).

266

Рисунок 8.12. Пункты-переключатели в меню

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

procedure TPictureForm.ToolBarMenuItemClick(Sender: TObject); begin

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

ToolBarMenuItem.Checked := not ToolBarMenuItem.Checked; end;

procedure TPictureForm.StatusBarMenuItemClick(Sender: TObject); begin

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

StatusBarMenuItem.Checked := not StatusBarMenuItem.Checked; end;

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

8.1.9. Взаимоисключающие переключатели

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

Шаг 12. Добавьте в меню View три пункта: Half Size (программное имя HalfSizeMenuItem),

Normal Size (программное имя NormalSizeMenuItem) и Double Size (программное имя

DoubleSizeMenuItem), отделив их от остальных пунктов меню с помощью разделительной линии.

Шаг 13. Объедините только что созданные пункты меню в одну согласовано работающую группу. Для этого у всех пунктов установите одинаковое ненулевое значение свойства GroupIndex (например, 1). Кроме того, установите для всех этих пунктов свойство RadioItem в значение True, чтобы метка имела вид жирной точки. Один из пунктов (например, Normal Size) переведите во включенное состояние, установив его свойство Checked в значение True (рисунок 8.13).

267

Рисунок 8.13. Взаимоисключающие переключатели в меню

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

procedure TPictureForm.HalfSizeMenuItemClick(Sender: TObject); begin

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

HalfSizeMenuItem.Checked := True; end;

procedure TPictureForm.NormalSizeMenuItemClick(Sender: TObject); begin

// Показать рисунок нормального размера

NormalSizeMenuItem.Checked := True; end;

procedure TPictureForm.DoubleSizeMenuItemClick(Sender: TObject); begin

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

DoubleSizeMenuItem.Checked := True; end;

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

8.1.10. Недоступные пункты меню

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

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

(рисунок 8.14).

268

Рисунок 8.14. Недоступные пункты меню

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

EnableCommands:

type

TPictureForm = class(TForm)

...

private

{ Private declarations }

procedure EnableCommands(Enable: Boolean); end;

...

procedure TPictureForm.EnableCommands(Enable: Boolean); begin

SaveAsMenuItem.Enabled := Enable;

CloseMenuItem.Enabled := Enable; HalfSizeMenuItem.Enabled := Enable; NormalSizeMenuItem.Enabled := Enable; DoubleSizeMenuItem.Enabled := Enable;

end;

Параметр Enable данного метода определяет, в какое состояние перевести пункты меню: доступны — True или недоступны — False.

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

269

procedure TPictureForm.OpenMenuItemClick(Sender: TObject); begin

// Открыть рисунок и разрешить команды

EnableCommands(True); end;

procedure TPictureForm.CloseMenuItemClick(Sender: TObject); begin

// Закрыть рисунок и запретить команды

EnableCommands(False); end;

Выполните компиляцию и запустите программу. Посмотрите, как изменилось ее меню

(рисунок 8.15).

Рисунок 8.15. Меню работающей программы. Некоторые пункты недоступны.

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

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

8.1.11. Контекстное меню

Контекстное (вспомогательное) меню представлено в среде Delphi компонентом

PopupMenu (рисунок 8.16). Отыщите его в палитре компонентов на вкладке Standard и поместите на форму. Дайте новому компоненту имя PopupMenu.

Рисунок 8.16. Компонент PopupMenu

Прежде, чем перейти к практическому использованию контекстных меню, кратко опишем отличительные свойства компонента PopupMenu (таблица 8.4).

Свойство Описание

270