Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как лучше закрыть несколко одинаковых форм? [D7, WinXP]


Страницы:   1 2

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

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

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


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

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

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


Kolan   (2009-07-28 13:56:00) [2]

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


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

Окончательно. В 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-24 15:44:00) [4]

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

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

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

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


KSergey   (2009-07-24 14:28:00) [5]

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

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


Kolan   (2009-07-23 16:40:00) [6]

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


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

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;


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

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


MsGuns   (2009-06-05 15:18:00) [9]

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

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

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


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

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


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


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


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


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

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

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


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

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

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


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

if LParam <> Handle then Release


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


> if not (csDestroying inComponentState) then Release;


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


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

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

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


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

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


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


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


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


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


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


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


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


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


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


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


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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо