看Delphi如何把操作系统的消息转化为控件的事件的
在操作系统中是把中断转化为消息发送个各个窗体的。那么消息又是如何转换为在程序设计中的事件的呢?
中断经过封装变为消息在系统中流动,消息又被封装为事件。当事物被封装了几次之后略一看就变的有点神奇了。
--定义事件
TMouseEvent = procedure(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer) of object;
--定义控件
TControl = class(TComponent)
private
FOnMouseDown: TMouseEvent;
//最接近消息的过程
procedure DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
Shift: TShiftState);
//从操作系统中捕获消息
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); dynamic;
//最接近客户定义的外部事件处理过程的属性
property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
end;
procedure TControl.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
//如果在代码中定义了事件就去执行事件
if Assigned(FOnMouseDown) then
FOnMouseDown(Self, Button, Shift, X, Y);
end;
//在此方法中调用外部函数
procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
Shift: TShiftState);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do
if (Width > 32768) or (Height > 32768) then
with CalcCursorPos do
MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y)
else
MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);
end;
//从操作系统中捕获消息
procedure TControl.WMLButtonDown(var Message: TWMLButtonDown);
begin
SendCancelMode(Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := True;
if csClickEvents in ControlStyle then Include(FControlState, csClicked);
//把消息传递给方法
DoMouseDown(Message, mbLeft, []);
end;