Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.08.07;
Скачать: [xml.tar.bz2];

Вниз

MDI приложение, работа с формами   Найти похожие ветки 

 
Juice ©   (2005-07-19 15:42) [0]

Перевожу приложение в MDI  и возник один вопрос. Есть child-форма, и в ее обработчике закрытия пишу так:

procedure TdlgPortf.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Action := caFree;
end;

Все ОК, теперь при закрытии формы она действ. закрывается а не просто сворачивается. Вот проблема в том чтобы при потребности ее повторного отображения создать ее в случае если она разрушена и просто показать ее если она создана. Как узнать что форма разрушена ? Такой код приводит к ошибке:

if dlgPortf<>nil then
   dlgPortf.Show  
 else
   dlgPortf.Create(self);


 
msguns ©   (2005-07-19 15:44) [1]

MDIChildCount, MDIChildren


 
msguns ©   (2005-07-19 15:46) [2]

Чтобы код в сабже заработал, необходимо в событии OnDestroy дочки обнулить указатель на нее в гл.форме (dlgPortf)


 
Юрий Зотов ©   (2005-07-19 15:48) [3]

procedure TdlgPortf.FormDestroy(Sender: TObject)
begin
 dlgPortf := nil
end;

И все заработает.

Только нелогично это. Ваш код не позволяет создать более одной дочерней формы - а тогда зачем же нужен MDI? Ведь смысл этого интерфейса прямо противоположный.


 
Гаврила ©   (2005-07-19 16:11) [4]


> if dlgPortf<>nil then
>    dlgPortf.Show  
>  else
>    dlgPortf.Create(self);


Это еще что такое? надеюсь, опечатка?

пиши просто
TdlgPortf.Create(Application), а глобальную переменную dlgPortf  снеси нафиг
я бы так сделал


 
APXi   (2005-07-19 16:34) [5]

>пиши просто
>TdlgPortf.Create(Application), а глобальную переменную
>dlgPortf  снеси нафиг

а как потом к этой форме обращаться из других форм? Постоянно искать в MDIChildren?


 
Юрий Зотов ©   (2005-07-19 16:38) [6]

> APXi   (19.07.05 16:34) [5]

> как потом к этой форме обращаться из других форм?
> Постоянно искать в MDIChildren?

Ничего искать не придется. Потому что при Вашем подходе никаких других дочерних форм не будет. Будет либо одна, либо ни одной.


 
Гаврила ©   (2005-07-19 16:39) [7]


>  [5] APXi


Если допускается создание нескольких форм класса TdlgPortf, то сносить глоб. переменную надо. А то потом будет при обращении из других форм непонятно, к кому, собственно, идет обращение.

А вообще, имхо, такие обращения не должны иметь место при правильном проектировании, за исключением нотификационных сообщений


 
DiamondShark ©   (2005-07-19 16:49) [8]


> а как потом к этой форме обращаться из других форм? Постоянно
> искать в MDIChildren?

А кроме глобальных переменных больше никакаких методов общения нет?


 
Juice ©   (2005-07-19 17:05) [9]


> dlgPortf.Create(self);
>
> Это еще что такое? надеюсь, опечатка?

Конечно

Я вообще взялся за MDI в целях ознакомления и о дублировании дочки даже не думал, а прочитав все это  решил сделать свое приложение действительно многодокументным. Эта форма порождает другие, между ними должна быть координация, кроме того задействован ActionList. Варианты конечно есть как это все связать между собой , но хотелось бы услышать ваши советы где и как хранить указатели на связаные формы чтобы работа с ними не вызывала лишних проблем.


 
Juice ©   (2005-07-19 17:10) [10]

Например реализовать через цепочку Owner ? Как вы на это смотрите ?


 
DiamondShark ©   (2005-07-19 17:17) [11]


> но хотелось бы услышать ваши советы где и как хранить указатели
> на связаные формы чтобы работа с ними не вызывала лишних
> проблем.

Хранить их там, где они нужны.
Например, если порожлающая форма должна управлять порождаемой, то и хранить указатель в экземпляре порождающей формы.
По-моему, очевидно.


 
Юрий Зотов ©   (2005-07-19 17:20) [12]

> Juice ©   (19.07.05 17:05) [9]

> где и как хранить указатели на связаные формы

1. Раз таких форм может быть много, то хранить их надо уж точно не в единственной скалярной переменной. Посему эту переменную следует снести совсем.

2. По той же причине выбор между Show и Create тоже следует снести. Всегда Create, никаких Show.

3. Где хранить. Во-первых, они и так уже хранятся в MDIChildren. И нужно очень хорошо подумать, нужно ли еще какое-то дополнительное хранилище. Часто оно и не нужно вовсе, бывает достаточно обращения к ActiveMDIChild - если код может быть построен так, что ему без разницы, какая именно форма активна в данный момент.

4. Если же дополнительное хранилище все-таки нужно, то вариантов много - массив, TList, TObjectList, TCollection и т.д. Лично я, скорее всего (хотя выбор зависит от деталей задачи), предпочел бы глобальный TList, а в OnCreate/OnDestroy классов дочерних форм прописал бы автоматическое добавление себя в этот список и удаление себя из него.


 
msguns ©   (2005-07-19 17:52) [13]

Надо же, я делал как советует ЮЗ ;)
В смысле указатели на "дочки" хранил в TList гл.формы. Там же держал еще и некоторые данные, нужные для управления датасетами "дочек", инкапсулированного в датамодуле.


 
Juice ©   (2005-07-19 18:18) [14]

Не все так просто (как мне кажется). Допустим, имеем что-то наподобие такого:
MainMDI -> ChildMDI -> SomeWnd (not MDI, related to ChildMDI)
Т.е. ChildMDI создает форму SomeWnd.
Весь код работы форм ChildMDI и SomeWnd сосредоточен в ActionList"e (находится в отдельном датамодуле). Например в SomeWnd генерируется действие, а в этом действии должны выполняться манипуляции с SomeWnd. Каким образом обработчику действия узнать(сообщить) какая из клонов SomeWnd его вызвала? Обработчик получает параметр Sender, который может указывать и на кнопку и на другой контрол SomeWnd, получается что ему нельзя анализировать Sender.Owner


 
Juice ©   (2005-07-19 19:20) [15]

Или для каждой из цепочек ChildMDI и SomeWnd динамически  создавать новый ActionList ?


 
msguns ©   (2005-07-19 19:37) [16]

Во-первых, если дочка и создает свою форму, то эта форма, имхо, должна быть модальной.
Во-вторых, если управление реализовано через централизованные экшины, то и обращаться из модальной формы (т.к. панели управления Гл.формы недоступны) надо непосредственно к этим экшинам. Т.е. в модуле модальной формы добавить Uses DataModule
Свои же уникальные методы модальная форма обязана реализовывать самостоятельно.


 
Juice ©   (2005-07-19 19:51) [17]


> должна быть модальной

Она и есть модальная

> Свои же уникальные методы модальная форма обязана реализовывать
> самостоятельно.

Так и сделал


 
Defunct ©   (2005-07-20 03:03) [18]

Juice ©   (19.07.05 18:18) [14]

Я делаю так:
при активации MDIChild"а - вешаю на главную форму его ToolBar"ы и пункты меню. При деактивации - убираю. Те самые Action list"ы размещаю либо на фреймах (которые потом кидаю на MDIChild) либо непосредственно на child форме без всяких датамодулей, которые только запутывают структуру и без того сложных программ.

msguns ©   (19.07.05 19:37) [16]
> Во-первых, если дочка и создает свою форму, то эта форма, имхо, должна быть модальной.
Абсолютно верно, иначе глюков необерешься.

> Во-вторых, если управление реализовано через централизованные экшины
Централизованное управление IMHO - горячка (ошибка при проектировании), как для MDI приложения не годится.


 
Юрий Зотов ©   (2005-07-20 05:16) [19]

> Juice ©   (19.07.05 18:18) [14]
> получается что ему нельзя анализировать Sender.Owner

Запросто. Но рекурсивно (или в цикле) - до формы.

Или (для контролов) можно сразу анализировать GetParentForm.

Что и снимает все вопросы.
:о)



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.08.07;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.067 c
4-1118046120
Андрей Жук
2005-06-06 12:22
2005.08.07
Как перечислить потоки, которые привязаны к процессу?


1-1121759874
serguncho
2005-07-19 11:57
2005.08.07
Представление Float на разных машинах


1-1121874412
Igorek
2005-07-20 19:46
2005.08.07
Кодировка файла для чтения/записи из ActiveX обьекта


9-1113910376
[GameDev]
2005-04-19 15:32
2005.08.07
На какой ячейке мышь ?


1-1121449372
lookin
2005-07-15 21:42
2005.08.07
Печать из TStringGrid





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский