Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/35: Рейтинг темы: голосов - 35, средняя оценка - 4.83
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
1

Как обращаться к программно создаваемой форме

04.03.2015, 16:12. Показов 6785. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите пожалуйста.
Есть код - создание формы:
Delphi
1
2
3
4
5
6
procedure TForm1.Button1Click(Sender: TObject);
begin;
Form2:= TForm2.Create(Application);
Form2.Caption:= 'Новое сообщение';
form2.Show;
end.
Если несколько раз подряд нажимаем Button1 получаем несколько форм.
Вопрос в следующем: как обращаться к этим формам ?
Пробовал по свойству Name: ... FormN.Name ..... но при изменении имени какой-нибудь одной формы, я всё равно могу обратиться к ней по старому имени. В общем это не правильно.
Т.е. какое свойство есть у формы, которое позволяет её идентифицировать ?
Какие значения получает это свойство при программном создании форм ?

Добавлено через 3 минуты
Насколько я понял, после просмотра форумов, нужно делать список LIST и хранить имена форм. Еще один вариант - это с классами. Но в объектно-ориентированное программирование пока лезть не хочу (попозже). Как можно решить данный вопрос без ООП.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.03.2015, 16:12
Ответы с готовыми решениями:

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

Как программно создать объект на другой форме?
Добрый вечер! Есть код, который должен создать компонент Lbl на другой форме(form4,lbl на ней...

Как программно послать сообщение форме, о нажатой клавише?
Например, с такими параметрами "message = WM_KeyDown, wParam = VK_UP".

Как закрыть окно MessageBox программно в скрытой форме без закрытия программы
Я скачал исходники многопользовательского чата и решил их переделать под другие цели. Отправка...

20
Native x86
Эксперт Hardware
5605 / 3348 / 952
Регистрация: 13.02.2013
Сообщений: 10,619
04.03.2015, 16:21 2
Цитата Сообщение от serg55 Посмотреть сообщение
нужно делать список LIST и хранить имена форм
Не имена, а ссылки на них:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
type
  TForm1 = class(TForm)
  ...
  private
    FForms: TList;
  public
    { Public declarations }
  end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  FForms:= TList.Create;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i:= 0 to FForms.Count-1 do 
    TForm2(FForms[i]).Free;
  FForms.Free;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Form2: TForm2;
begin;
  Form2:= TForm2.Create(Application);
  Form2.Caption:= 'Новое сообщение';
  Form2.Show;
  FForms.Add(Form);
  // после этого созданная форма доступна как TForm2(FForms[x]), где x -- номер по порядку.
  // цикл по всем ранее созданным формам выглядит так: for i:= 0 to FForms.Count-1 do TForm2(FForms[i])....
end.
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
04.03.2015, 17:15  [ТС] 3
Спасибо !
Цитата Сообщение от quwy Посмотреть сообщение
FForms.Add(Form);
Наверное Form2 ?
Цитата Сообщение от quwy Посмотреть сообщение
FForms.Add(Form2);
0
Native x86
Эксперт Hardware
5605 / 3348 / 952
Регистрация: 13.02.2013
Сообщений: 10,619
04.03.2015, 18:36 4
Цитата Сообщение от serg55 Посмотреть сообщение
Наверное Form2 ?
Да, конечно.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
04.03.2015, 19:24 5
Цитата Сообщение от serg55 Посмотреть сообщение
Delphi
1
Form2:= TForm2.Create(Application);
Здесь для формы Form2 владельцем (Owner) назначается объект Application. Соответственно, Application содержит сведения о всех компонентах, в том числе и формах, для которых он назначен владельцем.
Пример:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TForm1.Button1Click(Sender: TObject);
var
  i, Cnt : Integer;
  Cmp : TComponent;
  Form : TForm;
begin
  Memo1.Text := 'Список форм, для которых Application назначен владельцем:';
  Cnt := 0;
  for i := 0 to Application.ComponentCount - 1 do
  begin
    Cmp := Application.Components[i];
    if Cmp is TForm then
    begin
      Inc(Cnt);
      Form := Cmp as TForm;
      Memo1.Lines.Add('Form.Name = "' + Form.Name + '"');
    end;
  end;
  Memo1.Lines.Add('Application. Количество форм: ' + IntToStr(Cnt));
end;
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
04.03.2015, 22:05  [ТС] 6
Цитата Сообщение от Mawrat Посмотреть сообщение
Соответственно, Application содержит сведения о всех компонентах
Mawrat, вы хотели сказать, что обращаться с созданной формой нужно аккуратно, чтобы не задеть других потомков Application ?
0
пофигист широкого профиля
4755 / 3190 / 861
Регистрация: 15.07.2013
Сообщений: 18,471
04.03.2015, 22:16 7

Не по теме:

Цитата Сообщение от serg55 Посмотреть сообщение
обращаться с созданной формой нужно аккуратно
Конечно аккуратно, а то вдруг заденешь боком одной формы другую. Поломаешь обе. :)


Mawrat имел ввиду, что такой список уже есть. Зачем делать еще один?
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
05.03.2015, 00:10  [ТС] 8
Вот еще такой вопрос.
Если пишем вот так:
Цитата Сообщение от serg55 Посмотреть сообщение
var
Form2: TForm2;
procedure TForm1.Button1Click(Sender: TObject);
begin;
Form2:= TForm2.Create(Application);
Form2.Caption:=Form2.Name';
form2.Show;
end.
Создается форма повторяющая Form2. Её Name будет Form2_1. Если создавать далее - Form2_2, Form2_3 и т.д.
А если написать вот так:
Цитата Сообщение от serg55 Посмотреть сообщение
var
Form2:TForm;
procedure TForm1.Button1Click(Sender: TObject);
begin;
Form2:= TForm.Create(Application);
Form2.Caption:= Form2.Name;
form2.Show;
end.
Тогда поле Caption пустое. Что создается в этом случае ? Какое имя у формы ? Или этот код не корректен ?
0
пофигист широкого профиля
4755 / 3190 / 861
Регистрация: 15.07.2013
Сообщений: 18,471
05.03.2015, 00:34 9
Цитата Сообщение от serg55 Посмотреть сообщение
Какое имя у формы ?
А ты его разве задал? Вот когда задашь, тогда и будет у неё имя.
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
05.03.2015, 09:08  [ТС] 10
Цитата Сообщение от northener Посмотреть сообщение
А ты его разве задал?
Согласен, не задал. Но тогда я немного не понимаю. Все таки объясните, что является идентификатором формы при её создании ? Ведь если форма создана и есть на экране, значит у неё должно быть имя или другое свойство, которое даёт на неё ссылку.
Еще раз на примере. Если форма добавлена в проект но автоматически не создается, мы её создаем так:
Delphi
1
2
3
4
5
6
7
var
  FormNew:[B]TForm2[/B];
begin
  FormNew := [B]TForm2[/B].Create(Application);
  FormNew.Show;
  FormNew.Caption :=FormNew.Name;
end;
delphi сам присваивает имя форме - Form2_1 (производное от Form2) и создает её такого же вида как и Form2.

Теперь поменяем тип переменной FormNew:
Delphi
1
2
3
4
5
6
var
  FormNew:[B]TForm[/B];
begin
  FormNew := [B]TForm[/B].Create(Application);
  FormNew.Show;
end;
На экране появляется ПУСТАЯ форма. Значит у неё должно быть имя ? Я так думаю ? Пробуем посмотреть и поменять имя на новое, а затем обратиться по новому имени:
Delphi
1
2
3
4
5
6
7
8
9
10
var
  FormNew:TForm;
begin
  FormNew := TForm.Create(Application);
  FormNew.Show;
  FormNew.Name := 'Name1';
  Name1.Caption := Name1.Name;    <---
  Name1.Name := 'Name2';
  Name2.Caption := Name2.Name;
end;
компилятор ругается, сразу же при первом обращении по имени (пометил стрелкой).
Также я пробовал засунуть переменную FormNew в поле Edit (по подобию Memo) чтобы увидеть её значение, но тип FormNew не string. Как посмотреть "идентификатор" (имя) формы ?
0
пофигист широкого профиля
4755 / 3190 / 861
Регистрация: 15.07.2013
Сообщений: 18,471
05.03.2015, 10:20 11
Сcылку на вновь созданную форму возвращает конструктор Create.
Имя пользовательской формы задает сама Дельфи в дизайнере.
Не надо путать имя сомпонента (TComponent.Name) и имя переменной.
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
05.03.2015, 14:08  [ТС] 12
Цитата Сообщение от northener Посмотреть сообщение
Сcылку на вновь созданную форму возвращает конструктор Create.
А тип данных какой тут получается ?
Как бы вывести в Edit или Label эту информацию ?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
05.03.2015, 14:13 13
Тот самый тип и получается, метод Create которого ты вызвал
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
05.03.2015, 14:40  [ТС] 14
Т.е. в моем случае это тип TForm и просто посмотреть переменную, которая указывает мне на форму, т.е. посмотреть что она из себя представляет - число, строка или что-то другое, не получиться ?

Добавлено через 1 минуту
Может есть поле в TForm какое, с таким "идентификатором" формы ? Если сохранять это в TList, как потом посмотреть что хранит TList ?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
05.03.2015, 14:49 15
Цитата Сообщение от serg55 Посмотреть сообщение
просто посмотреть переменную, которая указывает мне на форму, т.е. посмотреть что она из себя представляет - число, строка или что-то другое
Эта переменная FormNew у тебя вполне конкретного типа - TForm.
И содержит она ссылку на объект (класса TForm), который тебе вернул конструирующий метод TForm.Create
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
06.03.2015, 10:28  [ТС] 16
Нашел инфу. Делфи предоставляет нам удобный инструмент. Она ведёт самостоятельно список всех открытых форм. Доступ к этому массиву получить легко. Количество открытых форм – Screen.FormCount. Обратиться к конкретной форме – Screen.Forms[индекс].
http://www.delphi.int.ru/articles/45/

Добавлено через 18 часов 13 минут
Вобщето Screen.FormCount не очень подходит. Индекс не всегда будет соответствовать конкретной форме. Пи закрытии формы индексы меняются. Например, закрываем форму 3, её нет, а индекс три есть и принадлежит уже другой форме. Придется делать TList.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
06.03.2015, 10:50 17
Цитата Сообщение от serg55 Посмотреть сообщение
Вобщето Screen.FormCount не очень подходит. Индекс не всегда будет соответствовать конкретной форме. Пи закрытии формы индексы меняются. Например, закрываем форму 3, её нет, а индекс три есть и принадлежит уже другой форме.
Так это хорошо, как раз. Потому, что содержимое списка соответствует действительности - содержит ссылки только на существующие формы.
Цитата Сообщение от serg55 Посмотреть сообщение
Придется делать TList.
Лучше пользоваться Screen.Forms. Если надо отличать формы по номерам, для этого можно использовать свойство TForm.Tag - в него записывать соответствующие номера.
0
2 / 2 / 1
Регистрация: 15.08.2014
Сообщений: 170
06.03.2015, 10:59  [ТС] 18
Цитата Сообщение от Mawrat Посмотреть сообщение
Потому, что содержимое списка соответствует действительности
тогда нужно следить за соответствием списка и форм, чтобы они не поехали относительно друг друга. Хотя я вывел счетчик в поле Edit и увидел что при закрытии форм (на крестик в шапке формы) он не уменьшается. Может нужно их правильно уничтожать просто ? Какой-нибудь деструктор использовать. Разберусь с этим.
Цитата Сообщение от Mawrat Посмотреть сообщение
Если надо отличать формы по номерам, для этого можно использовать свойство TForm.Tag - в него записывать соответствующие номера.
Спасибо за подсказку. Погуглю что за свойство такое и как его использовать.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
06.03.2015, 11:19 19
TForm.Tag - это просто целочисленное поле, которое можно использовать для своих нужд. Например, можно записывать порядковый номер, в данном случае.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
06.03.2015, 13:09 20
Цитата Сообщение от serg55 Посмотреть сообщение
Может нужно их правильно уничтожать просто ?
Жмаканье крестика на любой форме, кроме главной, по умолчанию не приводит к уничтожению этой формы - она просто становится невидимой и по-прежнему продолжает фигурировать в списке Screen.Forms
Для уничтожения формы следует обработать событие OnCloseQuery, установив в нем параметр Action равным acFree

Добавлено через 2 минуты
Цитата Сообщение от serg55 Посмотреть сообщение
Придется делать TList
А еще лучше (в XE-линейке) - TObjectList<TMyForm>.
0
06.03.2015, 13:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.03.2015, 13:09
Помогаю со студенческими работами здесь

Как генерировать класс создаваемой формы?
Как генерировать класс создаваемой формы?

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

Как обращаться к PictureBox созданным программно?
Тут они создаются. class Block { int l; int blockLength = 40; int...

Как обращаться к элементам созданным программно
Как обратиться к элементу, который добавлен кодом ? ComboBox comboBox4 = new ComboBox(); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru