Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_4415.html
 

Событие закрытия дочерней формы.

Опубликовано 29.04.2010 г. 23:51

Недавно меня озадачили вопросом, как отловить момент закрытия дочерней формы. Должен вызываться onActivate,- подумал я сразу, дак нет. И как же все таки отловить подобное событие? Задача стояла следующая: есть главная форма, с нее открываются модальные дочерние. При закрытии дочерней модальной формы требуется произвести некоторые операции. Поэтому сразу и подумалось что должно сработать OnActivate главной формы, ведь по идее после закрытия модальной, основное окно получает фокус и становится активным. Но нет, такого не произошло. Второе что придумалось, в принципе как вариант логичное - сделать общую процедуру для показа модальных окон. Т.е допустим при нажатии на N-ную кнопку создается N-ная форма. Для этого создадим процедуру которая будет получать объект TForm, вызывать его showModal, и потом производить нужные действия.

procedure TMainForm.ShowModalAndDoAction(form : TForm);
begin
    form.showModal();
    do_something_here();
end;

procedure TMainForm.ButtonNClck(sender:TObject);
var form : TForm;
begin
    form := TForm.Create(self);
    ShowModalAndDoAction(form);
    form.free;
end;

Либо даже не только показывать, но и вообще создавать нужное окно, отображать, а потом производить операции, т.е если у нас на форме N кнопок, каждая из которых только и делает, что создает форму класса TFormN показывает ее модально, потом освобождает память, и тут то нам надо провести наши операции.

type TFormN = class(TForm);
...

procedure TMainForm.ShowModalAndDoAction(formClass : TFormСlass);
begin
    with formClass.Create(self) do begin
        ShowModal();
        free();
    end;
    do_something_here();
end;

procedure TMainForm.ButtonNClck(sender:TObject);
begin
    ShowModalAndDoAction(TFormN);
end;

Далее придумалась бредовая мысль, что если все дочерние формы унаследовать не от TForm а от своего класса, в котором переписать onDestroy таким образом, чтобы он вызывал метод главной форме, или отправлял сообщение. Но этот вариант в принципе реализуем, но не особо как то интересен. Далее мысль скакнула в сторону сообщений. Почему бы собственно и нет? Форма закрылась - должно разослаться сообщение. Пробежался по списку сообщений, кажется вот оно - WM_PARENTNOTIFY. Вот что нам сообщает MSDN:

The WM_PARENTNOTIFY message is sent to the parent of a child window when the child window is created or destroyed .... When the child window is being destroyed, the system sends the message before any processing to destroy the window takes place

кажется то что надо.. окей. далее

wParam The low-order word of wParam specifies the event for which the parent is being notified. This parameter can be one of the following values. WM_CREATE - The child window is being created. WM_DESTROY - The child window is being destroyed. .... LOWORD(wParam) - Meaning of HIWORD(wParam) WM_CREATE - Identifier of the child window. WM_DESTROY - Identifier of the child window.

кажется все ясно и понятно: получили сообщение, если старшее слово от wParam = WM_DESTROY то форма закрылась и в WParamLo имеем ее идентификатор. Долго не раздумывая пишем:

  private 
    procedure wmParentNotify(var msg:  TMessage); message WM_PARENTNOTIFY;
...
procedure TMainForm.wmParentNotify(var msg:TMessage);
begin 
   inherited;
   if msg.wParaHi = WM_DESTROY then begin
        showMessage('form closed!');
        msg.result := 0;
   end; 
end;

Ну или по крайней мере как то так. Запускаем, создаем дочернюю форму, закрываем иии... и ничего. Да, я так и не понял что с этим всем делать, если кто нить расскажет то буду рад (: все таки решение нашлось, но не совсем общее, хотя поставленную задачу решает идеально. Если с формой ничего не выходит, то может быть Application в чем нибудь сможет помочь? Смотрим свойства, методы.. modalStarted, modalFinished.. modalLevel, onModalStart и наконец onModalEnd. Итак, при вызове showModal формы, вызывается процедура onModalStarted, которая увеличивает счетчик modalLevel, далее если текущий modalLevel = 0 (т.е не открыты модальные формы) и назначено событие onModalStart, то это событие и вызывается. Аналогичная ситуация возникает при закрытии модальной формы: вызов modalFinished, уменьшение счетчика, и если уровень равен нулю, и назначено событие, то вызывается OnModalEnd. События эти самые обычные TNotifyEvent = procedure(Sender:TObject) of object, т.е указатели на процедуру с параметром типа TObject. Одна проблема, при вызове данного события, логично было бы предположить что sender это именно форма, которая закрывается, но нет - sender = Application. Т.е получить какую либо информацию о закрывающейся форме не получится. Что же выходит в итоге: при создании главной формы назначаем событие которое будет вызываться при закрытии модальной формы первого уровня. в нашем случае - процедура ChildFormClosed.

  private
    procedure ChildFormClosed(sender:TObject);
...

procedure TMainForm.FormCreate(Sender: TObject);
begin
    application.OnModalEnd := ChildFormClosed;
end;

procedure TMainForm.ChildFormClosed(sender:TObject);
begin
       ShowMessage('childForm Closed!');
end;

Да, можно, конечно, было воспользоваться объектом TApplicationEvents с панели инструментов Additional, но сути дела это не меняет. Вопрос о том, как же все таки в приложении перехватывать закрытия произвольных, в том числе не модальных окон, остается загадкой для меня. Все таки хочется думать что надо колдовать что то с WM_PARENTNOTIFY.. написано что это сообщение должны получать все окна до самого главного, причем не важно модальное было окно или нет, а в добавок еще и идентификатор окна получим, и сможем узнать что за окно закрылось. Кстати из расширенных свойств у каждой формы есть свойство WS_EX_NOPARENTNOTIFY, установив которое, при закрытии формы сие сообщение не рассылается. этот стиль по умолчанию имеют диалоговые окна. Использование тестового окна у которого заведомо не установлено это свойство все равно не дало результата при обработке данного сообщения.

 form := TForm.Create(self);
SetWindowLong(form.handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
Метки:  forms  |  messages  |  modal windows 

Комментарии

dymken
30.04.2010 в 23:25
Объект Screen, свойство Screen.ActiveForm и событие OnActiveFormChange не подойдут?
ter
01.05.2010 в 00:08
маловероятно, судя по названию это свойство и метод отображают текущую активную форму, и метод вызывающийся при смене активной формы. Как это соотнести вообще с закрытием дочерней формы я не представляю, т.е понятно что при закрытии дочерней (если она была активной), активной станет родительская например, и вызовется данный метод, но это всего лишь один из вариантов когда данный метод вызывается.
stokito
03.05.2010 в 11:54
эмм я бегло прочитал и не понял, а чем вам событие OnClose не нравиться? Делаете фабричный метод "создать дочернюю форму" в нём созадёте её, назначаете настроки и обработчики событий например на закрытие. У меня в проекте всё прекрасно работало и никаких проблем.
ter
03.05.2010 в 12:42
В условиях уже написанного проекта, когда все формы уже есть, у всех их есть уже различные свои обработчики onClose, хотелось перехватить просто закрытие произвольной формы, а про метод для создания формы я писал, да (:
Leechdraw
06.05.2010 в 14:29
А вариант вот такой не пробовали:
Дочерняя форма в событии OnClose посылает сообщение с определенным кодом кодом. А главная форма просо ждет этого сообщения и на это реагирует? Мы тут нечто подобное делали, но у нас было несколько больший гимор - дочерние формы вызывались из dll и при этом немодально. Ну то есть имеем несколько проблем - дочерние формы должны быть в единственно экземпляре, дочерние dll цепляются динамически и заранее неизвестно сколько их и они могут быть модальными и не очень ;) Тут собственно единственное решение которое мы нашли - это обмен сообщениями. Ведь дочерняя форма всегда имеет хендл родительской и может ей послать сообщение. Ну, а внедрить такое в уже существующий проект думаю тоже не сложно - достаточно описать слушателя для сообщений ну константу сообщения задать. Извините если не понятно изъясняюсь, я просто довольно слабо теоретически подкован - больше по хелпу делал. :)
ter
06.05.2010 в 19:21
дак понятно что можно у дочерних форм дописать onClose чтобы они чего нить куда нить посылали, или выполняли какой нибудь метод, но мне почему то кажется разумным что при закрытии формы вообще должно само по себе отправляться какое то сообщение.
т.е суть загвоздки в том, получить такое событие, не модифицируя код дочерних форм.
McFly
31.05.2010 в 21:58
procedure TMainForm.wmParentNotify(var msg:TMessage);
begin
inherited;
if msg.wParaHi = WM_DESTROY then begin
_______________________________________________

правильно :
if msg.wParaLo = WM_DESTROY then begin
ter
01.06.2010 в 10:36
действительно. в процитированном мной куске документации так и написано. странно что у меня иначе (: хотя помнится я там всяко разно пробовал :)) и как то не работало :)
DesweR
06.12.2012 в 12:59
if TWMParentNotify(Msg).Event = WM_DESTROY then
;-)
Cantona
21.08.2013 в 17:06
WM_DESTROY, WM_CREATE - не работает(
работает WM_RBUTTONDOWN
cheap car insurance online
11.08.2017 в 18:39
best auto insurance
[url="https://7auto24insurance.org/"]cheapest car insurance[/url]
cheapest car insurance
cheap auto insurance online
do auto insurance rates go up after age 70
[url=http://kocaelidenizyildizlari.com/index.php?option=com_k2&view=itemlist&task=user&id=25791]worst auto insurance companies
to work for[/url]
auto insurance trinidad
auto insurance portland
cheap car insurance online
18.08.2017 в 09:43
car insurance quotes
[url=http://carxxinsurancexx.org/]cheap auto insurance[/url]
cheap car insurance
cheap auto insurance
loans for bad credit
21.08.2017 в 15:02
payday loans
[url=http://lucrativeloans.org/]pay day loans[/url]
payday loans
cash advance
cheap car insurance
02.09.2017 в 17:38
https://getinsurancenowfast.org/ - progressive
car insurance
auto insurance quotes
cheap auto insurance
payday loans online
13.09.2017 в 09:27
http://getloansusapersonal.com/ - loan online
payday loans online
loans online
payday express
14.09.2017 в 07:33
http://cashlucrative.org/ - payday loans
cash advance
cash advance
direct deposit advance
27.09.2017 в 01:59
https://loanswayer.com - i need a loan asap
quick loans for bad credit
secured personal loan
auto insurance nm
29.09.2017 в 00:22
https://easycarup.com/ - auto insurance bundles
auto insurance unemployed
auto insurance essay
auto insurance with accidents
03.10.2017 в 06:02
http://p-ion.ru/?option=com_k2&view=itemlist&task=user&id=49971 - worst auto insurance
company houston tx
auto insurance who needs it
what auto insurance should i have
cheap car insurance
08.10.2017 в 15:02
car insurance quotes
cheap auto insurance
cheap car insurance
car insurance quotes
generic zithromax
10.10.2017 в 02:23
zithromax price
zithromax 500 mg
zithromax z-pak buy online
generic zithromax
zithromax antibiotic
10.10.2017 в 21:04
zithromax antibiotic
zithromax 500 mg
zuthromax 1000 mg
zithromax 500 mg
auto insurance verification
13.10.2017 в 12:56
auto insurance arkansas
do auto insurance ask for ss number
auto insurance declaration page
how much +for car insurance
online loans
22.10.2017 в 00:24
cash advance loan
online loan
cash loans
online loans
new online casino
23.10.2017 в 19:31
slot machine
online roulette
casino usa
online slots
new slot
23.10.2017 в 23:42
slots lv
slots
fruit machines online
real money slot
slots canada online
celebrex buy line
25.10.2017 в 23:27
celebrex sale
cheap generic celebrex
cheapest price for celebrex
where to buy generic celebrex
discount card for celebrex
new casino
26.10.2017 в 13:18
money slot
slot sites
best slot games
blackjack online
best online casinos
online casino usa
02.11.2017 в 19:06
casino games
free casino games
casino online usa
real money casino
casino games
03.11.2017 в 16:39
online casino canada
casino slots
casino games
slot machines
slot machine comma 6
08.11.2017 в 20:27
progressive jackpot Pokies
playing online Pokies
play casino games for cash
online roulette canada real money
loan today
21.11.2017 в 20:45
fast loans
unsecured personal loans for bad credit
secured and unsecured loans
loans for bad credit rating
quick short term loans
online cash advance loans
22.11.2017 в 17:16
bad credit lenders
payday cash
direct payday loans
small personal loans bad credit
i need 1000 dollars now
online lenders
28.11.2017 в 22:53
pay advance
payday loan direct lenders only
online cash advance
loan today
online loans
pay day loan
30.11.2017 в 13:51
online payday loans
cash advance loans
pay day loan
online payday loans
payday loan online
casino online usa
30.11.2017 в 18:24
free casino games
online casino games
online casino games
casino usa
online casino
08.12.2017 в 11:54
free online casino games
free casino games
best us casinos online
slot machines
real money casino online usa
cash loans no credit check
payday loans no credit check
loans for bad credit
payday loans no credit check
payday loans no credit check
online casino
19.12.2017 в 18:55
casino games list
online casino
casino games
online casino
online casino games
payday loans definition
22.12.2017 в 02:52
small personal loans fast
payday loans direct lenders
payday loans online direct lenders
payday loans online same day
payday loans no credit check
22.12.2017 в 16:29
payday loans online no credit check
payday loans no credit check
payday loans no credit
payday loans no credit
payday loans no credit check
real money casino
27.12.2017 в 21:06
online casino
real money casino
online casino
online casino
casino games
loans no credit
05.01.2018 в 23:59
payday loans no credit check
loans for bad credit
payday loans online no credit check
payday loans no credit
payday loans online no credit check
aol slots
06.01.2018 в 16:26
free casino games no download
casino slot games
slots casino games
online casino real money
casino free games
payday loans no credit check
14.01.2018 в 15:13
loans no credit check
loans no credit check
loans no credit check
payday loans no credit
loans no credit check
online casino game
19.01.2018 в 16:56
absolutely free slots for fun
triple diamond slots 5x
casinos in michigan with hotels
free casino games vegas world
best free online casino
auto insurance quotes canada
26.01.2018 в 17:35
car insurance quotes comparison
car insurance companies
cheap car insurance calculator
cheap auto insurance quotes
pills to lose weight
26.01.2018 в 23:30
pills to lose weight
diet supplements
weight loss pill
appetite suppressant
weight loss pills for men
casino g
28.01.2018 в 18:03
casino online subtitrat
online casino no deposit bonus
new usa online casinos
online casinos 2016
prescription weight loss medication
weight loss pill
new weight loss medication
best diet pills for weight loss
weight loss prescription drugs
new usa online casinos 2017
30.01.2018 в 12:02
casino games roulette
new usa online casinos 2017
casino games
online gambling casino
top rated free online casino games
best diet pill available
31.01.2018 в 23:04
best weight loss pills
diet supplements
weight loss tablets
whats the best weight loss supplement
gnc diet pills that really work
weight loss for men
02.02.2018 в 18:16
best diet pills 2018
best diet pills 2018
best diet pills 2018
best diet pills for weight loss
speedy cash payday loans online
05.02.2018 в 18:22
small personal loans fast
best online loans instant approval
payday loans online no credit check
loans online instant approval
cheap auto insurance policy
14.02.2018 в 23:22
auto insurance quotes
car insurance quotes in florida
cheap auto insurance quotes
car insurance quotes online
auto insurance program
17.02.2018 в 23:38
cheap car insurance quotes california
cheap auto insurance quotes
car insurance quotes florida
car insurance quotes florida
I know this if off topic but I'm looking into starting my own blog and was wondering what all is needed to get
set up? I'm assuming having a blog like yours would cost a
pretty penny? I'm not very internet savvy so I'm not 100% certain. Any tips
or advice would be greatly appreciated. Thank you
mezo
25.03.2018 в 13:23
Greetings I am so excited I found your webpage,
I really found you by accident, while I was researching on Google for
something else, Anyways I am here now and would just like
to say cheers for a tremendous post and a all
round thrilling blog (I also love the theme/design), I don’t have time to go through it all at the moment but I have
saved it and also added in your RSS feeds, so when I have time I will be
back to read a great deal more, Please do keep up
the awesome jo.
ready
27.03.2018 в 09:30
Thank you for sharing your thoughts. I truly appreciate your efforts and I am waiting for your next write ups thanks once
again.
Viagra sale coupon
30.03.2018 в 11:46
Fine way of telling, and pleasant piece of writing to take information regarding my presentation topic, which
i am going to present in school.
router login
27.04.2018 в 05:18
I just added your blog to my bookmark sites. thanks.Quality posts is the crucial to invite the visitors to visit the web page, that's what this web page is providing.
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно