powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Закрытие MDIChild-формы
18 сообщений из 43, страница 2 из 2
Закрытие MDIChild-формы
    #39780369
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так создавайте изначально так, чтобы такой формы небыло
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
function CreateForm(FormClass: TMdiBaseFormClass): TMdiBaseForm;
var i: Integer;
begin
  for i := 0 to MDIChildCount - 1 do
    if MDIChildren[i].ClassType = FormClass then begin
      Result := MDIChildren[i] as TMdiBaseForm;
      Exit;
    end
  Result :=  FormClass.Create(Application);
end;
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780370
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch2) иметь один единственный реестр в приложении - глобальную переменную

А ещё лучше не глобальную, а локальную для класса

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Type TMdiBaseForm = class
...
private // или strict private или protected
   class var FRegistry: TList<TMdiBaseForm>; 
   class constructor CreateReg;
   class destructor FreeReg;

...

class constructor TMdiBaseFormCreateReg;
begin
   FRegistry := TList<TMdiBaseForm>.Create;
   FRegistry.Capacity := 32; 
   inherited;
end;

class destructor TMdiBaseForm.FreeReg;
begin
   FRegistry.Free; 
   inherited;
end;
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780371
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochgoldmi45Arioch,

Зачем создавать то, что уже есть?

MDIChildren и MDIChildCount

1) лаконичнее. Одна строка - вызов стандартной функции TList<t>.Contains гораздо меньше, чем расписанный вами if с циклами. Следовательно, меньше шансов тупой ошибки.

Да, Contains лаконичнее. Но ошибка может вкрасться на другом этапе (к примеру, забыв добавить переменную в список). И кода будет ни сколько не меньше: необходимо создавать список, его удалять, добавлять в него переменную. Возможно, необходимы отдельные методы, как у вас.

Arioch2) гибче. Например, в дальнейшем нужно будет иметь несколько MDI-Parent окон. Или с MDI будет переход на что-то другое (табы, докающиеся плавающие окна, ...)
Согласен. Код имеет ограничения и вы предлагаете более гибкий подход.
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780375
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBrНу так создавайте изначально так, чтобы такой формы небыло
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
function CreateForm(FormClass: TMdiBaseFormClass): TMdiBaseForm;
var i: Integer; 
begin
  for i := 0 to MDIChildCount - 1 do 
    if MDIChildren[i].ClassType = FormClass then begin
      Result := MDIChildren[i] as TMdiBaseForm;
      Exit;
    end
  Result :=  FormClass.Create(Application);
end;



Дважды вызывать функцию MDIChildren[i] - долго и потенциально моежт привести к опискам (например - несколько циклом, или индексы более разнообразные и сложные)

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
{.$Define hackyhack} // :-D

function CreateForm1(const FormClass: TMdiBaseFormClass): TMdiBaseForm;
var i: Integer; F: TForm {$IfDef hackyhack} absolute Result {$EndIf};
begin
  for i := 0 to MDIChildCount - 1 do begin
    F := MDIChildren[i];
    if F.ClassType = FormClass then 
{$IfDef hackyhack}
      Exit;
{$Else}
      Exit( F as TMdiBaseForm );
  end;
  Result :=  FormClass.Create(Application);
end;

function CreateForm2(const FormClass: TMdiBaseFormClass): TMdiBaseForm;
begin
  if not MyDictionary.TryGetValue( FormClass, Result ) then
  begin
    Result :=  FormClass.Create(Application);
    MyDictionary.Add( FormClass, Reuslt );
  end;
end;
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780383
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
client6aacНо за наставление на путь истинный - спасибо!

в общем, несколько вариантов тебе накидали, плюсы-минусы упомянули, планировтаь будущее программы и оценивать их - дело уже твоё.

главное, не забывай, что "90% кода в интернете - говно" - https://www.gunsmoker.ru/2010/05/90.html
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780388
client6aac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ToAll
Я приятно удивлен, что вроде такой пустяковый вопросик вызвал такую достаточно бурную и конструктивную реакцию комьюнити.
Всем спасибо!
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780434
Фотография LocksmithPC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему нельзя открыть (создать) дочернюю форму два раза?

У меня вообще все дочерние формы создаются TfrmMDIChild.Create(Self); Надо сотню открыть? На здоровье!
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780492
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Якобы, задача такая, что не надо.
Скрестим пальцы, чтобы он не ошибся.


Есть тезис "не изобретать велосипеды"

goldmi45Зачем создавать то, что уже есть?

MDIChildren и MDIChildCo

И есть тезис "писать программу так, как будто через год её будет дописывать маньяк-убийца, которому расскажут, где живёт твоя семья"

zinpubНо Arioch прав, гораздо лучше реестр окон, в который можно добавить собственные свойства\методы

При этом тезис
client6aacВ текущей логике приложения как раз и нужно открытие окошек в единственном экземпляре.

- это ставка в азартной игре "угадай, как дела обстоят не в реальности, а на самом деле".
Обычно мы угадываем, но иногда ошибаемся.
Очевидно, что заранее мы не знаем, где ошибёмся, иначе не ошиблись бы

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

Пример - да хотя бы вечный срач про контроль типов (строгий / не строгий / никакого и статический / динамический), например https://www.sql.ru/forum/1309685/incompatible-types.

Собираем мой бред в кучку.

goldmi45Зачем создавать то, что уже есть?

MDIChildren и MDIChildCo

"Бизюзловно" - прозюзюкала Зази.

Если программа пишется на один раз и через неделю её выкинут на помойку навсегода - то экономия на велосипедах сыграет.
Если "В текущей логике приложения как раз и нужно" и ни-ког-да никакой другйо логики не будет.

Но! если "другая логика" всё же случится, то "в класс-реестр можно добавить собственные свойства\методы".
А это значит, что в само объявление этих методов (списки/типы параметров, названия) можно зашить "требования к реальному миру". И при нарушении этих требований - компиляция сломается. И это - хороший код

DimaBr
Код: pascal
1.
function CreateForm(FormClass: TMdiBaseFormClass): TMdiBaseForm;


Тут мы предполагаем, что "TMdiBaseFormClass" - полный и уникальный идентификатор формы.
ЕСЛИ потом у нас будут несколько форм одного класса, то будет что-то вроде

Код: pascal
1.
2.
3.
4.
5.
6.
7.
type RMDIFormID = record
  FormClass: TMdiBaseFormClass;
  ProjectPath: TFileName;
  DocumentNo: cardinal;
end;

function CreateForm(const FormClass: RMDIFormID): TMdiBaseForm;



После этого всё позабытые нами вызовы "CreateFrom( MySuperMDIClass )" просто не соберутся. Даже если мы захотим их пропустить - Delphi не даст.

Но это - объявление метода.
А вот сам цикл - все равно будет собираться.

DimaBr
Код: pascal
1.
2.
3.
4.
5.
6.
  for i := 0 to MDIChildCount - 1 do
    if MDIChildren[i].ClassType = FormClass then begin
      Result := MDIChildren[i] as TMdiBaseForm;
      Exit;
    end
  Result :=  FormClass.Create(Application);



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

Таким образом, использование этого "из коробки" функционала - это очень сильная ставка на YAGNI.

Ну и "охотничья байка".
Есть стандартный срач в БД - суррогатный или натуральный должен быть ключ таблиц.
Должен ли уникальный идентификатор строки в таблице иметь реальный смысл или быть полностью очищен от любых пересечений с реальностью.

Несколько лет назад мне надо было быстро сделать самописку для внутренних нужд компании.
Среди прочего там была таблицы контрагентов - юр/лиц.
В качестве Primary Key я там поставил ИНН. Сразу многие запросы стали проще, а при просмотре вторичных таблиц вместу асбтрактного случайного номера - был реальный и осмысленный ИНН. Удобно и быстро.

....перед этим я всю контору обошёл и у всех спросил, могут ли в России быть два юр-лица с одинаковым ИНН. И мне все сказали, что конечно же нет, и вообще "программе это никогда не понадобится". Ну и я "срезал угол". Тем более, что надо было быстро.

Прошло полгода. У самописки появились пользователи, у пользователей появились привычки, в БД появились данные.

И вдруг ко мне приходят и говорят, что программа остановила работу. Надо ввести контр-агента ,а не получается, ругается на повтор ИНН.

- значит, вы его уже раньше ввели в БД, берите готовый.
- нет, тот "Василёк", а нужен "Ромашка".
- значит "Василёк" переименовался в ромашку. Переименуйте в БД и используйте.
- нет, это разные юр-лица и нам нужны ОБА СРАЗУ
- если это разные юр-лица, то у них и ИНН разные, ищите опечатку.
- нет опечаток. Юр-лица разные, а ИНН общий
- ЧТО ????

...оказалось, что хотя вообще-то ИНН - "индивидуальный номер", но конкретно у филиалов банокв в разных городах ИНН был общий, а различались только КПП.

Но ИНН уже был PK, на него уже были построены многие Foreign Key, но это были завязаны запросы и куски кода. И всё это уже было полгода в реальной работе.

....а мне надо бросив все срочно вспомнить как та программа писалась, сделать ИНН неуникальным - в программе и БД, и при этом не потерять данные, ни в чём не изменить поведение программы, и чтобы никто из пользователей вообще не заметил обновления.

...но вообще конечно же, YAGNI и "В текущей логике приложения как раз и нужно"
Делайте ваши ставки, господа!
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780547
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AriochДелайте ваши ставки, господа!
а ты не мог бы сказать то же самое, но покороче?
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780552
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док,

- Долго ли умеючи?
- Умеючи-то долго!
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780554
client6aac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
экак Вас поперло... пора уже выдыхать:D
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39780821
AJi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
AJi
Гость
У меня обычно используется вот такой вариант:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class function TMdiBaseFormClass.ExistForm: TMdiBaseFormClass;
var
  n: Integer;
begin
  Result := nil;
  for n := 0 to Screen.FormCount - 1 do
    if Screen.Forms[n].ClassName = Self.ClassName then begin
      Result := Screen.Forms[n] as TMdiBaseFormClass;
      Break;
    end;
end;



Туда же можно засунуть и создание формы, при желании.
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39781070
maratvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
client6aac,

на дороге MDI вы еще не дошли до вопроса "Как сделать, чтобы при максимизации одного окна, другие оставались в нормальном состоянии?" и иже с ними. Может вам не надо MDI, а то придется велосипедить долго и упорно. :)
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39782394
Фотография Old Nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем вообще переменная?

Код: pascal
1.
2.
3.
4.
5.
6.
procedure TMainForm.OnClickButton1(Sender: TObject);
var frm: TMdiBaseForm;
begin
  frm := TMdiPriceSelectForm.Create(Application);
  frm.Show;
end;



После выхода из метода переменная сама обнулится.
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39782761
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Old NickА зачем вообще переменная?

Код: pascal
1.
2.
3.
4.
5.
6.
procedure TMainForm.OnClickButton1(Sender: TObject);
var frm: TMdiBaseForm;
begin
  frm := TMdiPriceSelectForm.Create(Application);
  frm.Show;
end;



После выхода из метода переменная сама обнулится.

А зачем вообще переменная? Если она не нужна - так и не нужно ее делать.
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TMainForm.OnClickButton1(Sender: TObject);
begin
  with TMdiPriceSelectForm.Create(Application) do begin
    Show;
  end;
end;
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39782769
Фотография LocksmithPC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fraks, зачем вообще Show?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
  with TOpenDialog.Create(Self) do
    try
      if Execute then
        TMdiPriceSelectForm.Create(Self, FileName);

    finally
      Free;

    end;
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39782787
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТСу необходимо создавать в единственном экземпляре дочерние окна. Последние три писателя - нечитатели.
...
Рейтинг: 0 / 0
Закрытие MDIChild-формы
    #39782793
Фотография LocksmithPC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45, ого, да ты гения!
...
Рейтинг: 0 / 0
18 сообщений из 43, страница 2 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Закрытие MDIChild-формы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]