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

Вниз

Как лучше закрыть несколко одинаковых форм?   Найти похожие ветки 

 
Дмитрий Белькевич   (2009-06-04 14:00) [0]

Есть некоторое количество одинаковых форм. Они могут быть на одном мониторе, либо на нескольких. Быть как MDI, так и SDI. При закрытии одной из них нужно по некоторому критерию (формы "связаны" через специальный идентификатор) закрывать некоторые другие с таким же идентификатором.

Как такое лучше орагинизовать?


 
Медвежонок Пятачок ©   (2009-06-04 14:02) [1]

сообчениями лучше


 
Дмитрий Белькевич   (2009-06-04 14:16) [2]

Если так сделать в FormClose, то каждая закрывающаяся форма будет опять всем рассылать сообщение. Хорошо ли это?


 
Медвежонок Пятачок ©   (2009-06-04 14:42) [3]

а если не в FormClose то не будет.
А если и будет то что?


 
Дмитрий Белькевич   (2009-06-04 14:44) [4]

>а если не в FormClose то не будет.

И куда лучше? В OnDestroy? Попробую... Боюсь зацикливания форм друг на друга...


 
Медвежонок Пятачок ©   (2009-06-04 14:44) [5]

рассыл надо делать под кнопкой "закрыть все"


 
Медвежонок Пятачок ©   (2009-06-04 14:47) [6]

никакого зацикливания не будет даже если в OnClose это сделать


 
Игорь Шевченко ©   (2009-06-04 14:48) [7]

Я бы отправлял сообщение главной форме - закрой все такие же.


> Если так сделать в FormClose, то каждая закрывающаяся форма
> будет опять всем рассылать сообщение. Хорошо ли это?


Такое можно сделать в обработчике Wm_SysCommand :)


 
Дмитрий Белькевич   (2009-06-04 15:01) [8]


> Я бы отправлял сообщение главной форме - закрой все такие
> же.


И все другие при закрытии будут тоже сообщение посылать - закрой все такие же...


> Такое можно сделать в обработчике Wm_SysCommand :)


Сделал пока в OnDestroy, вроде пока живёт, погоняю еще...


 
Игорь Шевченко ©   (2009-06-04 15:05) [9]


> И все другие при закрытии будут тоже сообщение посылать
> - закрой все такие же...


если в OnDestroy и посылать через PostMessage - ничего страшного, деструктор выполнится до того, как будет выбрано сообщение


 
Медвежонок Пятачок ©   (2009-06-04 15:11) [10]

И все другие при закрытии будут тоже сообщение посылать - закрой все такие же...

Если юзер успеет нажать в них кнопку "закрыть все такие" после того, как он нажал ее же в активной форме


 
Дмитрий Белькевич   (2009-06-04 15:39) [11]


> если в OnDestroy и посылать через PostMessage - ничего страшного,
>  деструктор выполнится до того, как будет выбрано сообщение


Я еще и разрушение объекта вызываю до посылки сообщения, что бы форма сама себе мессагу не прислала... Параноя ;) Смысла, наверно, немного - всё равно очередь будет уже убита.


 
Дмитрий Белькевич   (2009-06-04 15:44) [12]


> Если юзер успеет нажать в них кнопку "закрыть все такие"
> после того, как он нажал ее же в активной форме


OnDestroy у всех случается, вообще-то... Только что если, как Игорь советовал, Wm_SysCommand ловить.


 
Игорь Шевченко ©   (2009-06-04 15:54) [13]


> Смысла, наверно, немного - всё равно очередь будет уже убита.


какая именно очередь ?


 
Дмитрий Белькевич   (2009-06-04 16:27) [14]


> какая именно очередь ?


Очередь окна, которое только что разрушалось и послало всем остальным (но уже не самому себе) об этом сообщение.


 
Игорь Шевченко ©   (2009-06-04 17:45) [15]

Дмитрий Белькевич   (04.06.09 16:27) [14]


> Очередь окна


У окон нет очередей


 
Юрий Зотов ©   (2009-06-04 17:46) [16]

1. Сообщение рассылать из деструктора.

2. При получении сообщения:
if not (csDestroying inComponentState) then Release;


 
Игорь Шевченко ©   (2009-06-04 18:18) [17]


> if not (csDestroying inComponentState) then Release;


Я что-то не могу представить ситуацию, когда сообщение может быть получено при csDestroying in ComponentState


 
Медвежонок Пятачок ©   (2009-06-04 18:22) [18]

if LParam <> Handle then Release


 
Юрий Зотов ©   (2009-06-05 04:42) [19]

> Игорь Шевченко ©   (04.06.09 18:18) [17]

А это смотря что понимать под словом "сообщение". Не обязательно интерпретировать его именно как сообщение Windows. Например, это может быть вызов какого-то метода (аналог Notification).


 
Дмитрий Белькевич   (2009-06-05 12:07) [20]

>У окон нет очередей

Имел в виду форму...


 
Игорь Шевченко ©   (2009-06-05 12:24) [21]


> Имел в виду форму...


У форм вроде тоже нет. Очереди (сообщений) есть у потоков - одна очередь на все сообщения всем окнам потока


 
MsGuns ©   (2009-06-05 15:10) [22]

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


 
MsGuns ©   (2009-06-05 15:18) [23]

Если же закрыытие всех однотипных форм нужно выполнять автоматически, то добавить глобальную переменную-флажок и его обработку:

- в процедуре закрытия в начале кода поднимать его, а в конце опускать
- в событиях OnClose  дочек проверять его и если он поднят, то никаких действий не производить.

В результате вызов закрывающей процедуры будет выполнен только один раз - при обращении формы-инициатора, остальные закрываемые формы закроются мовчки ;)


 
Медвежонок Пятачок ©   (2009-06-05 15:50) [24]

остается только выйти из кода вызвавшего метод главной формы


 
Юрий Зотов ©   (2009-06-07 11:28) [25]

Unit1:

type
 TForm1 = class(TForm)
   btnCreate1: TButton;
   btnCreate2: TButton;
   procedure btnCreate1Click(Sender: TObject);
   procedure btnCreate2Click(Sender: TObject);
 protected
   procedure Notification(AComponent: TComponent; Operation: TOperation); override;
 end;

procedure TForm1.btnCreate1Click(Sender: TObject);
begin
 TForm2.Create(Self, 1).Show
end;

procedure TForm1.btnCreate2Click(Sender: TObject);
begin
 TForm2.Create(Self, 2).Show
end;

procedure TForm1.Notification(AComponent: TComponent; Operation: TOperation);
var
 i: integer;
begin
 inherited;
 if (Operation = opRemove) and not (csDestroying in ComponentState) and (AComponent is TForm2) then
   for i := ComponentCount - 1 downto 0 do
     if (Components[i] is TForm2) and not (csDestroying in Components[i].ComponentState)
       and (Components[i].Tag = AComponent.Tag) then
       TForm2(Components[i]).Close

end;

Unit2:

type
 TForm2 = class(TForm)
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 public
   constructor Create(AOwner: TComponent; ATag: integer); reintroduce; overload;
 end;

constructor TForm2.Create(AOwner: TComponent; ATag: integer);
begin
 inherited Create(AOwner);
 Tag := ATag;
 Caption := IntToStr(Tag)
end;

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


 
Kolan ©   (2009-07-23 16:40) [26]

О закрытии надо уведомлять контроллер, который и должен закрывать все подобные.


 
KSergey ©   (2009-07-24 14:28) [27]

> Kolan ©   (23.07.09 16:40) [26]
> О закрытии надо уведомлять контроллер, который и должен закрывать все подобные.

Автор опасается, что "каждое подобное" при своём закрытии будет снова уведомлять контроллер о необзодимости "закрыть все подобные". Другое участинки предлагают как этого избехать или не бояться.


 
Kolan ©   (2009-07-24 15:44) [28]

KSergey, передайте автору, что я предлагаю использовать флаг. :)

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

Принципиальный код:

procedure CloseEventHandler;
begin
 if ReactOnClose then
 begin
   ReactOnClose := False;
   try
     for ... do
       Form[I].Close;
   finally
     ReactOnClose := True;
   end;  
 end;
end;


 
Дмитрий Белькевич   (2009-07-25 21:52) [29]

Окончательно. В FormDestroy:


for i := 0 to Screen.FormCount - 1 do
 if Screen.Forms[i] is TForm14 then
  PostMessage(Screen.Forms[i].Handle, FM_CLOSE14, SeriesID, Handle);


Обработчик сообщения:


procedure TForm14.Form14Close(var Msg: TMessage);
begin
if Msg.WParam = SeriesID then
 Close;
end;


Похоже, что работает... И само себя себя не успевает повторно вызывать - умирает раньше. Можно было бы дополнительно на совпедение передаваемого Hadle"а с Handle"ом Self"а проверять, но убрал - работает и без этого.


 
Kolan ©   (2009-07-28 13:56) [30]

Как-то очень не универсально. Для остальных 13 форма свои циклы и константы FM_CLOSExx?


 
Дмитрий Белькевич   (2009-07-28 16:04) [31]

>Как-то очень не универсально. Для остальных 13 форма свои циклы и константы FM_CLOSExx?

Нет - у меня 14-тых форм может быть 4-5 штук, а то и больше. Остальных - по одной.



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

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

Наверх





Память: 0.52 MB
Время: 0.003 c
2-1292846680
harisma
2010-12-20 15:04
2011.03.13
Работа с реестром в 64-разрядной ОС


3-1254859922
Дмитрий
2009-10-07 00:12
2011.03.13
Нет коннекта с сервером


15-1290775632
digger
2010-11-26 15:47
2011.03.13
IE 7 не показывает png файлы


15-1291223827
Haradzienski
2010-12-01 20:17
2011.03.13
Книги по Дэлфи


2-1292862496
v_a_belousov
2010-12-20 19:28
2011.03.13
Авторизация в программе





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский