Странности с модальными формами
Модератор: Модераторы
-
wwswowsogon
- постоялец
- Сообщения: 157
- Зарегистрирован: 23.12.2008 19:41:37
Странности с модальными формами
Здравствуйте!
Внезапно словил странный глюк:
родительское окно закрывается при закрытии дочернего модального. Ежели модальность убрать, то этот эффект пропадает. Дочернее окно закрываю просто по Close. Эффект работает независимо от наличия в событии другого кода.
Пробовал на 1.0.4 и на 1.6.4.
Известно ли кому-нибудь о таком и как с этим бороться?
Внезапно словил странный глюк:
родительское окно закрывается при закрытии дочернего модального. Ежели модальность убрать, то этот эффект пропадает. Дочернее окно закрываю просто по Close. Эффект работает независимо от наличия в событии другого кода.
Пробовал на 1.0.4 и на 1.6.4.
Известно ли кому-нибудь о таком и как с этим бороться?
это как? Т.е. MDI стиль + модальное?дочернего модального
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
видимо, речь об окне открывающемся из другого окна.
-
wwswowsogon
- постоялец
- Сообщения: 157
- Зарегистрирован: 23.12.2008 19:41:37
pupsik писал(а):это как? Т.е. MDI стиль + модальное?
нее, fsNormal.
Лекс Айрин писал(а):видимо, речь об окне открывающемся из другого окна.
Да, именно так.
Если точнее - из главного окна вызывается дочернее, поменьше, с помощью Card1.Show, а уже из него ещё одно, ещё поменьше, с помощью Dlg1.ShowModal
Не знаю, много раз так делал раньше, всё было нормально. Более того, ЕМНИП, и в этом проекте до какого-то момента было всё хорошо.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
wwswowsogon, имхо, ты путаешь терминологию. Дочернее окно оно плоть от плоти основного и является, по сути, обычным компонентом.
А то, что ты его запустил или, вдруг, создал, в другом окне не делает его дочерним. А вообще, нужен код... без него астрологи не видят звезд, а медиумы будущего... Не хочешь целиком, так выложи как создается, запускается и закрывается окно.
Знакомая ситуация. И еще не раз встретится. Просто иногда ошибка или компенсируется или лежит в мертвом коде.
А то, что ты его запустил или, вдруг, создал, в другом окне не делает его дочерним. А вообще, нужен код... без него астрологи не видят звезд, а медиумы будущего... Не хочешь целиком, так выложи как создается, запускается и закрывается окно.
wwswowsogon писал(а): Более того, ЕМНИП, и в этом проекте до какого-то момента было всё хорошо.
Знакомая ситуация. И еще не раз встретится. Просто иногда ошибка или компенсируется или лежит в мертвом коде.
-
wwswowsogon
- постоялец
- Сообщения: 157
- Зарегистрирован: 23.12.2008 19:41:37
Не спорю, возможно.Лекс Айрин писал(а):ты путаешь терминологию
Выложить код не жалко, но иногда стыдно:))
Имеется в виду, самое крайнее?Лекс Айрин писал(а):выложи как создается, запускается и закрывается окно.
Код: Выделить всё
procedure TDlg1.FormCreate(Sender: TObject);
var vaclist: TextFile;
s: String;
begin
Caption := 'Параметры';
Position := poMainFormCenter;
Label1.Caption:='Выбор вакцины:';
Label1.Font.Bold := true;
Label2.Caption:='Периодичность:';
Label2.Font.Bold := true;
Label3.Caption:='Дата текущей:';
Label3.Font.Bold := true;
Label4.Caption:='Дата следующей:';
Label4.Font.Bold := true;
Label5.Caption:='Примечание:';
Label5.Font.Bold := true;
CB1.Text:='';
CB1.Font.Bold := true;
BitBtn1.Caption:='Принять';
BitBtn1.Font.Bold := true;
BitBtn2.Caption:='Отмена';
BitBtn2.Font.Bold := true;
Edit1.Text:=IntToStr(UpDown1.Min);
Edit1.AutoSelect:=true;
Edit1.Font.Bold := true;
Edit2.Text:='';
Edit2.Font.Bold := true;
UpDown1.Associate := Edit1;
UpDown1.Min := 1;
UpDown1.Max := 99;
Period := StrToInt(Edit1.Text);
MaskEdit1.EditMask := '!00.00.0000;1;_';
MaskEdit1.Font.Bold := true;
MaskEdit2.EditMask := '!00.00.0000;1;_';
MaskEdit2.Font.Bold := true;
DataCh := 0;
//Загрузка списка вакцин из файла
if FileExists('data\vaclist.dat') then
begin
AssignFile(vaclist, 'data\vaclist.dat');
Reset(vaclist);
while not EoF(vaclist) do
begin
ReadLn(vaclist, s);
s := Copy(s, 1, Pos('^', s) - 1);
CB1.Items.Add(s);
end;
CloseFile(vaclist);
CB1.Caption := CB1.Items[0];
end
else ShowMessage('Файл "vaclist.dat" не найден.');
end;
Открывается так:
Код: Выделить всё
procedure TCard1.BitBtn1Click(Sender: TObject);
begin
Dlg1.NewRow := 1;
Dlg1.ShowModal;
end;Закрывается по кнопке, причем кнопки две, и от каждой закрываются оба окна
Код: Выделить всё
procedure TDlg1.BitBtn1Click(Sender: TObject);
{begin
if DataCh = 1
then
begin
//Main.Data1Changed := 1;
//Card1.Data1Changed := 1;
if NewRow = 1 then
begin
Card1.Data1.RowCount := Card1.Data1.RowCount + 1;
Card1.Data1.Cells[1, Card1.Data1.RowCount - 1] := CB1.Text;
Card1.Data1.Cells[2, Card1.Data1.RowCount - 1] := MaskEdit1.Text;
Card1.Data1.Cells[3, Card1.Data1.RowCount - 1] := MaskEdit2.Text;
Card1.Data1.Cells[4, Card1.Data1.RowCount - 1] := Edit2.Text;
end
else
begin
Card1.Data1.Cells[1, Card1.NSS] := CB1.Text;
Card1.Data1.Cells[2, Card1.NSS] := MaskEdit1.Text;
Card1.Data1.Cells[3, Card1.NSS] := MaskEdit2.Text;
Card1.Data1.Cells[4, Card1.NSS] := Edit2.Text;
end;
Close;
end
else }Close;
end; Без разницы, работает ли закомментированный код, или нет. Даже простое Close приводит к закрытию обоих.
если не сложно: можно исходники в архиве? А то как то ... вроде много написано, а чёт странности..
Как я понимаю: форма (модальная) у вас создаётся автоматом?
Как я понимаю: форма (модальная) у вас создаётся автоматом?
wwswowsogon писал(а):Открывается так:Код: Выделить всё
procedure TCard1.BitBtn1Click(Sender: TObject);
begin
Dlg1.NewRow := 1;
Dlg1.ShowModal;
end;
Поставьте проверку
if Dlg1.ShowModal = mrClose then ...
else ...
sign писал(а):Поставьте проверку
Ну если так решать, то можно ещё попробовать конкретно ей указать, что именно закрывать:
Код: Выделить всё
Dlg1.Close;
Но скорее всего, как обычно, дело в каком-то сбое в теле программы.
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Если стыдно показать код - приведи его в порядок.
Dlg1, Label1, Btn1, Project1 - это имена не для людей, а для машин. Машине пофигу, а человек (особенно сам автор программы) может запросто в этом запутаться и наделать глупых ошибок. За то время, что вы ждете ответа на форуме, можно десять раз все привести в порядок и дать человеческие имена.
В процедуре FormCreate() нет никакой необходимости назначать свойства контролам, это все делается в редакторе формы.
Научись использовать ActionList (он в стандартных контролах) и привязывать действия к кнопкам и менюшкам. Это сэкономит много времени и нервов.
В модальной форме достаточно назначить в кнопке свойство ModalResult любое значение, кроме mrNone и при нажатии будет автоматически происходить Close() с возвратом заданного результата. Но это только для "обычных" кнопок (TButton и его потомков), для групповых кнопок (TSpeedButton, TToolButton) это не работает.
Dlg1, Label1, Btn1, Project1 - это имена не для людей, а для машин. Машине пофигу, а человек (особенно сам автор программы) может запросто в этом запутаться и наделать глупых ошибок. За то время, что вы ждете ответа на форуме, можно десять раз все привести в порядок и дать человеческие имена.
В процедуре FormCreate() нет никакой необходимости назначать свойства контролам, это все делается в редакторе формы.
Научись использовать ActionList (он в стандартных контролах) и привязывать действия к кнопкам и менюшкам. Это сэкономит много времени и нервов.
В модальной форме достаточно назначить в кнопке свойство ModalResult любое значение, кроме mrNone и при нажатии будет автоматически происходить Close() с возвратом заданного результата. Но это только для "обычных" кнопок (TButton и его потомков), для групповых кнопок (TSpeedButton, TToolButton) это не работает.
-
wwswowsogon
- постоялец
- Сообщения: 157
- Зарегистрирован: 23.12.2008 19:41:37
sign писал(а):Поставьте проверку
if Dlg1.ShowModal = mrClose then ...
else ...
Проверил, рез-т отрицательный, что логично...
vitaly_l писал(а):Ну если так решать, то можно ещё попробовать конкретно ей указать, что именно закрывать:
КОД: ВЫДЕЛИТЬ ВСЁ
Dlg1.Close;
Уже делал, нэ помогло.
serbod писал(а):Если стыдно показать код - приведи его в порядок.
Спасибо за рекомендацию, но к нашей теме это не имеет непосредственного отношения. Это важный вопрос общей культуры
Исходники здесь, если кто посмотрит, буду признателен.
Сейчас работает при простом Show, что не особо критично, но хотелось бы сделать по-людски.
https://yadi.sk/d/IbO_I5tN3Fzwk5
wwswowsogon писал(а):Исходники здесь, если кто посмотрит, буду признателен.
Сейчас работает при простом Show, что не особо критично, но хотелось бы сделать по-людски.
https://yadi.sk/d/IbO_I5tN3Fzwk5
Код: Выделить всё
procedure TDlg1.FormClick(Sender: TObject);
begin
//close;
end;
Закомментируйте, close <-- как в примере и будет Вам счастье. У Вас на кнопку стоит mrOk больше ничего в коде писать ненужно. Она сама закроется. Ненужно нигде писать Close, на кнопках, у которых выставляете modalResult; И вообще ненужно писать команду Close если используете кнопки с modalResult - они сами закрывают форму.
vitaly_l Вы это запустили? Хм... а я устал править код.
wwswowsogon
1. DirectorySeparator - знакомо?
2. TryStrToDate - в вашем варианте более желателен.
3. пути.... есть такое слово const. Т.е. прописывайте путь в виде константы.
4. Utf8Pos и похожее - рецепт для лазаря (учитывая что файлы у вас в ютф8...).
....
и много, много чего
...
В общем, по идее, "ловите" исключение и происходит вылет приложения. Т.е. вы вызвали модальную форму и пытаетесь править главную.. По идее - не стандартная ситуация, мягко говоря.
Советую добавить "отлов" ModalResult. И вынести процедуру заполнения из диалога в главную форму (или какая у вас она там).
Т.е.
Могу ошибаться. Программа не запустилась. Ну...у лень править столько
да???Закомментируйте, close <-- как в примере и будет Вам счастье.
wwswowsogon
хм... Начнём:Внезапно словил странный глюк:
1. DirectorySeparator - знакомо?
2. TryStrToDate - в вашем варианте более желателен.
3. пути.... есть такое слово const. Т.е. прописывайте путь в виде константы.
4. Utf8Pos и похожее - рецепт для лазаря (учитывая что файлы у вас в ютф8...).
....
и много, много чего
...
В общем, по идее, "ловите" исключение и происходит вылет приложения. Т.е. вы вызвали модальную форму и пытаетесь править главную.. По идее - не стандартная ситуация, мягко говоря.
Советую добавить "отлов" ModalResult. И вынести процедуру заполнения из диалога в главную форму (или какая у вас она там).
Т.е.
Код: Выделить всё
procedure TCard1.BitBtn1Click(Sender: TObject);
begin
Dlg1.NewRow := 1;
Dlg1.ShowModal;
if Dlg1.ModalResult = mrok then
begin
if DataCh = 1 then
begin
if NewRow = 1 then
begin
Card1.Data1.RowCount := Card1.Data1.RowCount + 1;
....
end else
begin
Card1.Data1.Cells[1, Card1.NSS] := CB1.Text;
....
end;
end;
end;
Могу ошибаться. Программа не запустилась. Ну...у лень править столько
pupsik писал(а):vitaly_l Вы это запустили? Хм... а я устал править код.
Могу ошибаться. Программа не запустилась. Ну...у лень править столько
У меня всё с первого раза запустилось и работало.
Действительно, третье окно с карточкой - закрывало два окна (себя и предка).
Увидел что, функция Close - лишняя, т.к. она дублирует Close у кнопки с modalResult = mrOk .
Закомментировал Close, как мной показано выше и всё стало работать, как надо.
В смысле у меня третья форма закрывается, а вторая остаётся открытой.
Ничего кроме Close я не смотрел. Починил Close и стёр проект
PS: ещё я там ShowModal включил вместо Show, чтобы смотреть.
.
сделайте простой тест. 2 формы. На кнопку повесьте MrOk и close. Попробуйте.vitaly_l
проблема №1 - у меня линь... проблема №2 - транк. Проект сделан "конкретно" под винду. Кросом и не пахнет. Поэтому и сложность запуска.У меня всё с первого раза запустилось и работало.
п.с.
"лень"... ну реально: десяток путей, ошибки чтения формата даты и ещё тележка ошибок. В принципе можно поправить... но - это каждый чих править, или сорцы проверять.. Всё это займет время. Могу его потратить если заинтересует, а так... искать баг в коде и без интереса - лень (пардон ).
