TButton是从TButtonControl-TWinControl-TControl一层一层继承下来的,其中TControl中
处理了Windows的WM_LBUTTONUP消息,当鼠标在这个Button上单击并弹起时会传递这个WM_LBUTTONUP
消息给Button,Button收到WM_LBUTTONUP后触发WMLButtonUp消息处理过程,如果这个控件是可单击的
(csClicked in ControlState)并且鼠标位置是在客户区内,就调用Click方法,你看到Click方法中检查
FOnClick这个过程类型的变量是否赋值,其实也就是我们是否写了Button的OnClick事件,如果写了则
通过这个过程类型的变量调用它.
ButtonClick是一个过程名,出现在Events页中就是表示我们在设计的时候就给Button的OnClick事件赋了值,
它的值就是过程ButtonClick(请注意OnClick是过程类型的事件属性,它指向过程类型的成员变量FOnClick),
我们也可以在程序中动态给Button的OnClick事件赋值,而不是在设计时指定:
比如Button.OnClick:=MyButtonClick,只需要定义一个过程MyButtonClick就可.不过这个过程必须是一个对象的成员,
而且它的参数必须是(Sender:TObject);
procedure TControl.DoMouseUp(var Message: TWMMouse; Button: TMouseButton);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do MouseUp(Button, KeysToShiftState(Keys), XPos, YPos);
end;
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
end;
DoMouseUp(Message, mbLeft);
end;
procedure TControl.Click;
begin
{ Call OnClick if assigned and not equal to associated action's OnExecute.
If associated action's OnExecute assigned then call it, otherwise, call
OnClick. }
if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
FOnClick(Self)
else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
ActionLink.Execute(Self)
else if Assigned(FOnClick) then
FOnClick(Self);
end;