Wu50Feng

许多年以后,希望能看到自己留下的脚印

 

看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;

posted on 2005-12-16 13:19  Dany  阅读(667)  评论(0编辑  收藏  举报

导航