RRU*_*RUZ 8

Andreas解决方案的另一个替代方案是使用CM_MOUSELEAVE已在delphi 7中定义的VCL消息.

使用内插器类检查此示例 TButton

type
  TButton = class(StdCtrls.TButton)
  private
    FOnMouseLeave: TNotifyEvent;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;


  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private
     procedure ButtonMouseLeave(Sender: TObject);
  public
  end;

//handle the message and call the event handler
procedure TButton.CMMouseLeave(var Message: TMessage);
begin
  if (Message.LParam = 0) and Assigned(FOnMouseLeave) then
      FOnMouseLeave(Self);
end;


procedure TForm1.ButtonMouseLeave(Sender: TObject);
begin
   //your code goes here   
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //assign the event
  Button1.OnMouseLeave:=ButtonMouseLeave;
end;
Run Code Online (Sandbox Code Playgroud)

  • @Andreas我认为,这将适用于那种情况,实际上这种方式与现代版本的Delphi如何实现此事件非常相似. (3认同)

And*_*and 6

WM_MOUSELEAVE当鼠标离开控件时,您可以告诉Windows向您发送消息,更具体地说是消息.为此,请调用该TrackMouseEvent函数.在TRACKMOUSEEVENT结构中,指定TME_LEAVE标志.

根据要求,一些代码:

创建控件后,如果鼠标位于控件的客户区域内,请告诉Windows您要通知鼠标离开控件:

procedure TMyControl.SetMouseEvent;
var
  tme: TTrackMouseEvent;
begin
  tme.cbSize := sizeof(tme);
  tme.dwFlags := TME_LEAVE;
  tme.hwndTrack := Self.Handle;
  TrackMouseEvent(tme);
end;
Run Code Online (Sandbox Code Playgroud)

创建控件并且鼠标位于控件内部时,请调用此过程.现在你只需要听一下WM_MOUSELEAVE消息.在您的WndProc过程(类的受保护成员)中,添加一个WM_MOUSELEAVE案例.

procedure TMyControl.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
    WM_MOUSELEAVE:
      beep;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我认为Windows在创建消息时会删除通知请求,因此您必须在收到消息后重新请求通知.你不能打电话SetMouseEventWndProc,因为鼠标需要,当你调用控件的客户端区域内TrackMouseEvent.我想你可以把你的SetMouseEvent内部放在OnMouseMove控件内:

procedure TMyControl.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
    WM_MOUSELEAVE:
      beep;
    WM_MOUSEMOVE:
      SetMouseEvent;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我之前没有测试过上面的代码,因为我使用的是Delphi的新版本,Delphi 2009,它在幕后做了类似的事情(我想,因为现在OnMouseLeave控件中有一个事件),我认为会干扰.