Форум: "Начинающим";
Текущий архив: 2007.05.13;
Скачать: [xml.tar.bz2];
ВнизИгра с формами Найти похожие ветки
← →
Kostafey © (2007-04-24 17:19) [0]Уважаемые Мастера!
Помогите пожалуйста разрешить следующую проблему.
Повторить ее очень просто.
Создается Form1, Form2, Form3.
На Form1 размещаются 2 кнопки (вызывающие Form2 -модально и Form3):
procedure TForm1.ButtonForm2ModalCallClick(Sender: TObject);
begin
Form2.ShowModal;
end;
procedure TForm1.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Show;
end;
На Form2 размещается 1 кнопка (вызывающая Form3):
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Show;
end;
На Form3 размещается например Memo
Запускаем.
Жмем на кнопку, вызывающую модально Form2, Затем на Form2 нажимаем кнопку, вызывающую Form3.
Memo, находящееся на Form3 будет работать исправно.
Теперь другая ситуация.
Перезапускаем приложение.
Жмем в Form1 на кнопку, вызывающую Form3 (ее содержимое работеает исправно),
затем на Form1 нажимаем кнопку, вызывающую модально Form2. А в Form2
Вызываем уже открытую Form3. Все! Содержимое Form3, например, Memo работать не будет.
Не будут работать и другие визуальные компоненты формы.
Описанная ситуация точно копирует, ту сложность что возникла у меня.
Притом, даже если предварительно программно закрыть Form3:
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Close;
Form3.Show;
end;
Ничего не изменится.
Сделать так:
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
if Form3.Active then Form3.BringToFront
else Form3.Show;
end;
Тоже бесполезно.
Как же заставить Form3, уже открытую до этого, адекватно работать
при вызове ее из модальной формы?
← →
{RASkov} (2007-04-24 17:23) [1]> [0] Kostafey © (24.04.07 17:19)
Имхо... Не пользоваться переменными Form1, Form2, Form3.....
← →
Kostafey © (2007-04-24 17:27) [2]> Имхо... Не пользоваться переменными Form1, Form2, Form3.....
Ну шутку я оценил, здорово!
Нет я нарочно привел такой упрощенный пример, чтобы его
при желании можно было повторить.
← →
_Аноним © (2007-04-24 17:28) [3]
> Как же заставить Form3, уже открытую до этого, адекватно
> работать
> при вызове ее из модальной формы?
создай другой экземпляр TForm3, и покажи
а старый перед этим закрой
← →
Kostafey © (2007-04-24 17:29) [4]> создай другой экземпляр TForm3, и покажи
> а старый перед этим закрой
А экземпляр уже будет с другим именем?
← →
Kostafey © (2007-04-24 17:32) [5]> создай другой экземпляр TForm3, и покажи
> а старый перед этим закрой
Вот так ?
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Application.CreateForm(TForm3, Form3);
Form3.Show;
end;
А что, и правда работает.
Такой способ будет корректным ?
← →
Kostafey © (2007-04-24 17:33) [6]то есть
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Close;
Application.CreateForm(TForm3, Form3);
Form3.Show;
end;
← →
{RASkov} (2007-04-24 17:38) [7]> [2] Kostafey © (24.04.07 17:27)
> Ну шутку я оценил, здорово!
Это не шутка...
Во первых продумать алгоритм программы, и сделать так, чтоб не было возможным отоброжение одной и той же формы в двух разных режимах...
А про переменные я имел ввиду вот это:
With TFormN.Create() do begin
.....
ShowModal
Free;
end;
Что-то в этом духе....
← →
Kostafey © (2007-04-24 17:46) [8]> Во первых продумать алгоритм программы, и сделать так, чтоб
> не было возможным отоброжение одной и той же формы в двух
> разных режимах...
Неправда. Каждая форма отображается в совем режиме.
В модальном только Form2 (в данном примере).
Form3 отображается всегда немодально, другой вопрос, что в проекте
форма с аналогичным назначением может вызываться как справочник и как
независимый редактор (может со стороны это выглядит и не совсем корректно).
Вы имели в виду такой обработчик?
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
With TForm3.Create(Application) do begin
ShowModal;
Free;
end;
end;
Но тогда Form3 не закроется до закрытия Form2.
← →
Kostafey © (2007-04-24 17:47) [9]> в совем
в своем
← →
{RASkov} (2007-04-24 17:49) [10]> procedure TForm2.ButtonForm3CallClick(Sender: TObject);
> begin
> With TForm3.Create(Application) do begin
> ShowModal;
> Free;
> end;
> end;
>
> Но тогда Form3 не закроется до закрытия Form2.
Это почемуй-то Form3(Т.н. экземпляр TForm3, а не Form3) не закроется... это к TForm2 доступа не будет пока открыта в модальном режиме TForm3...
← →
Kostafey © (2007-04-24 17:54) [11]> Это почемуй-то Form3(Т.н. экземпляр TForm3, а не Form3)
> не закроется...
Ну так Сами попробуйте. Сначала открыть Form3, а потом из Form2 вызвать Ваш обработчик [8]
> пока открыта в модальном режиме TForm3...
Form3 ВСЕГДА ОТКРЫВАЕТСЯ В НЕМОДАЛЬНОМ РЕЖИМЕ !!!
Из разных форм она вызывается, но всегда немодально.
← →
Kostafey © (2007-04-24 17:56) [12]> Form3 ВСЕГДА ОТКРЫВАЕТСЯ В НЕМОДАЛЬНОМ РЕЖИМЕ !!!
> procedure TForm2.ButtonForm3CallClick(Sender: TObject);
> begin
> With TForm3.Create(Application) do begin
> ShowModal;
> Free;
> end;
> end;
Классно.
Я конечно имел в виду:
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
With TForm3.Create(Application) do begin
Show;
Free;
end;
end;
← →
Kostafey © (2007-04-24 18:07) [13]Вопрос теперь вот в чем.
Писать, наверное лучше всего так:
Form3.Close;
Form3.Free; //Нужен вот только ли этот оператор ??
Form3:= TForm3.Create(Application);
Form3.Show;
← →
{RASkov} (2007-04-24 18:38) [14]> [13] Kostafey © (24.04.07 18:07)
Ну тогда попробуй так, т.е. как все и делал вначале только добавь выделенное.
procedure TForm1.ButtonForm2ModalCallClick(Sender: TObject);
begin
Form2.ShowModal;
end;
procedure TForm1.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Show;
end;
На Form2 размещается 1 кнопка (вызывающая Form3):
procedure TForm2.ButtonForm3CallClick(Sender: TObject);
begin
Form3.Perform(CM_RECREATEWND, 0, 0);
Form3.Show;
end;
← →
Kostafey © (2007-04-24 18:45) [15]> Form3.Perform(CM_RECREATEWND, 0, 0);
О! Спасибо!
Опять меня выручаете.
← →
Leonid Troyanovsky © (2007-04-24 18:46) [16]
> Kostafey © (24.04.07 18:07) [13]
> Писать, наверное лучше всего так:
Выруби у себя на стене: "Модальную форму показываем так":
with TFormX.Create(nil) do
try
{подготовительная работа}
case ShowModal of
{анализ выбора пользователя}
end;
finally
Free;
end;
За остальными знаниями подходи после усвоения материала.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-04-24 18:49) [17]
> {RASkov} (24.04.07 18:38) [14]
Form2, Form3 - MD.
--
Regards, LVT.
← →
Kostafey © (2007-04-24 18:57) [18]> Выруби у себя на стене: "Модальную форму показываем так":
Топора нет, фламастер высох.
Рисую карандашом.
> после усвоения материала
Материал усвоил.
Я делал немного по-другому: http://delphimaster.net/view/2-1177072185/
Но одно другому не мешает.
> Form3 - MD.
MD - модальная ? Это тоже шутка.
← →
Kostafey © (2007-04-24 18:58) [19]> with TFormX.Create(nil) do
> try
> {подготовительная работа}
> case ShowModal of
> {анализ выбора пользователя}
> end;
> finally
> Free;
> end;
А вообще, спасибо!
← →
{RASkov} (2007-04-24 19:06) [20]> [17] Leonid Troyanovsky © (24.04.07 18:49)
> Form2, Form3 - MD.
?
> [19] Kostafey © (24.04.07 18:58)
with TFormX.Create(nil) do
....
Только из AutoCreate убери(если еще не сделал этого) TFormX.
← →
Leonid Troyanovsky © (2007-04-24 19:17) [21]
> Kostafey © (24.04.07 18:57) [18]
> Материал усвоил.
Ну, если ты так быстро схватываешь,
немодальные оставлю в качестве домашнего задания.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-04-24 19:20) [22]
> {RASkov} (24.04.07 19:06) [20]
> > Form2, Form3 - MD.
Must Die.
See also: LMD.
--
Regards, LVT.
← →
{RASkov} © (2007-04-24 19:29) [23]> [22] Leonid Troyanovsky © (24.04.07 19:20)
> Must Die.
Согласаен.
См. [1] и далее [14] - это я чтоб не писать много слов скопировал код автора из [0]. "Ошибки" в данном случае нет. Но для "правильного" написания кода в данной ветке уже обговорены моменты, например в [16], но для НЕ модальных - этого мало. Поэтому и привел в том виде как было сначала.
← →
Kostafey © (2007-04-24 19:35) [24]То есть Вы хотите сказать, что работать с модальными окнами через их имена не рекомендуется ?
← →
Leonid Troyanovsky © (2007-04-24 19:42) [25]
> Kostafey © (24.04.07 19:35) [24]
> То есть Вы хотите сказать, что работать с модальными окнами
> через их имена не рекомендуется ?
Мы хотели лишь сказать, что использовать глобальные
переменные типа Form1..N не следует ни для каких форм.
--
Regards, LVT.
← →
Kostafey © (2007-04-24 19:50) [26]> Только из AutoCreate убери(если еще не сделал этого) TFormX.
Имеется в виду Application.CreateForm(TForm3, Form3); в основном файле проекта?
> Ну, если ты так быстро схватываешь,
> немодальные оставлю в качестве домашнего задания.
Вы что же хотите сказать, что аналогично нужно и немодальные окна run-time создавать?
Извините, если посчитаете вопросы слишком глупыми. Раздел форума так и называется, да и
определение LMD я разобрал.
← →
Kostafey © (2007-04-24 19:52) [27]> Только из AutoCreate убери(если еще не сделал этого) TFormX.
Имеется в виду Application.CreateForm(TForm3, Form3); в основном файле проекта?
> Ну, если ты так быстро схватываешь,
> немодальные оставлю в качестве домашнего задания.
Вы что же хотите сказать, что аналогично нужно и немодальные окна run-time создавать?
Извините, если посчитаете вопросы слишком глупыми. Раздел форума так и называется, да и
определение LMD я разобрал.
← →
Leonid Troyanovsky © (2007-04-24 19:55) [28]
> {RASkov} © (24.04.07 19:29) [23]
> Поэтому и привел в том виде как было сначала.
Каюсь, начало пропустил :(
Но, твой костыль не спасет уважаемого Kostafey.
Если же он прислушается к другим твоим более, IMHO,
полезным советам, то сможет ходить без костылей.
--
Regards, LVT.
← →
Kostafey © (2007-04-24 19:57) [29]> Мы хотели лишь сказать, что использовать глобальные
> переменные типа Form1..N не следует ни для каких форм.
Ясно. В этом случае, немодальные формы могли бы стать, например,
локальными переменными главной формы.
Д.З. понял.
← →
Leonid Troyanovsky © (2007-04-24 19:58) [30]
> Kostafey © (24.04.07 19:52) [27]
> Вы что же хотите сказать, что аналогично нужно и немодальные
> окна run-time создавать?
Аналогия только в одном - без использования глобальных переменных.
Или ты не хочешь делать домашнее задание? :)
--
Regards, LVT.
← →
Kostafey © (2007-04-24 20:00) [31]> [28] Leonid Troyanovsky © (24.04.07 19:55)
Простите, это > [14] {RASkov} Вы назвали костылем ?
← →
Leonid Troyanovsky © (2007-04-24 20:04) [32]
> Kostafey © (24.04.07 19:50) [26]
> Имеется в виду Application.CreateForm(TForm3, Form3); в
> основном файле проекта?
Вобщем-то - да. Но, лезть в dpr руками не обязательно, достаточно
Project - Options - Forms: Auto-create -> Available
--
Regards, LVT.
← →
Kostafey © (2007-04-24 20:05) [33]> Аналогия только в одном - без использования глобальных переменных.
Да, понимаю. Но завтра в обед мне уже готовый вариант надо показывать.
Глобально что перестраивать сейчас что-то уже поздновато, вот я и пытаюсь
вникнуть лучше, чтобы в следующем проекте уже более грамотно делать.
> Или ты не хочешь делать домашнее задание? :)
Ну как вы такое могли подумать?! Я товарищь на такие вещи ответственный ! :)
← →
Leonid Troyanovsky © (2007-04-24 20:11) [34]
> Kostafey © (24.04.07 20:00) [31]
> Простите, это > [14] {RASkov} Вы назвали костылем ?
Когда что-то хромает, возникает потребность в костыле.
--
Regards, LVT.
← →
Kostafey © (2007-04-24 20:16) [35]> Когда что-то хромает, возникает потребность в костыле.
А когда кто-то летает ему и костыли ни к чему. Понял.
Спасибо за Ваши разъяснения !
← →
Leonid Troyanovsky © (2007-04-24 20:19) [36]
> Kostafey © (24.04.07 19:57) [29]
> локальными переменными главной формы.
В быту называемыми полями (формы).
Можно даже и вовсе без переменных обойтись, бо
храняться все ссылки на формы в Screen.Forms.
Ну, а основное отличие немодальных от модальных форм
в том, что неизвестен момент, когда их закроют
(т.е., когда их, собс-но, следует разрушить).
Хотя (hint), как разрушать понятно - Action := caFree
--
Regards, LVT.
← →
{RASkov} © (2007-04-24 20:36) [37]> Kostafey ©
Проделай такой эксперемент и сделай выводы. Для простоты примера обе формы в AutoCreate.В Form2
procedure TForm2.Button1Click(Sender: TObject);
begin
Form2:=TForm2.Create(Self);
Form2.Caption:="F1"; Form2.Left:=Random(Screen.Width-Width);
Form2.Show;
Form2:=TForm2.Create(Self);
Form2.Caption:="F2"; Form2.Left:=Random(Screen.Width-Width);
Form2.Show;
Form2:=TForm3.Create(Self);
Form2.Caption:="F3"; Form2.Left:=Random(Screen.Width-Width);
Form2.Show;
FreeAndNil(Form2);
end;
В Form1
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
// if Assigned(Form2) then FreeAndNil(Form2);
// with TForm2.Create(nil) do Show;
end;
Button1 на формах нажимай более одного раза.
Затем расскомментируй втрорую и третью строку и закомментируй первую... попробуй еще раз. Обращай внимание на все и поймешь разницу.
← →
{RASkov} © (2007-04-24 20:37) [38][37] Это как раз про использование глобальных переменных....
← →
Leonid Troyanovsky © (2007-04-24 20:46) [39]
> {RASkov} © (24.04.07 20:36) [37]
> // if Assigned(Form2) then FreeAndNil(Form2);
Не хочу снижать педагогический эффект,
и неохота, собс-но, воспроизводить твой, без сомнения,
полезный пример, но, мимо квотируемого пройти не могу.
Т.е., FreeAndNil тоже костыль, бо, для любых компонентов
механизма Notification вполне, IMHO, достаточно.
Да озаботятся этим все держатели ссылок на компонент.
--
Regards, LVT.
← →
Kostafey © (2007-04-24 20:48) [40]> [37] {RASkov} © (24.04.07 20:36)
Form2:=TForm3.Create(Self);
[Oшибкa] Unit2.pas(36): Incompatible types: "TForm2" and "TForm3"
Сейчас попробую разобраться...
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.05.13;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.048 c