Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.03.13;
Скачать: CL | DM;

Вниз

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

 
Дмитрий Белькевич   (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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.008 c
15-1291052230
polkin
2010-11-29 20:37
2011.03.13
SHA1


15-1290806981
Юрий
2010-11-27 00:29
2011.03.13
С днем рождения ! 27 ноября 2010 суббота


1-1248707578
Oleg
2009-07-27 19:12
2011.03.13
Docking


2-1292936617
adigozelov
2010-12-21 16:03
2011.03.13
Struktur db


1-1248865008
pan2905
2009-07-29 14:56
2011.03.13
TXMLDocument: ошибка: "Не был произведен вызов CoInitialize"