Неопределенное количество форм в рантайме.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Padre_Mortius
энтузиаст
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Сообщение Padre_Mortius »

OberonAR писал(а):А если сделать все таки 1 форму, а на ней pagecontrol с вкладками под каждую таблицу и при вызове делать visible:=true только нужной вкладке?

Тогда уж лучше пользоваться фреймами
Аватара пользователя
OberonAR
новенький
Сообщения: 73
Зарегистрирован: 08.02.2012 11:46:04
Откуда: Краснодарский край

Сообщение OberonAR »

Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

мой архиватор говорит что и этот архив не съедобен:
gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Exiting with failure status due to previous errors

а почему не можно прикрепить файл к сообщению или скинуть на файлопомойку :?:
Аватара пользователя
OberonAR
новенький
Сообщения: 73
Зарегистрирован: 08.02.2012 11:46:04
Откуда: Краснодарский край

Сообщение OberonAR »

На форум не могу - ошибку выдает, выше уже писал. Может так:
http://depositfiles.com/files/fu59n6lhn
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

Да, теперь открылось...
хз... дело конечно хозяйское - можно и так... но мне кажется можно проще сделать.
зачем нужен промежуточный модуль all - не понятно... контролировать все формы?
по моему даже массив форм который я предложил, предоставляет больше контроля над всеми открытыми окнами...
плюс можно открываемой форме добавить нужные свойства/методы и тогда передавать параметры в открытую форму можно как-то так AllMyForms[i].MyParam1, а если нужно получать какие-то данные обратно - то делать это перед уничтожением в конструкции try ... finally ... end ...
Массив форм даёт возможность правильно удалить их из памяти перед завершением программы просто пробежавшись по массиву.
Вообще просто с массивом не удобно работать - есть для этого специальные классы и generic'и... читай в этой ветке

p.s. я в своём примере с массивами допустил ошибку - там нельзя после уничтожения формы-элемента массива уменьшать массив - получишь ошибку ;)
Аватара пользователя
OberonAR
новенький
Сообщения: 73
Зарегистрирован: 08.02.2012 11:46:04
Откуда: Краснодарский край

Сообщение OberonAR »

leo_bsv
Спасибо! Просто я сделал так, как позволяют мои знания на данный момент и некоторые нюансы будущей программы. Но Ваш вариант я обязательно попытаюсь сделать. Так а с моим вариантом как - нет ли грубых ошибок?
svk12
постоялец
Сообщения: 411
Зарегистрирован: 09.06.2008 18:42:47

Сообщение svk12 »

OberonAR писал(а):массив форм который я предложил, предоставляет больше контроля над всеми открытыми окнами...


Массив не нужен!
Если формы создавались Application.CreateForm(), то они находятся в списке Components главной формы приложения.
Тогда:

Код: Выделить всё

var i:integer;
begin
  with Application.MainForm do
  begin
    for i:=0 to Pred(ComponentCount) do
    begin
       if Components[i] is TForm then //Отбор всех форм
       begin
          if Components[i] is T...Form then //Отбор всех форм нужного класса
          with Components[i] as T...Form do//Доступ к полям формы
       end;
    end;
  end;
end;


Соответственно, при закрытии главной формы все прочие будут удалены из памяти.
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

svk12 писал(а):Если формы создавались Application.CreateForm(), то они находятся в списке Components главной формы приложения.

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

человек вроде не желает создавать всё и сразу, на сколько я понял.
OberonAR писал(а):а с моим вариантом как - нет ли грубых ошибок?

при беглом просмотре листинга я не нашёл, но из-за того что код разбросан по модулям можно что-то упустить...
ИМХО, контроль над формами нужно сосредоточить в одном месте...

Добавлено спустя 7 минут 38 секунд:
if Components[i] is T...Form then //Отбор всех форм нужного класса
with Components[i] as T...Form do//Доступ к полям формы

с массивом, списками типов TFPGList и TObjectList теоретически можно проделать то же самое, задав в качестве класса массива/списка TForm? или я не прав?
svk12
постоялец
Сообщения: 411
Зарегистрирован: 09.06.2008 18:42:47

Сообщение svk12 »

leo_bsv писал(а):человек вроде не желает создавать всё и сразу, на сколько я понял.


Список Components - динамический, формы туда попадают при создании в рантайме, и соответственно, уходят при их закрытии.

leo_bsv писал(а):с массивом, списками типов TFPGList и TObjectList теоретически можно проделать то же самое, задав в качестве класса массива/списка TForm? или я не прав?


Прав, конечно, но стоит ли огород городить, если это уже есть в LCL?
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

Кстати да, Components тоже складывает объекты в список TFpList...

Добавлено спустя 10 минут 17 секунд:
но по-моему форма создаётся сразу при вызове Application.CreateForm из модуля проекта...

Код: Выделить всё

procedure TApplication.CreateForm(InstanceClass: TComponentClass; out Reference);
var
  Instance: TComponent;
...
begin
...
  Instance := TComponent(InstanceClass.NewInstance);
 ...
    if (FCreatingForm=nil) and (Instance is TForm) then
      FCreatingForm:=TForm(Instance);
    Instance.Create(Self);
...

видимо всё-же в память она сразу грузится... поправьте если я не прав.
svk12
постоялец
Сообщения: 411
Зарегистрирован: 09.06.2008 18:42:47

Сообщение svk12 »

При выполнении команды меню Файл->Новая форма в модуль проекта .lpr добавляется строка:

Код: Выделить всё

Application.CreateForm(TForm1, Form1); 


Если оставить всё как есть, то, действительно, все формы проекта будут созданы при его запуске между

Код: Выделить всё

begin
  Application.Initialize;
   и
  Application.Run;
end.


В этом случае, при создании формы (Application.CreateForm) её свойство Visual будет просто измененяется на True - и всё.
Но если хочется создавать форму динамически, то следует убрать её Application.CreateForm из файла проекта и вызывать в нужном месте в нужное время.
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

svk12 писал(а):Но если хочется создавать форму динамически, то следует убрать её Application.CreateForm из файла проекта и вызывать в нужном месте в нужное время.

как же она попадёт в Application.Components? в нужном месте в нужное время создавать её методом Application.CreateForm(TForm1, Form1); :?:

Добавлено спустя 5 минут 28 секунд:
тогда встаёт вопрос - как динамически создать столько форм сколько надо - ведь они должны определяться как-то так

Код: Выделить всё

var
  Form1, Form2...: TForm1;

мы не знаем имени нового объекта... а процедура требует имя:

Код: Выделить всё

Application.CreateForm(TForm1, Form2); 

как быть?
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

leo_bsv писал(а):мы не знаем имени нового объекта... а процедура требует имя:
как быть?

Код: Выделить всё

frm := TForm1.Create(Application);
...

ипи

Код: Выделить всё

with TForm1.Create(Application) do
...

что не так?
Но если хочется создавать форму динамически, то следует убрать её Application.CreateForm из файла проекта

В параметрах проекта есть удобная вкладка "Формы".
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

iskander писал(а):frm := TForm1.Create(Application);

iskander писал(а):with TForm1.Create(Application) do

если обе эти конструкции регистрируют форму в свойстве Application.Components... то я соглашусь что их использование имеет право на жизнь :D в смысле динамического создания кучи форм.
iskander писал(а):В параметрах проекта есть удобная вкладка "Формы".

Хорошая штука, конечно, но я, зная о ней, обычно руками всё делаю... Проект->Посмотреть исходный код проекта... привык. :)
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

leo_bsv писал(а):если обе эти конструкции регистрируют форму в свойстве Application.Components

см. TComponent.Create.
ИМХО если речь идёт о справочниках, то возня с кучей форм представляется излишней.
Создал справочник, показал модально, обработал пользовательский ввод, уничтожил справочник.
Ответить