事件处理程序到底是谁调用的 ( 积分: 100 )

  • 主题发起人 主题发起人 sjjwan
  • 开始时间 开始时间
S

sjjwan

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在对一个问题老是不解!
事件处理程序到底是谁调用的,调用者又是怎么把实际参数传给它的!
比如这个 procedure TForm1.StringGrid1SelectCell(Sender: TObject
ACol,
ARow: Integer
var CanSelect: Boolean);事件处理程序,人在选择不同的单元时,调用者是怎么得到不同的实际参数传给ACol,ARow这两个形式参数的。
它跟消息处理程序又有什么关系?
 
我现在对一个问题老是不解!
事件处理程序到底是谁调用的,调用者又是怎么把实际参数传给它的!
比如这个 procedure TForm1.StringGrid1SelectCell(Sender: TObject
ACol,
ARow: Integer
var CanSelect: Boolean);事件处理程序,人在选择不同的单元时,调用者是怎么得到不同的实际参数传给ACol,ARow这两个形式参数的。
它跟消息处理程序又有什么关系?
 
看VCL源码!

一般理解:
鼠标点击产生LBUTTONDOWN消息 ->
processmessage收到,遣至StringGrid的窗口处理过程 ->
查找窗口句柄对应的VCL对象(Sender参数) ->
HitTest鼠标位置(计算判断点击在哪一单元格内,ACol、ARow参数) ->
if 存在事件处理过程 then 调用过程 ->
if CanSelect then 构建编辑框并处于被选择状态
...
 
首先,一个delphi应用程序通过如下步骤进入消息循环
Application.Run->HandleMessage->ProcessMessage

消息处理过程大概如下:
事件->windows转换为消息->系统消息队列->线程消息队列->PeekMessage->TranslateMessage->DispatchMessage->VCL提供的消息处理回掉函数(delphi为了能让类消息处理方法来代替传统的以pascal方式调用的windows回调函数,使用很多技巧,这包括thunk技术,函数调用类型转换技术等等)->通过一系列中间过程到达众所周知的wndproc->(以下只针对一种情况来将)查找可处理相应消息的动态方法(delphi为了节约空间,通常将末端处理消息的过程声明为dynamic方式)->调用诸如DoXXX之类的过程(这步不是必须的)->在该动态方法中或DoXXX中查找FOnXXX变量是否赋值(它实际上就是对应你申明的消息处理过程)->执行->回到消息循环

当然如果当前类没有能力处理该消息,则会进行一长串的调用,最终由Windows的defwndproc好处理。这里就不多说了。
 
后退
顶部