Блог Александра Божко
Архивы
Рубрики
Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

В своем блоге Александр Бондарь публикует своего рода методические пособие по RAD Studio. Дело это, безусловно, полезное с точки зрения популяризации Delphi, поэтому этот блог и включен в ленту новостей Delphifeeds.Ru. Хотя, наверняка, для большинства читателей сайта, работающих с Delphi/C++ Builder на практике, в этих постах интересного мало. В свое время у меня был некоторый педагогический опыт и опыт написания методических пособий. К сожалению, с тех пор минуло довольно много времени и найти их я не смог. Но на волне ностальгии, меня посетила мысль в своем блоге дополнить данное пособие, парочкой интересных,  на мой взгляд, кейсов. Не думаю, что для профессионалов здесь будут какие-то откровения, но для “продвинутых” студентов это может быть интересно.

Этимология форм

Если говорить о формах, то весьма важно разобраться с их сущностью. Понятно, что речь идет об объекте, но объект этот не совсем обычный. Начальные значения его свойств хранятся в специальных файлах форм. В случае VCL они имеют расширение *.dfm, если речь идет о FireMonkey, то *.fmx. Данные файлы можно отредактировать, как с использованием IDE, так и в обычном текстовом редакторе. В первом случае, достаточно в редакторе форм из контекстного меню выбрать пункт View as Text. Во втором случае следует найти файл с именем модуля, содержащего форму и расширением *.dfm или  *.fmx, и открыть его в текстовом редакторе. После этого, можно поменять какое-либо из свойств формы, например, Caption и, вернувшись в редактор формы,  посмотреть как изменится внешний вид формы. Заодно и поэкспериментировать с кодировками.

object fMain: TfMain
  Left = 0
  Top = 0
  Caption = #1053#1086#1074#1099#1081' '#1079#1072#1075#1086#1083#1086#1074#1086#1082
  ClientHeight = 299
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object btnStart: TButton
    Left = 520
    Top = 256
    Width = 75
    Height = 25
    Caption = 'Start'
    TabOrder = 0
    OnClick = btnStartClick
  end
  object ButtonedEdit1: TButtonedEdit
    Left = 24
    Top = 32
    Width = 273
    Height = 21
    TabOrder = 1
    Text = 'c:\change'
  end
  object Edit1: TEdit
    Left = 336
    Top = 32
    Width = 121
    Height = 21
    TabOrder = 2
    Text = '2setup_v_11_0_19'
  end
end

 Листинг 1. 

Редактор кода IDE достаточно оригинально преобразовывает русские символы в *.dfm файлах.

Задание стартовой формы и структура приложения

Кроме файла форм, в проекте присутствует файл проекта. Его можно увидеть вызвав пункт меню Project | View Source.

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

Здесь же нелишне упомянуть, что правильнее создавать формы динамически, а не использовать Auto-create forms. Соответственно, отключить создание по-умолчанию формы можно, как в коде проекта, так и в опциях проекта.

program setupCopy;

uses
  Vcl.Forms,
  uMain in 'uMain.pas' {fMain},
  uAdd in 'uAdd.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := False;
  Application.CreateForm(TForm1, Form1);  // Это форма будет главной
  Application.CreateForm(TfMain, fMain);  // Если эту строку закомментировать, форма не попадет в список Auto-create в опциях
  Application.Run;
end.

Листинг 2

События формы

Здесь, самое интересное, на мой взгляд, последовательность событий при загрузке формы. Для того, что бы наглядно отследить эту последовательность можно воспользоваться утилитой CodeSite, из-под пера Рея Конопки. В секции Uses главной формы приложения подключим модуль CodeSiteLogging, а в обработчик каждого из потенциально интересующих нас событий, впишем следующую строку

CodeSite.Send(<имя события>);

где укажем название обрабатываемого события. Примерно так:

procedure TForm1.FormActivate(Sender: TObject);
begin
 CodeSite.Send('FormActivate' );
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CodeSite.Send('FormClose' );
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CodeSite.Send('FormCloseQuery' );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 CodeSite.Send('FormCreate' );
end;

procedure TForm1.FormHide(Sender: TObject);
begin
CodeSite.Send('FormHide' );
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
   CodeSite.Send('FormPaint' );
end;

procedure TForm1.FormResize(Sender: TObject);
begin
CodeSite.Send('FormResize' );
end;

procedure TForm1.FormShow(Sender: TObject);
begin
CodeSite.Send('FormShow' );
end;

Результат будет выглядеть следующим образом:

FormCreate
FormShow
FormActivate
FormResize
FormPaint
FormCloseQuery
FormClose
FormHide
FormDestroy

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

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

Создадим, новое приложение, добавим еще одну форму.  Обе формы будут создаваться автоматически, так, как это есть по-умолчанию.   В секции Uses первой формы подключим вторую форму и в обработчике события onCreate попытаемся ее отобразить. В результате получим Access Violation. Иначе говоря, попытка обратиться к несуществующему объекту. Этот пример позволяет понять, в какой последовательности отрабатываются события в процессе запуска приложения.

Давайте еще раз посмотрим на код приложения  (Листинг 2).

OnCreate главной формы вызывается, что совершенно логично, в момент создания формы. В это время вторая форма еще не создана. Однако, отображение главной формы происходит в результате вызова метода Run, объекта Application. К этому моменту  вторая форма уже создана. Поэтому, если перенести вызов второй формы на обработчик события OnShow, все заработает.

И в заключение вопрос на сообразительность. Можно ли закрыть форму таким образом, что бы обработчик события OnClose не вызывался?

 


Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

5 комментариев: Еще немного о формах…

  • А можно я ещё вот такую ссылочку оставлю? :)
    http://www.delphinotes.ru/2013/03/form-events.html

    Там есть ссылка на exe-файл, я специально писал программку для того, чтобы легче осознать когда и какие события вызываются (ну кроме Resize и Paint, т.к. в них закладывать логику обработки ввода пользователя смысла нет).

    Спасибо.

  • Знаете – ХОРОШО написано. С ТОЛКОМ. Мне – НРАВИТСЯ. Но НЕПОНЯТНО – зачем. Неужто это всё НЕЛЬЗЯ прочесть в документации? Я не “наезжаю”.. Я правда спрашиваю.

    Я и про Бондаря могу сказать – он – МОЛОДЕЦ. НУЖНОЕ ДЕЛО делает. Но вот “уровень”. Правда ТАКОЙ нужен?

    Опять же – “без наездов”. Я Попытался рассказать про DUnit и Unit-тестирование. На основе примера, который предложил Всеволод Леонов. Мне и этот-то пример показался “примитивным”. Но ведь “оказывается”, что и это – “сложно”, что “надо бы про DUnit написать”. Так скажем “для чайников”. А надо ли? Без чтения документации – далеко ли мы уйдём? Или я чего-то не понимаю?

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

      а вот про dunit твой я вот что скажу. Это ведь взаимосвязано. использование dunit сложно именно для тех, кого старательно учили именно на таком уровне: “сегодня мы изучаем TForm”… Тьфу.

  • Это я всё к чему? Я ведь “могу” многое рассказать.. Если интересно, но как Тепляков или GunSmoker – писать не умею. Я всё “нащупываю” так скажем “аудиторию”. И не могу понять “планку”.

    “Сложно” писать – “не понимают”.
    “Просто” – “тривиально”.

    Или “забить”?

  • “О Формах” ведь тоже многое можно написать, один только вопрос мучает “а надо ли”?

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика