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

DiVM / OOP / 12_116608_1_51491

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

OnRestore — происходит, когда пользователь восстанавливает свернутую программу.

OnSettingChange — происходит при изменении настроек операционной системы, например, настроек экрана или региональных настроек.

OnShortCut — происходит при нажатии клавиш на клавиатуре (еще до того, как в форме происходит событие OnKeyDown).

OnShowHint — происходит непосредственно перед появлением любой всплывающей подсказки.

Из всех методов объекта Application мы упомянем лишь один — Terminate. Он выполняет штатное завершение приложения. Запомните, метод Terminate не вызывает немедленного завершения приложения, давая возможность всем формам корректно себя закрыть. Во время закрытия форм свойство Terminated имеет значение True.

При необходимости на помощь объекту Application спешат менее значительные “персоны”: объекты Screen, Printer и Clipboard. Они также являются глобальными и создаются автоматически при запуске приложения (если, конечно, подключены стандартные модули, где они расположены).

7.7.2. Screen — объект, управляющий экраном

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

Width и Height — ширина и высота экрана в пикселях.

ActiveForm — активная форма (та, которая в текущий момент находится в фокусе ввода). ActiveControl — указывает компонент, который обладает фокусом ввода в активной форме. Cursor — управляет внешним видом указателя мыши для всех форм приложения. Cursors — список доступных указателей мыши.

DataModuleCount — количество модулей данных, созданных приложением. Модуль данных

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

DataModules — список всех модулей данных, созданных приложением.

DesktopWidth и DesktopHeight — ширина и высота виртуального экрана (используется, когда к компьютеру подключено несколько мониторов).

DesktopLeft и DesktopTop — позиция виртуального экрана на экране монитора. DesktopRect — координаты виртуального экрана.

Fonts — список всех поддерживаемых шрифтов. FormCount — количество форм, созданных приложением. Forms — список всех форм, созданных приложением. HintFont — шрифт всплывающих подсказок.

IconFont — шрифт подписей к значкам. MenuFont — шрифт текста в меню.

MonitorCount — количество мониторов, подключенных к компьютеру.

251

Monitors — список всех мониторов, подключенных к компьютеру. PixelsPerInch — количество пикселей в одном дюйме экрана монитора.

WorkAreaWidth и WorkAreaHeight — ширина и высота рабочей области экрана (не включает панель задач). Если к компьютеру подключено несколько мониторов, то рассчитывается ширина и высота рабочей области на основном мониторе.

WorkAreaLeft и WorkAreaTop — позиция рабочей области на экране монитора. WorkAreaRect — размеры и позиция рабочей области на экране монитора.

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

Screen.Cursor := crHourGlass; try

{ Длительная операция } finally

Screen.Cursor := crDefault; end;

7.7.3. Mouse — объект, представляющий мышь

Вряд ли сейчас можно встретить компьютеры без миниатюрного “хвостатого” устройства, называемого мышью. Для работы с ним в среде Delphi есть специальный объект Mouse: TMouse, автоматически добавляемый в программу при подключении модуля Controls. Перечислим наиболее важные свойства этого объекта:

Capture — содержит описатель окна, захватившего мышь для монопольного использования (это объект операционной системы Windows).

CursorPos — позиция указателя мыши.

DragImmediate — определяет, когда начинается буксировка: значение True — немедленно, значение False — после того, как указатель мыши переместиться на DragThreshold позиций при удерживаемой кнопке мыши.

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

IsDragging — проверяет, идет ли в данный момент процесс буксировки. MousePresent — проверяет, подключена ли мышь к компьютеру. WheelPresent — проверяет, есть ли у мыши колесико.

WheelScrollLines — количество логических строк, на которые смещается страница при прокрутке колесика мыши на один шаг.

7.7.4. Printer — объект, управляющий принтером

Большинство программ выводят некоторый текст или рисунки на печатающее устройство. Для этого полезного дела в среде Delphi имеется специальный объект Printer. Он становится доступен после подключения модуля Printers. Если вы включите этот модуль в проект, сразу после старта будет порожден объект Printer класса TPrinter. Его свойства и методы дают вам весьма неплохие возможности для печати из приложения на все виды принтеров. Однако, тема эта заслуживает отдельной главы (см. гл. 10).

7.7.5. Clipboard — объект, управляющий Буфером обмена

Каждый, кто работал с текстом, знает, какая это великолепная штука — Буфер обмена (Clipboard). Напомним, что это буфер, куда можно что-то положить (например, текст или рисунок), а потом взять это оттуда. За операции с Буфером обмена в среде Delphi отвечает

252

глобальный объект Clipboard класса TClipboard. Он расположен в модуле Clipbrd. О том, как объект Clipboard используется практически, подробно рассказано в гл. 8.

7.8. Итоги

Время потрачено не зря! Вы узнали о проекте все:

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

как открывать, сохранять, выполнять проект и управлять им с помощью окна Project Manager;

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

что есть компонент, откуда его взять, куда поместить, как навести порядок в группе компонентов;

кто управляет приложением изнутри (объект Application) и кто ему в этом помогает

(объекты Screen, Printer, Clipboard).

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

Глава 8. Меню, строка состояния и панель инструментов

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

8.1. Меню

8.1.1. Идея меню

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

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

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

контекстное меню формы или компонента.

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

253

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

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

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

8.1.2. Главное меню

Шаг 1. Приступая к практической работе, создайте новое приложение. Как это сделать, вы уже знаете. Поскольку в качестве примера мы решили разработать приложение для просмотра графических файлов, давайте назовем форму PictureForm (значение свойства Name), и дадим ей заголовок Picture Viewer (значение свойства Caption).

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

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

Рисунок 8.1. Компонент MainMenu

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

Свойство

Описание

 

 

AutoHotKeys

Значение maAutomatic избавляет программиста от

 

необходимости назначать пунктам меню "горячие"

 

клавиши (с помощью специального символа & в тексте

 

пунктов); компонент автоматически подбирает

 

"горячие" клавиши. Значение maManual требует,

 

чтобы "горячие" клавиши назначил программист (см.

 

параграф 8.1.3).

AutoLineReducti

Если равно значению maAutomatic, то при

on

отображении меню идущие подряд пункты-

 

разделители рисуются как один разделитель, а пункты-

 

разделители, находящиеся в начале или конце меню

 

вообще не показываются. Свойство AutoLineReduction

254

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

AutoLineReduction равно значению maManual, то все пункты меню рисуются как есть.

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

Images Список значков, отображаемых рядом с пунктами меню. Свойство Images используется совместно со свойством ImageIndex компонентов MenuItem (см. параграф 8.1.12).

Items

Массив пунктов меню.

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

OnMeasureItem и OnDrawItem. Событие

OnMeasureItem происходит в пункте меню, когда рассчитываются размеры пункта. Событие OnDrawItem происходит в пункте меню, когда пункт рисуется на экране. Если свойство OwnerDraw равно значению False, то пункты меню имеют стандартный вид и события OnMeasureItem и OnDrawItem не происходят.

OnChange

Происходит при изменении структуры меню.

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

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

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

8.1.3. Дизайнер меню

Вызов дизайнера меню осуществляется с помощью команды Menu Designer…, которая находится в контекстном меню компонента MainMenu (рисунок 8.2).

255

Рисунок 8.2. Вызов дизайнера меню (Menu Designer)

Шаг 3. Выберите показанную на рисунке команду Menu Designer… и на экране появится окно с заголовком PictureForm.MainMenu. Это и есть дизайнер меню.

Рисунок 8.3. Дизайнер меню (Menu Designer)

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

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

256

происходить по комбинации клавиш Alt+F. Заметим, что в некоторых версиях операционной системы Windows «горячие» клавиши подчеркиваются только после нажатия клавиши Alt.

Рисунок 8.4. Текст пункта меню

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

(&) из свойства Caption компонента FileMenuItem и убедитесь, что в компоненте

MainMenu свойство AutoHotKeys установлено в значение maAutomatic.

Шаг 5. Сейчас под пунктом File нужно создать подчиненное меню со списком команд. Для этого просто щелкните в дизайнере меню на пункте File, среда Delphi все сделает за вас. Под пунктом File появится пустая ячейка — заготовка первого пункта выпадающего списка. Выберите этот пункт с помощью мыши и дайте ему программный идентификатор OpenMenuItem (свойство Name), а в свойстве Caption впишите текст Open... . Вместо пустой ячейки появится текст Open... и пустая ячейка переместится ниже.

Шаг 6. Действуя по аналогии, добавьте еще три пункта: Save As... , Close и Exit. В

программе они должны называться SaveAsMenuItem, CloseMenuItem и ExitMenuItem

соответственно.

257

Рисунок 8.5. Пункты в меню File

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

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

 

Рисунок 8.6. Контекстные команды в дизайнере меню

 

 

Команда

Описание

 

 

Insert

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

Delete

Удаляет выбранный пункт.

258

Create Submenu

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

Select Menu

 

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

 

 

меню.

Save As Template

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

 

 

шаблонов.

Insert

From

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

Template

 

 

Delete Templates

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

Insert

From

Вставляет меню из файла с описанием меню

Resource

 

(расширение MNU) или из стандартного файла

 

 

ресурсов (расширение RC).

Таблица 8.2. Контекстные команды в дизайнере меню

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

8.1.4. Пункты меню

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

Свойство

Описание

 

 

 

 

 

 

Action

Задает так называемую команду, которая будет

 

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

 

список команд содержится в компоненте ActionList

 

(см. параграф 8.6).

 

 

 

AutoCheck

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

 

автоматически приводит к изменению значения

 

свойства Checked на противоположное. Если равно

 

значению False, то изменением свойства Checked

 

управляет программист.

 

 

 

AutoHotkeys

Значение maAutomatic избавляет программиста от

 

необходимости назначать пункту меню "горячую"

 

клавишу (с помощью специального символа & в

 

тексте пункта); компонент автоматически подбирает

 

"горячую" клавишу. Значение maManual требует,

 

чтобы "горячую" клавишу назначил

программист

 

(см. параграф 8.1.3). Значение maParent показывает,

 

что

способ

назначения

горячей

клавиши

 

определяется

"родительским"

компонентом

 

MainMenu.

 

 

 

 

259

AutoLineReduction

Если равно значению maAutomatic, то при

 

отображении меню подряд идущие пункты-

 

разделители рисуются как один разделитель, а

 

пункты-разделители, находящиеся в начале или

 

конце меню вообще не показываются. Свойство

 

AutoLineReduction

применяется при программном

 

добавлении и удалении пунктов меню, чтобы

 

избежать

нежелательных

явлений

вроде

 

повторяющихся и повисших разделительных линий.

 

Если свойство AutoLineReduction равно значению

 

maManual, то все пункты меню отображаются как

 

есть. Если свойство равно значению maParent, то

 

способ определяется “родительским” компонентом

 

(например, MainMenu).

 

 

 

 

Bitmap

Значок, который отображается рядом с текстом

 

пункта меню. Если для данного пункта меню указан

 

индекс значка с помощью свойство ImageIndex, то

 

значение свойства Bitmap игнорируется. Значки в

 

пунктах меню более подробно расмотрены в

 

параграфе 8.1.12.

 

 

 

 

 

Break

Если равно mbBreak или mbBarBreak, то пункт

 

меню начинает новый столбец. Значение

 

mbBarBreak обеспечивает отделение нового столбца

 

от предыдущего вертикальной чертой.

 

Caption

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

 

 

 

Checked

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

 

метку в виде "птички".

 

 

Default

Значение True говорит о том, что выбор пункта

 

меню можно осуществить

двойным

щелчком

 

"родительского" пункта меню.

 

 

Enabled

Определяет, доступен ли пользователю данный

 

пункт меню.

 

 

 

GroupIndex

Работает по-разному в зависимости от того,

 

находится пункт в подчиненном меню или в строке

 

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

 

одинаковым положительным значением GroupIndex

 

согласовано переключают между собой метку —

 

установка у одного пункта свойства Checked в

 

значение True снимает метку с другого пункта.

 

В MDI-формах свойство GroupIndex работает по-

 

другому. Пункты главного меню, находящиеся в

 

дочерней форме MDI, сливаются с пунктами

 

главного меню обрамляющей формы MDI при

 

активизации дочерней формы. При этом если в

 

строке

главного

меню обрамляющей

формы

260