вторник, 24 июня 2014 г.

9. События формы. Лабораторные Delphi, C++ (5)

Основные события формы в Delphi и C++Builder

Здесь будут исследованы события формы, связанные с появлением формы на экране, переключением между формами одного приложения, закрытием и изменениями размера формы:
·          OnActivate. Возникает после того, как форма становится активной — при первоначальном запуске приложения или когда форма после потери фокуса вновь получает фокус.
·          OnDeactivate. Возникает при деактивации формы — при потере фокуса, когда клиент переключается на другую форму того же приложения.
·          OnClose. Возникает непосредственно перед закрытием формы, после события OnCloseQuery.
·          OnCloseQuery. Возникает до закрытия формы перед событием OnClose.
·          OnPaint. Возникает при прорисовке формы.
·          OnResize. Возникает при изменении размера формы.
·          OnShow. Возникает один раз при начальной загрузке формы.

Запустите на выполнение Delphi или C++Builder. Создайте новый проект, выбрав в меню File | New | VCL Forms Application - Delphi (File | New | VCL Forms Application – C++Builder).

Создание двух форм

Положите на форму две кнопки Button с заголовками Форма и Завершить и компонент ListBox. В компонент ListBox будут помещаться информационные сообщения программы.











Рис. 1. Главная форма
При отображении такой формы, если размеры будут изменяться пользователем, то компонент ListBox будет занимать неправильное положение на форме. Чтобы размеры этого компонента каждый раз соответствовали размеру формы (чтобы от каждого края компонента до ближайшего края формы расстояние оставалось одинаковым), нужно установить значения для свойства Anchors компонента ListBox. Раскройте это свойство, щелкнув мышью по символу + слева от имени компонента. По умолчанию компонент привязан к левому верхнему углу формы — в значение True установлены подсвойства akLeft и akTop. Следует также установить в True значения подсвойств akRight и akBottom.
(Свойство Anchors мы с вами рассмотрим несколько позже, когда будем говорить о других компонентах).
Запустите программу на выполнение. Изменяйте размеры формы. Компонент ListBox в любом случае будет занимать на форме соответствующее положение с теми же расстояниями от края формы.
Создайте новую форму. Свяжите первую форму со второй.
Дважды щелкните мышью по кнопке Форма. Напишите следующий обработчик вызова второй формы:
Delphi
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show();
end;
C++Builder
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Form2->Show();
}
Вторая форма вызывается в немодальном варианте.
Для второй кнопки Завершить напишите обработчик щелчка, где форма закрывается методом Terminate класса Application:
Delphi
Application.Terminate();
C++Builder
Application->Terminate();

Основные события формы

OnShow

Выделите мышью первую форму, перейдите на вкладку событий, щелкнув мышью по вкладке Events в окне Object Inspector. Найдите событие OnShow и дважды щелкните мышью справа от названия события. В появившейся заготовке введите текст:
Delphi
procedure TForm1.FormShow(Sender: TObject);
begin
  Application.MessageBox('Show', 'Test', MB_OK);
end;
C++Builder
void __fastcall TForm1::FormShow(TObject *Sender)
{
  Application->MessageBox(L"Show", L"Test", MB_OK);
}
Поскольку в RAD Studio по умолчанию используются строки с кодировкой Юникод, в случае C++Builder перед строковым литералом в функции MessageBox нужно указать символ L.
Событие OnShow возникает перед первым появлением формы на экране. Чтобы отобразить факт возникновения этого события используется метод MessageBox объекта Application.
Запустите программу на выполнение. До того, как на экране появится сама форма, будет выдано сообщение:








Рис. 2. Сообщение о начале работы программы

OnActivate/OnDeactivate

Событие OnActivate возникает после того, как форма становится активной — при первоначальном запуске приложения или когда форма после потери фокуса вновь получает фокус, если пользователь перемещается между разными формами одного и того же приложения. Создайте следующий обработчик этого события:
Delphi
procedure TForm1.FormActivate(Sender: TObject);
begin
  ListBox1.Items.Add('FormActivate');
end;
C++Builder
void __fastcall TForm1::FormActivate(TObject *Sender)
{
  ListBox1->Items->Add("FormActivate");
}
Здесь в компонент ListBox помещается строка, информирующая о произошедшем событии.
Событие OnDeactivate возникает при деактивации формы — при потере фокуса, когда пользователь переключается на другую форму того же приложения. Для этого события напишите следующий обработчик:
Delphi
procedure TForm1.FormDeactivate(Sender: TObject);
begin
  ListBox1.Items.Add('FormDeactivate');
end;
C++Builder
void __fastcall TForm1::FormDeactivate(TObject *Sender)
{
  ListBox1->Items->Add("FormDeactivate");
}
Запустите программу на выполнение. Вызовите вторую форму, щелкнув по кнопке Форма. Переключайтесь с одной формы этого приложения на другую. В текстовом окне будут отображаться события активации/деактивации.

OnCloseQuery, OnClose

Событие OnCloseQuery возникает до закрытия формы непосредственно перед событием OnClose. Обработчику передается в виде параметра объект CanClose класса bool. Задавая в обработчике этого события свойству CanClose значение false, можно отменить закрытие формы. Значением по умолчанию является true — форма может быть закрыта.
Напишите следующий обработчик события:
Delphi
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if (Application.MessageBox('Завершить работу?',
      'CloseQuery', MB_OKCANCEL) = mrOk) then
    CanClose := true
  else
    CanClose := false;
end;
C++Builder
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  if (Application->MessageBox(L"Завершить работу?",
      L"CloseQuery", MB_OKCANCEL) == mrOk)
    CanClose = true;
  else
    CanClose = false;
}
Здесь при попытке закрыть форму пользователю выдается запрос о необходимости закрытия формы. Если пользователь щелкает по кнопке OK, то происходит закрытие формы. Иначе форма не закрывается.
Однако при выполнении оператора
Application.Terminate();
Application->Terminate();
событие OnCloseQuery не возникает.








Рис. 3. Запрос на завершение работы программы
Напишите следующий обработчик события OnClose:
Delphi
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Application.MessageBox('FormClose', 'Test', MB_OK);
end;
C++Builder
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  Application->MessageBox(L"FormClose", L"Test", MB_OK);
}
Событие OnClose также не возникает в случае выполнения оператора
Application.Terminate();
Application->Terminate();

Другие простые события формы

Событие OnPaint возникает, когда необходимо выполнить прорисовку формы либо при изменении ее размеров в сторону увеличения, либо при появлении формы на экране. Событие OnResize возникает при любом изменении размера формы.
Напишите следующие обработчики для этих двух событий:
Delphi
procedure TForm1.FormPaint(Sender: TObject);
begin
  ListBox1.Items.Add('FormPaint');
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  ListBox1.Items.Add('FormResize');
end;
C++Builder
void __fastcall TForm1::FormPaint(TObject *Sender)
{
  ListBox1->Items->Add("FormPaint");
}

void __fastcall TForm1::FormResize(TObject *Sender)
{
  ListBox1->Items->Add("FormResize");
}
Выполните программу, изменяйте размеры формы. Событие OnPaint возникает при прорисовке формы. Это событие будет происходить в самом начале выполнения программы, а также при изменении размеров формы в сторону увеличения. OnResize появляется при начальном запуске программы и при любом изменении размера формы.




3 комментария:

  1. Почему в обработчиках событий OnActivate/OnDeactivate нельзя вы вызать методы Hide/Show для других форм того же приложения?

    ОтветитьУдалить
  2. Я в подобных случаях использую свойство Visible других форм. Все работает прекрасно.

    ОтветитьУдалить
  3. Did you hear there's a 12 word sentence you can communicate to your crush... that will induce intense feelings of love and instinctual attraction to you deep within his heart?

    Because deep inside these 12 words is a "secret signal" that triggers a man's instinct to love, adore and look after you with his entire heart...

    12 Words Will Fuel A Man's Love Response

    This instinct is so built-in to a man's mind that it will drive him to work better than before to make your relationship as strong as it can be.

    In fact, triggering this dominant instinct is so binding to getting the best ever relationship with your man that the second you send your man one of these "Secret Signals"...

    ...You'll soon notice him open his soul and mind to you in a way he haven't expressed before and he'll perceive you as the one and only woman in the galaxy who has ever truly appealed to him.

    ОтветитьУдалить