关于消息的一问题(50分)

  • 主题发起人 主题发起人 awfigsk
  • 开始时间 开始时间
A

awfigsk

Unregistered / Unconfirmed
GUEST, unregistred user!
假设:在一个窗口有一个TButton组件,当单击TButton组件后,会产生二个消息,这里我想问的是:[red]为何这二个消息会调用主窗体的WndProc,而不是调用TButton本身的WndProc [/red]?

窗体和窗体所包含组件,当在组件处理组件产生的消息是一个什么样的过程?
还请各位富翁指点,谢谢!
 
这个问题,你要看一下李维大师的InsideVCL就可以有答案了。
其实你跟踪一下调用堆栈也能发现这个现象。

Windows消息确实是直接发给Button控件本身的。
可是Delphi处理消息的流程是,
先让“标准控件”处理这个消息,然后通过MainWndProc,将消息传递到Form上,
最后再派发到本控件。处理“Delphi控件”(封装部分)自定义消息,如Click等等。

这里的原因,我想Delphi主要是考虑让所有控件的处理方式一致,包括CustomControl和GraphiControl不同体系派生的控件,包括Windows标准控件和自定义控件。

这样的好处,
第一、统一
第二、可以预处理
第三、使用了Delphi自己的消息机制,可以调用到message方法,在TObject中是用Dispatch方法
 
对,呵,我正是在看这本书,看到这章不明白,[red]是不是在窗体上的组件所产生的消息都是先发送到窗体的wndproc处理,如果在窗体的wndproc没有被处理就会被一级一级的传送,最后送到了组件本身的wndproc或相关的消息处理过程中[/red]?

我记得在看window程序设计一书时上面也提到过窗体中的子组件产生的消息也会先被窗体的窗口过程进行处理。

可以这样理解吗?
 
窗体上按钮的click事件是通过wm_command来通知它的父窗体的。而且要调用它自己的父类来处理这个click事件。
 
TForm1.Button1Click($D637E8)
TControl.Click
TButton.Click
TButton.CNCommand((48401, 1256, 0, 591080, 0))
TControl.WndProc((48401, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
TWinControl.WndProc((48401, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
TButtonControl.WndProc((48401, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
TControl.Perform(48401,1256,591080)
DoControlMsg(591080,(no value))
TWinControl.WMCommand((273, 1256, 0, 591080, 0))
TCustomForm.WMCommand((273, 1256, 0, 591080, 0))
TControl.WndProc((273, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
TWinControl.WndProc((273, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
TCustomForm.WndProc((273, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
TWinControl.MainWndProc((273, 1256, 591080, 0, 1256, 0, 1256, 9, 0, 0))
StdWndProc(591168,273,1256,591080)
TWinControl.DefaultHandler((no value))
TControl.WMLButtonUp((514, 0, 37, 16, (37, 16), 0))
TControl.WndProc((514, 0, 1048613, 0, 0, 0, 37, 16, 0, 0))
TWinControl.WndProc((514, 0, 1048613, 0, 0, 0, 37, 16, 0, 0))
TButtonControl.WndProc((514, 0, 1048613, 0, 0, 0, 37, 16, 0, 0))
TWinControl.MainWndProc((514, 0, 1048613, 0, 0, 0, 37, 16, 0, 0))
StdWndProc(591080,514,0,1048613)
TApplication.ProcessMessage((591080, 514, 0, 1048613, 1781328, (481, 336)))
TApplication.HandleMessage
TApplication.Run
Project1
整个的调用顺序由下至上
 
啊,楼上用什么东西得到这么详细的?还是说手打的?PFPF
 
呵。多谢各位,我明白了!结贴!
 
后退
顶部