Практика
Создание компонентов в RunTime

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика


RunTime можно перевести как "время выполнения программы". Набросать компонентов на форму во время разработки программы может даже человек, очень далекий от программирования. Сложнее ему станет, если он захочет обработать события этих компонентов. А вот создать компонент в RunTime представится ему задачей невыполнимой. Однако, на самом деле, создавать компоненты в RunTime довольно просто. И сегодня мы в этом убедимся. Мы создадим не просто компонент, а небольшую форму с разными компонентами, и научимся обрабатывать их события.

Для создания формы нам понадобится переменная MyForm: TForm. Создадим форму: MyForm := TForm.Create( Self ). Теперь MyForm это форма, с которой можно делать все, что душе угодно. А нашей душе угодно получше эту форму оформить. Для этого проинициализируем некоторые ее свойства (MyForm.Width, MyForm.Height, MyForm.Caption и т.д.). После инициализации показываем форму: MyForm.ShowModal. На практике это будет выглядеть примерно так.

procedure TForm1.Button1Click(Sender: TObject);
begin
   // Создаем форму
   MyForm := TForm.Create( Self );
   // Создаем список TList - он пригодится нам в дальнейшем
   List := TList.Create;
   // Производим инициализацию
   MyForm.Caption := FormCaption.Text;
   MyForm.Width := 400;
   MyForm.Height := 250;
   MyForm.Position := poDesktopCenter;
   // Создаем обработчик формы OnClose
   MyForm.OnClose := MyFormClose;
   // Показываем форму
   MyForm.ShowModal;
end;

В этом примере мы создали обработчик события OnClose. Это сделано для того, чтобы после закрытия нашей формы список TList освобождался. Проще всего этот (и все другие) обработчик сделать следующим образом: создать обработчик OnClose для главной формы Form1, а затем просто переименовать его.

procedure TForm1.MyFormClose(Sender: TObject; var Action: TCloseAction);
begin
   List.Free;
end;

Теперь о списке TList, зачем он нужен? TList - это "объект-контейнер", который может хранить в себе кучу других объектов. Точнее сказать, он хранит только ссылки на эти объекты, но это не главное. Главное - TList позволяет хорошо управлять хранящимися в нём объектами. На форме мы будем создавать кнопки, для каждой из которых будем создавать обработчик события OnClick. Вернее сказать, обработчик будет один для всех созданных кнопок. При создании кнопки, мы поместим указатель на нее в список TList, а свойству Tag созданной кнопки присвоим ее индекс в списке TList. Что это за свойство Tag? Это просто целое значение, которое можно использовать по своему усмотрению. Это абсолютно не влияет на сам компонент, а этот индекс нам пригодится.

procedure TForm1.Button1Click(Sender: TObject);
begin
   MyButton := TButton.Create( MyForm );
   {...}
   MyButton.OnClick := ClickMyButtonClick;
   MyButton.Parent := MyForm;
   // Запоминаем индекс кнопки в списке
   MyButton.Tag := List.Add( MyButton );
end;

Обработчик OnClick для кнопки выглядит следующим образом.

procedure TForm1.ClickMyButtonClick(Sender: TObject);
begin
   ShowMessage( TButton( List.Items[TButton( Sender ).Tag] ).Caption );
end;

Здесь мы выводим Caption кнопки, по которой кликнули. Но как узнать, какая кнопка была нажата? Для этого воспользуемся TButton( Sender ).Tag (помните, в свойстве Tag мы сохраняли индекс кнопки в TList). Мы обращаемся к ячейке TList, индекс которой хранится в свойстве Tag, и получаем из этой ячейки указатель на кнопку, по которой щелкнули.

Иногда может понадобиться удалить один или несколько динамически созданных компонентов. Допустим мы создали на форме кнопку с заголовком "Del my".

procedure TForm1.FormCreate(Sender: TObject);
begin
   with TButton.Create( Self ) do
   begin
      Left := 10;
      Top := 10;
      Width := 80;
      Height := 22;
      Caption := 'Del my';
      Parent := Form1;
      Show;
   end;
end;

Для ее удаления напишем следующий код:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
   for i := Self.ComponentCount-1 downto 0 do
      if Components[i] is TButton then
         if TButton( Components[i] as TButton ).Caption = 'Del my' then
            Components[i].Free;
end;

Здесь мы в цикле перебираем все компоненты на форме, проверяя каждый найденный на принадлежность к классу TButton (if Components[i] is TButton). Если принадлежит, проверяем заголовок, и в случае совпадения удаляем кнопку.

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

.: Пример к данной статье :.


При использовании материала - ссылка на сайт обязательна