Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/40: Рейтинг темы: голосов - 40, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 3

Модальные формы и работа с ними

20.02.2018, 02:54. Показов 8343. Ответов 44
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В этом сообщении не буду рассматривать как создать форму авторизации используя модальное окно. Данный способ прекрасно описан здесь.
Собственно долго мучился с тем как правильно открывать и закрыть модальную форму №3 много раз, находясь в главном окне программы (форме № 2). Вроде все заработало, но история все равно остается какой-то мутной. Вот как я сделал:
C++
1
2
3
4
5
6
7
8
void __fastcall TForm2::Button1Click(TObject *Sender)
{
    TForm3 *frm3 = new TForm3(0);
    frm3->Left=Screen->Width/2-frm3->ClientWidth/2;  //выравниваем форму по центру
    frm3->Top=Screen->Height/2-frm3->ClientHeight/2; //выравниваем форму по центру
    frm3->ShowModal();
    
}
Во вновь созданной форме есть, кнопка "Закрыть" (Button), по нажатию которой форма закрывается
C++
1
2
3
4
void __fastcall TForm3::Button1Click(TObject *Sender)
{
 ModalResult = mrClose; //форма № 3 закрывается
}
Но почему-то в пособиях рекомендуют использовать следующую конструкцию для вызова и закрытия модальных форм:
C++
1
2
3
4
5
6
7
8
9
TFormX * FormX = new TFormX(0);
try
{
    FormX->ShowModal();
}
__finally
{
    delete FormX;
}
Вот только если такую конструкцию использовать, то форму № 3 хрен ты без ошибки закроешь. Ведь из Unit.cpp удалено TForm3 *Form3, из Unit.h удалено extern PACKAGE TForm3 *Form3, вроде как из-за того, что форма создается не автоматически, это позволяет избежать утечки памяти. Но в таком случае при работе с самой формой № 3 не получится ее закрыть обычным способом:
C++
1
Form3->Close();
или
C++
1
delete Form3;
Так вот вопрос: правильно ли я закрываю форму используя ModalResult = mrClose или нужно как-то победить delete FormX и заставить программу работать с ней?

Добавлено через 11 минут
Немного поясню, если использовать try/finally в главной форме, у меня это Form2, то как тогда по нажатию кнопки на третьей форме (Form3) закрыть эту самую Form3?
C++
1
2
3
4
5
6
7
8
9
TForm3 * Form3 = new TForm3(0);
try
{
    Form3->ShowModal();
}
__finally
{
    delete Form3;
}
Как тогда закрыть Form3?
C++
1
2
3
4
void __fastcall TForm3::Button1Click(TObject *Sender)
{
 ?????
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.02.2018, 02:54
Ответы с готовыми решениями:

Модальные формы
Добрый день, возникла очередная проблема - делаю вывод на печать модальной формой, в коде главного прописала #include...

Модальные формы
Всем добого дня! Помогите пожалуйста, мне нужно написать любую мнооконную программу с модальными формами... нам задали в институте, а мы...

Как сделать чтобы 2 модальные формы не конфликтовали между собой?
Добрый день! Как сделать чтобы 2 модальные формы не конфликтовали между собой? Заранее спасибо за ответ.

44
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.02.2018, 03:51
Цитата Сообщение от dia3do Посмотреть сообщение
Но почему-то в пособиях рекомендуют использовать следующую конструкцию для вызова и закрытия модальных форм:
Выкиньте пособие и пользуйте документацию по VCL. Форму нужно создавать при помощи Application->CreateForm. А выравнивать по центру вызывающей формы при помощи свойства Position которое задает относительно какого элемента выравниваться при открытии. При этомв подавляющем большинстве случаев нет абсолютно никаких причин создавать формы перед открытием если это не дочерние MDI формы которых может быть одновременно открыто много. Удалять же форму после закрытия в любом случае нужно не так а указывая CloseAction=caFree в обработчике события CloseQuery. Но опять же не имеет асболютно ни какого смысла динамически создавать и потом удалять формы не являющиеся дочерними MDI формами.

Добавлено через 12 минут
Цитата Сообщение от dia3do Посмотреть сообщение
TFormX * FormX = new TFormX(0);
А за 0 в качестве владельца (компонента ответственного за удаление) автору пособия вообще руки оторвать надо. В общем вывод - тому кто пособие писал нужно сортиры драить а не программировать учить.

Добавлено через 41 минуту
dia3do, В общем ставишь Form3 в автосоздание, выставляешь ей в ObjectInspector Position=poOwnerCenter а обработчик который ее открывает выглядит вот так:
C++
1
2
3
4
void __fastcall TForm2::Button1Click(TObject *Sender){
      Form3->ShowModal();
     // обработка результатов ввода.
}
И никуда она между закрытиями/открытиями не денется. Если препод что то придраться попробует - попроси его сначала предъявиить сертификат разработчика выданный Борланд или Эмбаркадеро.
1
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
21.02.2018, 17:24
Цитата Сообщение от dia3do Посмотреть сообщение
Но почему-то в пособиях рекомендуют использовать следующую конструкцию для вызова и закрытия модальных форм:
Все верно там написано. Если создаешь форму - должен позаботится об ее удалении.

Добавлено через 1 минуту
Цитата Сообщение от dia3do Посмотреть сообщение
не получится ее закрыть обычным способом:
Ошибка в том что если форма модальная, логично что ее должен закрывать пользователь, а не кодом.

Добавлено через 1 минуту
Цитата Сообщение от dia3do Посмотреть сообщение
C++
1
2
frm3->Left=Screen->Width/2-frm3->ClientWidth/2; //выравниваем форму по центру f
rm3->Top=Screen->Height/2-frm3->ClientHeight/2; //выравниваем форму по центру
У формы есть специальное свойство отвечающие за выравнивание на экране.

Добавлено через 2 минуты
Цитата Сообщение от dia3do Посмотреть сообщение
Ведь из Unit.cpp удалено TForm3 *Form3, из Unit.h удалено extern PACKAGE TForm3 *Form3, вроде как из-за того, что форма создается не автоматически,
А вот это мне не понятно.
В настройках проекта есть возможность задавать формы которые создаются автоматически и которые будут создаваться кодом. Именно через эти настройки и правильно задавать. Удалять в коде ничего не нужно.
1
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
21.02.2018, 18:02
Цитата Сообщение от Avazart Посмотреть сообщение
Если создаешь форму - должен позаботится об ее удалении.
ЕЕ надо создавать в ручную только если она MDI. А тем более если она диалоговая и нужна много раз удалять ее после каждого закрытия не имеет никакого смысла. И управлять этим вопросом гораздо лучше из события запроса на закрытие. Изучи для начала что такое список слабого владения потом попытайся понять почему такие финты нафиг не нужны.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
21.02.2018, 18:14
Fulcrum_013, Глупости.
Комментировать Ваш бред не вижу смысла.
Отвечу только на вопросы ТС.
1
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 3
25.02.2018, 02:29  [ТС]
Собственно способ от Fulcrum_013 работает, главное ведь все очень просто Спасибо.
Отдельное спасибо за свойство центровки на экране))

Ну раз уж разговор зашел за управление формами, в каких случаях их нужно удалять?
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 09:50
dia3do, Когда это MDI формы. Но MDI это не модальные формы. Их одинаковых может понадобится неизвестное заранее количество. Поэтому они создаются и добавляются в менеджер форм перед открытием, а при запросе на закрытие нужно давать команду менеджеру форм закрываемую форму удалять.

Добавлено через 15 минут
dia3do, Да кстати еще один ньюанс. У кнопки есть свойство ModalResult. если оно назначено оно автоматически назначается форме при нажатии на кнопку.
Т.е.вместо
C++
1
2
3
4
void __fastcall TForm3::Button1Click(TObject *Sender)
{
 ModalResult = mrClose; //форма № 3 закрывается
}
можно в ObjectInspector поставить этой кнопке ModalResult в mrClose;
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2018, 13:16
Цитата Сообщение от dia3do Посмотреть сообщение
Ну раз уж разговор зашел за управление формами, в каких случаях их нужно удалять?
Зависит от ситуации. Но в большинстве случаев всегда, для того что бы в памяти не висела.

dia3do, хотите слушать идиотские советы Fulcrum_013 - удачи, но я бы советовал почитать книги Архангельского.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 13:28
Avazart, Это у тебя советы идиотские. У приложения есть менеджер форм который отслеживает как жизненный цикл так и открытие закрытие и модальный приоритет. При этом запихивать в модальную очередь форму не привязанную к менеджеру форм идея прямо скажем не очень здравая. Не знаю где этот Архангельский с VCL работать учился но я и VCL изнутри изучал и подобные менеджеры форм сам реализовывал.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2018, 13:59
Вы С++ не можете изучить, Вы хотите что бы я поверил что изучали исходники на Delphi?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
У приложения есть менеджер форм
Опять выдуманное понятие, нет никакого менеджера форм.

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
35
36
37
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
  Instance: TComponent;
begin
  // Set flag that TCustomForm constructor can read, so it knows if it's being
  // created as a main form or not (required when MainFormOnTaskbar is True)
  FCreatingMainForm := (FMainForm = nil) and InstanceClass.InheritsFrom(TForm);
  Instance := nil;
  try
{$IF DEFINED(CLR)}
    Instance := InstanceClass.Create(Self);
    Reference := Instance;
{$ELSE}
    Instance := TComponent(InstanceClass.NewInstance);
    TComponent(Reference) := Instance;
    try
      Instance.Create(Self);
    except
      TComponent(Reference) := nil;
      Instance := nil;
      raise;
    end;
{$ENDIF}
 
    if (FMainForm = nil) and (Instance is TForm) then
    begin
      TForm(Instance).HandleNeeded;
      FMainForm := TForm(Instance);
      if MainFormOnTaskBar then
        SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_NOACTIVATE);
      ChangeAppWindow(Handle, not MainFormOnTaskBar, not MainFormOnTaskBar);
    end;
  finally
    if (FMainForm = nil) and (Instance is TForm) then
      TForm(Instance).FCreatingMainForm := False;
  end;
end;
В данном случае видно что CreateForm не дает никаких преимуществ перед созданием через new как это принято в С++.

Добавлено через 5 минут
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А за 0 в качестве владельца (компонента ответственного за удаление) автору пособия вообще руки оторвать надо. В общем вывод - тому кто пособие писал нужно сортиры драить а не программировать учить.
Если создаешь/удаляешь компонент руками, нет большой разницы передавать 0 или передавать владельцу.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 14:45
Цитата Сообщение от Avazart Посмотреть сообщение
Опять выдуманное понятие, нет никакого менеджера форм.
А TApplication это что по твоему? При этом отсутствие чего либо приводящего к неработоспособности формы созданной сторонними методами в текущей реализации TApplication абсолютно не гарантирует такое же положение дел в последующих реализациях.
Цитата Сообщение от Avazart Посмотреть сообщение
Если создаешь/удаляешь компонент руками, нет большой разницы передавать 0 или передавать владельцу.
В данном конкретном случае разница в том что ее на каждое открытие создавать не имеет вообще никакого смысла. А вообще разница есть когда создаешь пачку компонентов. Например панель и набор контролов на ней. Потом точно так же пихают нуль каждому контролу и имеют очень большие вопросы как потом все это разобрать обратно.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2018, 14:51
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А TApplication это что по твоему?
А переводчик что говорит?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
При этом отсутствие чего либо приводящего к неработоспособности формы созданной сторонними методами в текущей реализации TApplication абсолютно не гарантирует такое же положение дел в последующих реализациях.
Это ничего не гарантирует.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 14:55
Цитата Сообщение от Avazart Посмотреть сообщение
Это ничего не гарантирует.
Правильно. Вот поэтому и создавать нужно через CreateForm чтобы в последующих версиях гарантированно работало.
Цитата Сообщение от Avazart Посмотреть сообщение
А переводчик что говорит?
А типа оконное приложение менеджментом форм и отслеживанием модальной очереди ни разу не занимается?
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2018, 14:57
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Правильно. Вот поэтому и создавать нужно через CreateForm чтобы в последующих версиях гарантированно работало.
Буквально 0 смысла.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А типа оконное приложение менеджментом форм и отслеживанием модальной очереди ни разу не занимается?
Еще одно выдуманное Вами понятие.

Прям бери и записывай ...
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 15:21
Цитата Сообщение от Avazart Посмотреть сообщение
Буквально 0 смысла.
Смысл в том что если нарастят функционал TApplication добавив к примеру возможность создания визардов/форм авторизации /сплешскринов запускаемых перед основным приложением и т.п. могут появится неоднозначности куда именно созданную через new форму пихать. При этом реализовывать альтернативные версии TApplication тоже никто не запрещает. С CreateForm такой неоднозначности точно не будет а следственно и с переносом кода создающего формы из проекта в проект.
Цитата Сообщение от Avazart Посмотреть сообщение
Еще одно выдуманное Вами понятие.
Вообще то модальные окна еще имеют название стековые окна потому что закрываются в порядке строго обратном открытию. А стек еще называется FILO-очередь.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2018, 15:25
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Смысл в том что если нарастят функционал
Опять выдумки.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Вообще то модальные окна еще имеют название стековые окна потому что закрываются в порядке строго обратном открытию. А стек еще называется FILO-очередь.
Ок, допустим что Вы это не выдумали, на минуту, откуда это вы взяли/прочитали?

Гуглим, читаем

Модальное окно в графическом интерфейсе пользователя — окно, которое блокирует работу пользователя с родительским приложением до тех пор, пока пользователь это окно не закроет. Модальными преимущественно реализованы диалоговые окна. Также модальные окна часто используются для привлечения внимания пользователя к важному событию или критической ситуации[1]
https://ru.wikipedia.org/wiki/... 0%BD%D0%BE
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 15:32
Цитата Сообщение от Avazart Посмотреть сообщение
Опять выдумки.
Почему выдумки? Как раз наличие специально выделенного метода CreateForm там где в общем то на текущем этапе могут обойтись без него как раз и говорит о том что такая точка расширения в исхоже зарезервированна.
Цитата Сообщение от Avazart Посмотреть сообщение
Ок, допустим что Вы это не выдумали, на минуту, откуда это вы взяли/прочитали?
Это давно было. Еще во времена Turbo Vision. Да и опять же в любом случае нужно контролировать возможность получения фокуса ввода формой т.е. отключать/включать такую возможность у родительской и других немодальных формы приложения. Это по сути FILO-очередь даже если она не везде явно видна.
0
25.02.2018, 15:36

Не по теме:

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А стек еще называется FILO-очередь
:wall:Откуда такая страсть к переворачиванию всего с ног на голову? Стек - это LIFO очередь вообще-то. FILO глаз и слух просто режет.

0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2018, 15:37
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Почему выдумки? Как раз наличие специально выделенного метода CreateForm там где в общем то на текущем этапе могут обойтись без него как раз и говорит о том что такая точка расширения в исхоже зарезервированна.
Это ничего не говорит. Как нет ничего говорящего о том что поведение будет другим в будущем.


Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Это давно было. Еще во времена Turbo Vision. Да и опять же в любом случае нужно контролировать возможность получения фокуса ввода формой т.е. отключать/включать такую возможность у родительской формы. Это по сути FILO-очередь даже если она не везде явно видна.
Опять моразм.
Можно легко по-гулить Ваши "термины" и понять что Вы не от мира сего.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
25.02.2018, 16:03
Avazart, точно так же не гуглится к примеру пересечение 4D цилиндров. Но это не значит что такого не существует.

Добавлено через 19 минут
Цитата Сообщение от Avazart Посмотреть сообщение
Это ничего не говорит. Как нет ничего говорящего о том что поведение будет другим в будущем.
Как раз это и говорит о том что поведение может изменится в будущем или в альтернативной реализации TApplication. При этом этого может абсолютно достаточно для того чтобы использовать исключительно то что гарантированно останется корректным в случае если это произойдет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.02.2018, 16:03
Помогаю со студенческими работами здесь

Несколько ToolBar и работа с ними
Добрый день. Подскажите, пожалуйста, каким образом организовать работу нескольких тулбаров, чтобы они автоматически выравнивались по...

Модальные и не модальные формы. Почему уничтожаются не модальные формы?
Приложение сотоит из нескольких форм. Все они взяимосвязаны мужду собой т.е. обмениваются данными. Для этого я их всех объявляю как...

Формы и работа между ними
Всем привет. Кто подскажет в чём ошибка. Имеем Form1 с label1(в Form1.Designer.cs указал что label1 - public вместо private). Далее на...

Модальные формы
Доброго времени суток! Что это значит? Модальные? Не понятно объясните пожалуйста.

Модальные формы
помогите понять модальные формы? вобщем вот в чем проблема. unit Unit1; interface uses Windows, Messages, SysUtils,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru