delphi - Why does CM_CONTROLLISTCHANGE performs for indirect parent controls? -
i noticed if have main container/parent (mainpanel
), adding child panel (childpanel
), perform cm_controllistchange
on mainpanel
(in twincontrol.insertcontrol()
) fine.
but if insert child control (childbutton
) childpanel
, cm_controllistchange
fired again main mainpanel
!
why that? expecting cm_controllistchange
fire childpanel
when inserting childbutton
childpanel
.
mcve
unit unit1; interface uses windows, messages, sysutils, classes, graphics, controls, forms, dialogs, extctrls, stdctrls; type tmainpanel = class(extctrls.tcustompanel) private procedure cmcontrollistchange(var message: tcmcontrollistchange); message cm_controllistchange; end; tform1 = class(tform) button1: tbutton; memo1: tmemo; procedure button1click(sender: tobject); private public mainpanel: tmainpanel; end; var form1: tform1; implementation {$r *.dfm} procedure tmainpanel.cmcontrollistchange(var message: tcmcontrollistchange); begin if message.inserting begin form1.memo1.lines.add('tmainpanel.cmcontrollistchange: inserting ' + message.control.classname); // parent nil if message.control.parent = nil form1.memo1.lines.add('*** parent=nil'); end; inherited; end; procedure tform1.button1click(sender: tobject); var childpanel: tpanel; childbutton: tbutton; begin freeandnil(mainpanel); mainpanel := tmainpanel.create(self); mainpanel.setbounds(0, 0, 200, 200); mainpanel.parent := self; childpanel := tpanel.create(self); childpanel.parent := mainpanel; childbutton := tbutton.create(self); childbutton.parent := childpanel; // why cm_controllistchange in "mainpanel"? end; end.
dfm
object form1: tform1 left = 192 top = 114 width = 685 height = 275 caption = 'form1' color = clbtnface font.charset = default_charset font.color = clwindowtext font.height = -11 font.name = 'ms shell dlg 2' font.style = [] oldcreateorder = false pixelsperinch = 96 textheight = 13 object button1: tbutton left = 592 top = 8 width = 75 height = 25 caption = 'button1' taborder = 0 onclick = button1click end object memo1: tmemo left = 456 top = 40 width = 209 height = 193 taborder = 1 end end
p.s: don't know if matters, i'm on delphi 5.
this question easy answer using debugger. have done quite readily. enable debug dcus , set breakpoint inside if
statement in tmainpanel.cmcontrollistchange
.
the first time breakpoint fires when child panel inserted. expect, immediate child of main panel being added, child panel. second time breakpoint fires point of interest. that's when child of child panel added.
when breakpoint fires, call stack this:
tmainpanel.cmcontrollistchange((45100, $22420ec, true, 0)) tcontrol.wndproc((45100, 35922156, 1, 0, 8428, 548, 1, 0, 0, 0)) twincontrol.wndproc((45100, 35922156, 1, 0, 8428, 548, 1, 0, 0, 0)) twincontrol.cmcontrollistchange((45100, 35922156, 1, 0, 8428, 548, 1, 0, 0, 0)) tcontrol.wndproc((45100, 35922156, 1, 0, 8428, 548, 1, 0, 0, 0)) twincontrol.wndproc((45100, 35922156, 1, 0, 8428, 548, 1, 0, 0, 0)) tcontrol.perform(45100,35922156,1) twincontrol.insertcontrol($22420ec) tcontrol.setparent($2243dd4) tform1.button1click(???)
at point can inspect call stack double clicking on each item. i'd start @ tform1.button1click
confirms indeed responding childbutton.parent := childpanel
. work way list.
two items come twincontrol.insertcontrol
, when double click on item find:
perform(cm_controllistchange, integer(acontrol), integer(true));
here, acontrol
button, , self
child panel. let's continue far twincontrol.cmcontrollistchange
. now, message handled, , still have self
being child panel. body of function is:
procedure twincontrol.cmcontrollistchange(var message: tmessage); begin if fparent <> nil fparent.windowproc(message); end;
and answer puzzle. vcl propagates message parent chain. call leads top of call stack, tmainpanel.cmcontrollistchange
, self
main panel, fparent
in call twincontrol.cmcontrollistchange
.
i know have pointed @ twincontrol.cmcontrollistchange
, have answered question directly. want make point such questions quite readily resolved relatively simple debugging.
note have debugged delphi 6 closest readily available version delphi 5 have, principles outlined here, , answer remain valid in versions.
Comments
Post a Comment