МегаПредмет

ПОЗНАВАТЕЛЬНОЕ

Сила воли ведет к действию, а позитивные действия формируют позитивное отношение


Как определить диапазон голоса - ваш вокал


Игровые автоматы с быстрым выводом


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


Целительная привычка


Как самому избавиться от обидчивости


Противоречивые взгляды на качества, присущие мужчинам


Тренинг уверенности в себе


Вкуснейший "Салат из свеклы с чесноком"


Натюрморт и его изобразительные возможности


Применение, как принимать мумие? Мумие для волос, лица, при переломах, при кровотечении и т.д.


Как научиться брать на себя ответственность


Зачем нужны границы в отношениях с детьми?


Световозвращающие элементы на детской одежде


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


Как слышать голос Бога


Классификация ожирения по ИМТ (ВОЗ)


Глава 3. Завет мужчины с женщиной


Оси и плоскости тела человека


Оси и плоскости тела человека - Тело человека состоит из определенных топографических частей и участков, в которых расположены органы, мышцы, сосуды, нервы и т.д.


Отёска стен и прирубка косяков Отёска стен и прирубка косяков - Когда на доме не достаёт окон и дверей, красивое высокое крыльцо ещё только в воображении, приходится подниматься с улицы в дом по трапу.


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

От создания до уничтожения





 

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

propertyOnCreate: TNotifyEvent;

 

В табл. 9.3 приведена последовательность событий, возникающих при создании и выводе на экран новой формы.

 

Таблица 9.3. Основные события класса Tform

Собятия Описания
OnCreate() Создание формы. Обычно этот обработчик события используется для инициализации глобальных переменных формы и других подготовительных операций, необходимых для дальнейшей работы с формой.
OnShow() Форма с секунды на секунду будет выведена на экран. Событие происходит после вызова метода Show() или ShowModal() или присвоения свойству Visible формы значение true.
OnCanResize() Событие возникает перед изменением размера формы. Форма проверяет корректность своих новых размеров.
OnResize() Событие инициируется сразу после изменения размеров формы.
OnActivate() Форма становится ативной
OnPaint() Осуществляется перерисовка формы.

 

Особый интерес представляет событие, возникающее при перерисовке формы:

propertyOnPaint: TNotifyEvent;

 

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

В череде событий перерисовки всех размещенных на форме элементов управления событие OnPaint() формы вызывается первым.

. . .

Public

BitMap:TBitMap;

end;

varForm1: TForm1;

Implementation

{$R *.DFM}

procedureTForm1.FormCreate(Sender: TObject);

Begin

BitMap:=TBitMap.Create;

BitMap.LoadFromFile('<Путь к растровому файлу .bmp>');

end;

procedureTForm1.FormPaint(Sender: TObject);

Begin

Form1.Canvas.Draw(0, 0, BitMap);

end;

procedureTForm1.FormClose(Sender: TObject; var Action: TCloseAction);

Begin

BitMap.Free;

end;

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

Не меньший интерес представляют события, возникающие при закрытии

формы. Для начала процесса закрытия формы необходимо вызвать метод:

procedureClose;

 

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

Таблица 9.4.События, сопровождающие процесс закрытия формы

События Описание
OnCloseQuery() Запрос разрешения на открытие формы.
OnClose() Форма закрывается.
OnDeactivate() Форма перестает быть активной.
OnHide() Форма скрывается с экрана.
OnDestroy() Форма уничтожена.

 

Перед закрытием формы производится вызов обработчика события:

propertyOnCloseQuery: TCloseQueryEvent;

typeTCloseQueryEvent = procedure(Sender: TObject; varCanClose: Boolean) of object;

 

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

procedureTForm1.FormCloseQuery(Sender: TObject; varCanClose: Boolean);

Begin

ifMemo1.Modified=true then

Begin

ifMessageDlg('Сохранить изменения в тексте?', mtConfirmation, [mbOk, mbCancel], 0) = mrOK then

Begin

//сохранение изменений в тексте

end elseCanClose := true;

end;

end;

 

Если форма получила разрешение на закрытие, далее генерируется событие:

propertyOnClose: TCloseEvent;

typeTCloseAction = (caNone, caHide, caFree, caMinimize);

TCloseEvent = procedure(Sender: TObject; varAction: TCloseAction) of object;

 

Изменяя значение переменной Action (табл. 9.5), программист может управлять поведением закрываемой формы.



 

Таблица 9.5. Варианты закрытия формы TCloseAction

 

Значение Описание
caNone Ничего не происходит.
caHide Форма не закрывается, а только становится невидимой. К данной форме приложение имеет полный доступ. Значение по умолчанию для SID-форм.
caFree Форма закрывается и освобождает занимаемые ресурсы.
caMinimize Вместо закрытия форма сворачивается. Значение по умолчанию для MDI-форм.

 

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

Action значение caFree. Только тогда будет вызвано событие:

 

propertyOnDestroy: TNotifyEvent;

 

При этом форма и все принадлежащие ей объекты удаляются из памяти

компьютера.

Изменение размеров

 

Оба обработчика событий, связанные с изменением размеров формы, унаследованы от класса Tcontrol:

propertyOnCanResize: TCanResizeEvent;

typeTCanResizeEvent = procedure(Sender: TObject; varNewWidth, NewHeight: Integer; varResize: Boolean) of object;

и

propertyOnResize: TNotifyEvent;

 

Событие OnCanResize возникает перед изменением размера формы, например при растягивании границ формы мышью, при разворачивании/сворачивании формы или изменении размеров формы программным методом. Данный обработчик события предоставляет возможность контролировать приемлемость новых размеров; он содержит четыре параметра (табл. 9.6).

 

Таблица 9.6.Параметры события OnCanResize()

 

Параметры Описание
Sender Элемент-источник сообщения.
NewWidth Предлагаемый размер по горизонтали.
NewHeight Предлагаемый размер по вертикали.
Resize Переменная, разрешающая (true) или запрещающая (false) установить новый размер.

 

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

формы по горизонтали, равный 200 пикселам:

procedureTForm1.FormCanResize(Sender: TObject; varNewWidth, NewHeight: Integer; varResize: Boolean);

Begin

Resize:=(NewWidth>=200); //false, если размер менее 200

end;

 

Событие OnResize() инициируется сразу после изменения размеров формы.

Как правило, событие используется для перераспределения компонентов,

расположенных на форме.

Быстрые клавиши

 

При изучении класса TWinControl мы встретились с тремя событиями клавиатуры: OnKeyDown(), OnKeyPress() и OnKeyUp(). У формы предусмотрено дополнительное событие, контролирующее нажатие пользователем быстрых клавиш:

 

propertyOnShortCut: TShortCutEvent;

TShortCutEvent = procedure(varMsg: TWMKey; varHandled: Boolean) of object;

 

В очередности событий, связанных с работой на клавиатуре, OnShortCut() вызывается самым первым и поэтому успевает обработать комбинацию быстрых клавиш до того, как за дело берутся другие обработчики событий (как формы, так и элементов управления). Для того чтобы не допустить дальнейшую обработку быстрых клавиш в последующей цепочке событий, установите параметр Handled в true, тем самым вы укажете Windows, что обработка завершена. Параметр Msg соответствует стандартному сообщению Windows для обработки нажатия клавиши на клавиатуре.

Type

TWMKey = packed record

Msg : Cardinal;

CharCode : Word;

Unused : Word;

KeyData : Longint;

Result : Longint;

end;

 

Здесь параметр CharCode содержит код виртуальной клавиши (см. табл. 6.9

в главе 6). Параметр KeyData содержит дополнительную информацию: число

повторов данного сообщения, предыдущее состояние клавиши, состояние

дополнительных клавиш (таких как Alt, Ctrl). В поле Result будет записан результат обработки. Простейший пример использования данного обработчика события приведен ниже. Нажатие клавиши Esc (VK_ESCAPE) приведет к закрытию формы:

 

procedureTForm1.FormShortCut(varMsg: TWMKey; varHandled: Boolean);

Begin

ifMsg.CharCode=VK_ESCAPE thenClose;

end;

 

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

propertyKeyPreview:Boolean;

 

в значение true. Тогда активная форма (окно) обладала приоритетом при обработке нажатия клавиш.

procedureTForm1.FormKeyDown(Sender: TObject; varKey: Word; Shift: TShiftState);

Begin

ifssCtrl inShift then{если нажата клавиша Ctrl}

caseKey of

VK_UP : Form1.Top:=Form1.Top-1;

VK_DOWN : Form1.Top:=Form1.Top+1;

VK_LEFT : Form1.Left:=Form1.Left-1;

VK_RIGHT : Form1.Left:=Form1.Left+1;

end;

end;

 

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

Интерфейсы SDI и MDI

 

Операционная система Windows предоставляет возможность разрабатывать

приложения в одной из двух разновидностей интерфейса:

SDI (Single Document Interface) – однодокументный интерфейс.

MDI (Multiple Document Interface) – многодокументный интерфейс.

Каждый из указанных стилей интерфейса обладает своими уникальными

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

Чтобы далеко не ходить за примером,

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

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

Windows). Для этого в строке ввода

Открыть надо набрать команду Sysedit

(рис. 9.5) и нажать кнопку ОК.

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

Как я и обещал, перед вами появилось

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

привязаны к главной форме проекта

и могут свободно разгуливать по всему пространству рабочего стола. В качестве примера классического приложения SDI может выступать Delphi. Главным окном Delphi служит форма, на

которой расположены главное меню, палитра компонентов и «быстрые» кнопки. Остальные окна (окна проекта, Инспектор объектов и др.) являются дочерними.

 

Построение проекта MDI

 

Для того чтобы сообщить Delphi о своем намерении построить приложение

с интерфейсом MDI, первым делом установите отвечающее за тип формы свойство FormStyle главной формы проекта в значение fsMDIForm. Тем самым вы назначите родительское окно приложения. Для всех остальных дочерних форм проекта свойство FormStyle должно соответствовать значению fsMDIChild.

Если свойство FormStyle дочернего окна по-прежнему установлено в значение fsNormal, то поведение дочернего окна будет соответствовать поведению окна приложения SDI. Вне зависимости от стиля интерфейса любое приложение обязано обладать главным окном. Все остальные окна являются дочерними. Главное окно определяется в момент разработки приложения, и по умолчанию таковым становится самое первое окно – Form1. При желании назначить главным окном другую форму проекта на-

до воспользоваться пунктом меню ProjectOptions.

Одновременно с изучением особенностей приложения с интерфейсом MDI

в качестве примера работы мы попробуем написать упрощенный аналог утилиты Sysedit. Для этого создадим новый проект и в инспекторе объектов изменим имя и стиль главной формы:

Имя главной формы: Name=frmMain

Стиль главной формы: FormStyle= fsMDIForm

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

Имя дочерней формы: Name = frmChild

Стиль формы: FormStyle = fsMDIChild

Выберите пункт меню File → Save для того, чтобы сохранить проект. В ответ

на запрос мастера сохранения укажите названия исходных файлов проектов. Модуль главной формы назовите main.pas, дочерней формы – child.pas.

головной файл проекта предлагаю назвать mysysed.dpr. Теперь смело запустите проект на выполнение.

Обратите внимание на обещанную особенность приложения с интерфейсом

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

границы. А вот еще один нюанс: попробуйте закрыть дочернюю форму. Получилось? Вместо того чтобы исчезнуть, дочерняя форма просто свернулась и «упала» вниз главной формы. Почему? Перечитайте информацию о событии OnClose(): все определяется значением переменной Action : TCloseAction. Для дочерней формы приложения MDI значение по умолчанию – caMinimize (вместо уже привычного нам caHide).

Теперь для того чтобы, например, уничтожить дочернюю форму, ее обработчик события OnClose() должен выглядеть примерно так:

 

procedureTfrmChild.FormClose(Sender: TObject; varAction: TCloseAction);

Begin

Action := caFree;

end;

Для того чтобы при старте приложения избежать автоматического создания дочерней формы, выберите пункт меню Project → Options и в открывшемся диалоговом окне на вкладке Forms перенесите форму frmChild из списка автоматически создаваемых форм в раздел доступных форм (рис. 9.7).

Каким образом можно создать

новую дочернюю форму? Все достаточно просто: вызываем из кода модуля главной формы конструктор дочерней формы:

unitmain;

Implementation

usesChild;

procedure

varnewChild : TFrmChild;

Begin

newChild:=TFrmChild.Create(Application);

end;

 

Но не забудьте, что главная форма проекта (а точнее соответствующий ей

модуль main) нуждается в ссылке на дочернюю форму. Поэтому в начале раздела реализации модуля main.pas мы предупреждаем компилятор о том, что намерены использовать модуль child.pas. Вернемся к нашему примеру. Поместите на дочернюю форму многострочный текстовый редактор TMemo и его свойству Align присвойте значение alClient. В обработчике события OnShow главной формы проекта напишите следующие строки кода:

 

procedureTFrmMain.FormShow(Sender: TObject);

varnewChild : TFrmChild;

Begin

newChild:=TFrmChild.Create(Application);

NewChild.Memo1.Lines.LoadFromFile('c:\autoexec.bat');

NewChild.Caption:='Autoexec.bat';

newChild:=TFrmChild.Create(Application);

NewChild.Memo1.Lines.LoadFromFile('c:\config.sys');

NewChild.Caption:='Config.sys';

end;

 

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

информирующих нас о содержимом файлов Autoexec.bat и Config.sys.

Ненадолго вернемся к теории. В классе TForm предусмотрен ряд свойств и методов, специализирующихся именно на приложениях с интерфейсом MDI.

Например, родительское окно приложения MDI всегда обладает информацией о количестве созданных дочерних окон:

propertyMDIChildCount: Integer;

 

Доступ ко всем созданным дочерним окнам можно получить из массива величин типа Tform:

propertyMDIChildren[I: Integer]: TForm;

 

Дочерние окна заносятся в массив в порядке их создания. Если какое-то

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

 

procedure

varI : integer;

Begin

fori:=0 tofrmMain.MDIChildCount-1 do

iffrmMain.MDIChildren[i].Caption='Новый документ'

thenfrmMain.MDIChildren[i].WindowState:=wsMinimized;

end;

Код приведенного листинга позволяет среди всех дочерних окон обнаружить

формы, в заголовке которых написано «Новый документ», и свернуть их.

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

 

propertyActiveMDIChild: TForm;

 

Если у родительского окна в настоящий момент нет дочерних окон (свойство

MDIChildCount=0), свойство ActiveMDIChild вернет значение nil. Ряд методов главного окна решает задачи, связанные с размещением и упорядочиванием дочерних окон в своей клиентской области. Для выравнивания значков свернутых дочерних окон предназначен метод:

procedureArrangeIcons;

 

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

procedureCascade;

 

Процедура позволяет упорядочить окна таким образом, что пользователь

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

procedureTile;

 

Метод Tile сотрудничает со свойством:

 

propertyTileMode: TTileMode;

typeTTileMode = (tbHorizontal, tbVertical);

 

Код приведенного ниже примера упорядочит дочерние окна по горизонтали:

procedure

Begin

TileMode:= tbHorizontal;

Tile;

end;

 

Для перемещения по дочерним формам предназначены два метода:

procedureNext; //активизировать следующую форму

procedurePrevious; //активизировать предыдущую форму

 

Названия процедур говорят сами за себя: процедура Next() выбирает следующее окно, а Previous() возвращается к предыдущему. Напомню, что к текущему окну можно обратиться при помощи свойства ActiveMDIChild.

 

Интерфейс SDI

 

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

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

Delphi. Это классический пример интерфейса SDI. Корпорация Microsoft

как законодатель мод также постепенно снижает долю приложений с многодокументным интерфейсом. Например, все приложения из пакетов Microsoft Office 2000 и XP работают в режиме SDI.

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

может упорядочивать свои дочерние окна на экране. Но главная отличительная черта проекта SDI в том, что все формы проекта (как главная, так и подчиненные) создаются со стилем FormStyle = fsNormal. Благодаря этому дочерние формы проекта могут свободно «бродить» за пределами клиентской области главной формы. В результате у пользователя создается впечатление, что все экранные окна приложения имеют равные права.

Выбор интерфейса будущего программного продукта – индивидуальное право программиста, определяемое его личными предпочтениями. Здесь трудно дать однозначный совет. Скажу одно: на мой взгляд, интерфейс MDI целесообразно применять в проекте, предназначенном для одновременной работы с несколькими однотипными документами. Интерфейс SDI более универсален и может использоваться во всех остальных проектах.





©2015 www.megapredmet.ru Все права принадлежат авторам размещенных материалов.