Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: Закрытие MDIChild-формы  [new]
DimaBr
Member

Откуда:
Сообщений: 10994
Ну так создавайте изначально так, чтобы такой формы небыло
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;
28 фев 19, 13:41    [21821722]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Arioch
Member

Откуда:
Сообщений: 10807
Arioch
2) иметь один единственный реестр в приложении - глобальную переменную


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

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;
28 фев 19, 13:42    [21821723]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
goldmi45
Member

Откуда:
Сообщений: 1132
Arioch
goldmi45
Arioch,

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

MDIChildren и MDIChildCount


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

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

Arioch
2) гибче. Например, в дальнейшем нужно будет иметь несколько MDI-Parent окон. Или с MDI будет переход на что-то другое (табы, докающиеся плавающие окна, ...)

Согласен. Код имеет ограничения и вы предлагаете более гибкий подход.
28 фев 19, 13:42    [21821724]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Arioch
Member

Откуда:
Сообщений: 10807
DimaBr
Ну так создавайте изначально так, чтобы такой формы небыло
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] - долго и потенциально моежт привести к опискам (например - несколько циклом, или индексы более разнообразные и сложные)

{.$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;
28 фев 19, 13:50    [21821733]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Arioch
Member

Откуда:
Сообщений: 10807
client6aac
Но за наставление на путь истинный - спасибо!


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

главное, не забывай, что "90% кода в интернете - говно" - https://www.gunsmoker.ru/2010/05/90.html
28 фев 19, 14:02    [21821748]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
client6aac
Member

Откуда:
Сообщений: 16
ToAll
Я приятно удивлен, что вроде такой пустяковый вопросик вызвал такую достаточно бурную и конструктивную реакцию комьюнити.
Всем спасибо!
28 фев 19, 14:10    [21821754]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
LocksmithPC
Member

Откуда:
Сообщений: 178
А почему нельзя открыть (создать) дочернюю форму два раза?

У меня вообще все дочерние формы создаются TfrmMDIChild.Create(Self); Надо сотню открыть? На здоровье!
28 фев 19, 14:56    [21821833]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Arioch
Member

Откуда:
Сообщений: 10807
Якобы, задача такая, что не надо.
Скрестим пальцы, чтобы он не ошибся.


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

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

MDIChildren и MDIChildCo


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

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


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


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

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

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

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

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

MDIChildren и MDIChildCo


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

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

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

DimaBr
function CreateForm(FormClass: TMdiBaseFormClass): TMdiBaseForm;

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

type RMDIFormID = record
  FormClass: TMdiBaseFormClass;
  ProjectPath: TFileName;
  DocumentNo: cardinal;
end;

function CreateForm(const FormClass: RMDIFormID): TMdiBaseForm;


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

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

DimaBr
  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 и "В текущей логике приложения как раз и нужно"
Делайте ваши ставки, господа!
28 фев 19, 16:19    [21821939]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Док
Member

Откуда: Казань
Сообщений: 6131
Arioch
Делайте ваши ставки, господа!

а ты не мог бы сказать то же самое, но покороче? Картинка с другого сайта.

К сообщению приложен файл. Размер - 104Kb
28 фев 19, 17:31    [21822025]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Arioch
Member

Откуда:
Сообщений: 10807
Док,

- Долго ли умеючи?
- Умеючи-то долго!

К сообщению приложен файл. Размер - 55Kb
28 фев 19, 17:39    [21822033]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
client6aac
Member

Откуда:
Сообщений: 16
экак Вас поперло... пора уже выдыхать:D
28 фев 19, 17:44    [21822036]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
AJi
Member

Откуда: Москва
Сообщений: 72
У меня обычно используется вот такой вариант:

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;


Туда же можно засунуть и создание формы, при желании.
1 мар 19, 10:48    [21822479]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
maratvg
Member

Откуда: 74
Сообщений: 111
client6aac,

на дороге MDI вы еще не дошли до вопроса "Как сделать, чтобы при максимизации одного окна, другие оставались в нормальном состоянии?" и иже с ними. Может вам не надо MDI, а то придется велосипедить долго и упорно. :)
1 мар 19, 15:15    [21822810]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
Old Nick
Member

Откуда: Санкт-Петербург
Сообщений: 3103
А зачем вообще переменная?

procedure TMainForm.OnClickButton1(Sender: TObject);
var frm: TMdiBaseForm;
begin
  frm := TMdiPriceSelectForm.Create(Application);
  frm.Show;
end;


После выхода из метода переменная сама обнулится.
5 мар 19, 11:13    [21825164]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
fraks
Member

Откуда: Новосибирск
Сообщений: 1435
Old Nick
А зачем вообще переменная?

procedure TMainForm.OnClickButton1(Sender: TObject);
var frm: TMdiBaseForm;
begin
  frm := TMdiPriceSelectForm.Create(Application);
  frm.Show;
end;


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


А зачем вообще переменная? Если она не нужна - так и не нужно ее делать.
procedure TMainForm.OnClickButton1(Sender: TObject);
begin
  with TMdiPriceSelectForm.Create(Application) do begin
    Show;
  end;
end;
6 мар 19, 04:36    [21825869]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
LocksmithPC
Member

Откуда:
Сообщений: 178
fraks, зачем вообще Show?

  with TOpenDialog.Create(Self) do
    try
      if Execute then
        TMdiPriceSelectForm.Create(Self, FileName);

    finally
      Free;

    end;
6 мар 19, 06:03    [21825880]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
goldmi45
Member

Откуда:
Сообщений: 1132
ТСу необходимо создавать в единственном экземпляре дочерние окна. Последние три писателя - нечитатели.
6 мар 19, 08:53    [21825909]     Ответить | Цитировать Сообщить модератору
 Re: Закрытие MDIChild-формы  [new]
LocksmithPC
Member

Откуда:
Сообщений: 178
goldmi45, ого, да ты гения!
6 мар 19, 09:35    [21825925]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Delphi Ответить