Форум: "Основная";
Текущий архив: 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