Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.08.02;
Скачать: [xml.tar.bz2];

Вниз

Многократно копировать форму в MDI приложении   Найти похожие ветки 

 
anvolkov ©   (2009-06-07 17:37) [0]

Прошу вашего совета в таком вопросе.
Имеется MDI программа. Имеется форма, к примеру - накладная.
Нужно открывать ее не 1 раз, как это получается, а иметь возможность открывать сколько угодно ее копий, т.е. просматривать одновременно много разных накладных (как в 1С)
В документации так и не понял как это сделать.
Делать через классы не смогу, т.к. задолбаюсь прописывать в коде все расположения кнопок, все размеры, связи и т.д.
Если можно дублировать уже созданную в конструкторе форму - подскажите маленьким примерчиком, если не сложно...


 
Игорь Шевченко ©   (2009-06-07 17:43) [1]

with TMyMdiForm.Create (...) do
 show;


 
Сергей М. ©   (2009-06-07 17:43) [2]

NewInstanceOfMyMDIChildForm := TMyMDIChildForm.Create(..);


 
anvolkov ©   (2009-06-07 17:55) [3]

В таком варианте копирования будут работать подпрограммы событий, навешанные на эту форму? или им нужно будет создавать связи программно?


 
Григорьев Антон ©   (2009-06-07 17:59) [4]


> В таком варианте копирования будут работать подпрограммы
> событий, навешанные на эту форму?

Всё будет работать, как надо. Главное - не использовать внутри методов ту глобальную переменную, которую создаёт для формы среда (т.е., например, если у вас эта форма имеет тип TForm2, нельзя внутри её методов использовать созданную автоматически переменную Form2).


 
Юрий Зотов ©   (2009-06-07 18:20) [5]

А лучше всего эту переменную сразу удалить. Надежнее будет.


 
Юрий Зотов ©   (2009-06-07 18:21) [6]

И Show для child-форм - лишнее.


 
anvolkov ©   (2009-06-07 18:41) [7]


> И Show для child-форм - лишнее.

так show как раз и задумывался, чтобы открывать окна накладных, а пользователь поработав с ними - будет закрывать и освобождать эти формы.
Т.е. пусть живет одна форма - оригинал.

> А лучше всего эту переменную сразу удалить. Надежнее будет.

хм... а если на форме куча процедур обработки различных объектов? и все они управляются form2.

может, как-то можно объявить класс, включить в него готовую форму из конструктора, прописать обработчики и просто создавать?


 
Юрий Зотов ©   (2009-06-07 18:52) [8]

> anvolkov ©   (07.06.09 18:41) [7]

Андрей, в каталоге Delphi\Demos\Doc\TextEdit лежит пример проекта с MDI-Child формами. Если Вы его откомпилируете, запустите, посмотрите, как он работает, а потом посмотрите, как он написан, то...

...то таких конфузов, как в этой ветке, я надеюсь, Вы больше не допустите.


 
Сергей М. ©   (2009-06-07 19:05) [9]


> show как раз и задумывался, чтобы открывать окна


Show в переводе с нерусского - это "показать", а не "открыть".
"Открыть" в переводе с того же нерусского - это Open, но никак не Show.
Запомни: дельфийские MDIChild-формы не могут быть невидимыми, т.е. их создание (Create) безусловно влечет за собой их визуализацию (Show), то бишь создание таких форм автоматически подразумевает их визуализацию, так что явный вызов тобой метода Show избыточен, о чем и было важное замечание в [6].


 
Нат ©   (2009-06-07 19:06) [10]

Специально для правильно реакции объектов в событиях и методах объектов используется переменная Self, а также передается ссылка на объект
   procedure BitBtn1Click(Sender: TObject);


 
anvolkov ©   (2009-06-07 19:09) [11]

Спасибо за советы. Буду крутить, пробовать. :)


 
Игорь Шевченко ©   (2009-06-07 20:38) [12]


> создание таких форм автоматически подразумевает их визуализацию,
>  так что явный вызов тобой метода Show избыточен


Может быть он и избыточен, зато код более понятен


 
Сергей М. ©   (2009-06-07 22:03) [13]


> Может быть он и избыточен, зато код более понятен


Бесспорно.

Но факт этот знать непременно нужно, согласись ?

Ведь вторая строчка хит-парада вопросов про дельфийские MDIChild-формы - "а почему я ее хАйдю-клОзю, а она, зараза, уперлась и не хочет закрываться ?"


 
Игорь Шевченко ©   (2009-06-07 23:02) [14]


> Но факт этот знать непременно нужно, согласись ?


Соглашаюсь :)


 
Нат ©   (2009-06-07 23:02) [15]

Отдельный писк - попытка изменить тип из mdichild, установленный в дизайнере, на Нормал в событии формы OnCreate. :)


 
Германн ©   (2009-06-08 00:39) [16]


> Игорь Шевченко ©   (07.06.09 20:38) [12]


> Сергей М. ©   (07.06.09 22:03) [13]
>
>
> > Может быть он и избыточен, зато код более понятен
>
>
> Бесспорно.

Увы не соглашусь.
Будучи сей код распечатан на бумаге (в т.ч. на электронной) - тогда (и иногда) он более понятен (некоторым :).


 
Юрий Зотов ©   (2009-06-08 10:13) [17]

Вызывать ненужный метод ради "понятности"? Не понимаю.

FormStyle := ...;
RecreateWnd; // Который УЖЕ был вызван сеттером, но так ведь понятнее?


 
Игорь Шевченко ©   (2009-06-08 10:42) [18]


> FormStyle := ...;
> RecreateWnd; // Который УЖЕ был вызван сеттером, но так
> ведь понятнее?


Я надеюсь, приведенный код к TCustomForm.Show не имеет отношения ?


 
Юрий Зотов ©   (2009-06-08 12:56) [19]

Самое непосредственное.

Как ты знаешь, по умолчанию формы имеют Visible = False. И если child-форма становится видимой "автоматически", значит показ child-форм происходит так же "автоматически", где-то в недрах кода VCL. И даже без особого копания в этих недрах ясно, что показ формы тащит за собой неслабую цепочку исполняемого кода.

Спрашивается - зачем же вызывать эту же цепочку второй раз?

procedure TCustomForm.Show;
begin
 Visible := True;
 BringToFront;
end;

Отследи, к чему это приводит, включая вызов унаследованных методов. Не слишком ли дорогая цена мнимой "наглядности"?


 
Игорь Шевченко ©   (2009-06-08 13:01) [20]

Юрий Зотов ©   (08.06.09 12:56) [19]

Отслеживаю:

procedure TCustomForm.SetVisible(Value: Boolean);
begin
 if fsCreating in FFormState then
   if Value then
     Include(FFormState, fsVisible) else
     Exclude(FFormState, fsVisible)
 else
 begin
   if Value and (Visible <> Value) then SetWindowToMonitor;
   inherited Visible := Value;
 end;
end;

procedure TControl.SetVisible(Value: Boolean);
begin
 if FVisible <> Value then  begin
   VisibleChanging;
   FVisible := Value;
   Perform(CM_VISIBLECHANGED, Ord(Value), 0);
   RequestAlign;
 end;
end;

Как ты пришел к своим строкам ?


 
Юрий Зотов ©   (2009-06-08 13:45) [21]

> Игорь Шевченко ©   (08.06.09 13:01) [20]

> if FVisible <> Value then

Это и козе было понятно, практически все сеттеры так работают. Итого имеем лишнего:

- вызов TCustomForm.Show
- вызов TCustomForm.SetVisible
- проверка Visible <> Value в TCustomForm.SetVisible
- вызов TControl.SetVisible
- проверка FVisible <> Value в TControl.SetVisible
- 2 раза RET

И, кроме того:

- вызов TControl.BringToFront
- вызов TControl.SetZOrder
- проверка FParent <> nil в TControl.SetZOrder
- 2 раза Ret

Плюс обращения к полям объектов (загрузка в регистры и пр.), которых в этой цепочке тоже участвует немало.

И зачем все это? Достаточно просто знать, что child-формы невидимыми не бывают - и никакой "наглядности" уже не потребуется. Кстати, знать это не только достаточно, но и необходимо. А для совсем уж особых чайников достаточно перед вызовом конструктора child-формы написать комментарий:

// Вызов Show для child-форм не нужен, они становятся видимыми сами.

В общем, так - спорить тут не о чем. Если тебе нравится делать на фиг не нужные вызовы - вызывай хоть 100 раз. Только процитирую твои же слова: "у меня при взгляде на подобный код возникают сомнения в компетентности написавшего его программиста".


 
Игорь Шевченко ©   (2009-06-08 14:15) [22]

Юрий Зотов ©   (08.06.09 13:45) [21]

Представь себе, код с созданием формы и вызовом Show - понятнее.

А что до лишних вызовов, то как только ты используешь AnsiString по сравнению с array of char, у тебя генерируется столько вызовов, что по сравнению с ними перечисленное тобой выглядит незначительным.

И все-таки, откуда RecreateWnd-то взялся ? :)


 
Юрий Зотов ©   (2009-06-08 14:28) [23]

> Игорь Шевченко ©   (08.06.09 14:15) [22]

> И все-таки, откуда RecreateWnd-то взялся ?

Игорь, не ожидал. Просто убил. При изменении оконного стиля формы надо пересоздать само ее окно, или нет?

procedure TForm1.FormDblClick(Sender: TObject);
begin
 TForm2.Create(Self).FormStyle := fsMDIChild
end;

Изначально TForm1 - fsMDIForm, TForm2 - fsNormal. При изменении TForm2.FormStyle метод RecreateWnd вызывается автоматически, причем аж дважды. Вызывать его в третий раз вручную можно (и, якобы, наглядно) - но не нужно.

Это иллюстрация к твоей "наглядности".


 
Юрий Зотов ©   (2009-06-08 14:34) [24]

> Игорь Шевченко ©   (08.06.09 14:15) [22]

> код с созданием формы и вызовом Show - понятнее.

А комментарий:
// Вызов Show для child-форм не нужен, они становятся видимыми сами.
в пять раз понятнее.

И, что главное - в миллион раз полезнее.


 
Игорь Шевченко ©   (2009-06-08 14:40) [25]

Юрий Зотов ©   (08.06.09 14:28) [23]

Я вообще-то про Show говорил, что понятнее, а не про изменение стиля. Это к вопросу о RecreateWnd. Даже уточнил, в посте [18]


> А комментарий:
> // Вызов Show для child-форм не нужен, они становятся видимыми
> сами.
> в пять раз понятнее.
>
> И, что главное - в миллион раз полезнее.


Неубедительно.


 
Юрий Зотов ©   (2009-06-08 14:48) [26]

> Игорь Шевченко ©   (08.06.09 14:40) [25]

Ах, да, конечно.

LOL



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.08.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.005 c
15-1243695477
zdm
2009-05-30 18:57
2009.08.02
Windows 7 Delphi 2009 ошибка assertion failure


15-1243936738
boriskb
2009-06-02 13:58
2009.08.02
С юбилеем!


3-1225144232
Раиса
2008-10-28 00:50
2009.08.02
MySQL и SSH Tunneling - какие компоненты


2-1244472613
lewka
2009-06-08 18:50
2009.08.02
Работа в Word


15-1243497903
VirEx (work)
2009-05-28 12:05
2009.08.02
День программиста





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский