如何检测鼠标何时离开Delphi 6中的TPanel?

Sna*_*ore 6 delphi vcl

我正在使用OnMouseMove事件来检测鼠标指针何时在我的TPanel上,有没有办法知道鼠标指针何时离开它?

当鼠标指针悬停在面板上时,我需要面板改变颜色,一旦它离开它就恢复原来的颜色?

我顺便使用Delphi 6.

请帮忙.

最好的祝福.

klu*_*udg 8

您可以使用OnMouseEnter/OnMouseLeave事件对来检测鼠标

procedure TForm1.Panel1MouseEnter(Sender: TObject);
begin
  Panel1.Caption:= 'IN';
  Panel1.Color:= clBlue;
end;

procedure TForm1.Panel1MouseLeave(Sender: TObject);
begin
  Panel1.Caption:= 'OUT';
  Panel1.Color:= clWhite;
end;
Run Code Online (Sandbox Code Playgroud)

我无法在Delphi 6中测试以下代码,但我希望它没问题

更新

添加了TrackMouseEvent代码 - 感谢Sertac Akyuz的回答

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
    FOldWndProc: TWndMethod;
    FMouseInPanel: Boolean;
    procedure PanelWndProc(var Message: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FOldWndProc:= Panel1.WindowProc;
  Panel1.WindowProc:= PanelWndProc;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Panel1.WindowProc:= FOldWndProc;
end;

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  mEvnt: TTrackMouseEvent;
begin
  if not FMouseInPanel then begin
    mEvnt.cbSize := SizeOf(mEvnt);
    mEvnt.dwFlags := TME_LEAVE;
    mEvnt.hwndTrack := Panel1.Handle;
    TrackMouseEvent(mEvnt);
    Panel1.Caption:= 'IN';
    FMouseInPanel:= True;
  end;
end;

// if not defined in Delphi 6, WM_MOUSELEAVE = $02A3
procedure TForm1.PanelWndProc(var Message: TMessage);
begin
  if Message.Msg = WM_MOUSELEAVE then begin
    Panel1.Caption:= 'OUT';
    FMouseInPanel:= False;
  end;
  FOldWndProc(Message);
end;

end.
Run Code Online (Sandbox Code Playgroud)

  • 如果未在"TrackMouseEvent"中指定窗口,则不会发布AFAIK"WM_MOUSELEAVE". (2认同)

Ser*_*yuz 6

另一个解决方案,TrackMouseEvent用于接收WM_MOUSELEAVE;

type
  TMyPanel = class(TPanel)
  private
    FMouseTracking: Boolean;
    FOnMouseLeave: TNotifyEvent;
    procedure WMMouseLeave(var Msg: TMessage); message WM_MOUSELEAVE;
  protected
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  published
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

procedure TMyPanel.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  mEvnt: TTrackMouseEvent;
begin
  inherited;
  if not FMouseTracking then begin
    mEvnt.cbSize := SizeOf(mEvnt);
    mEvnt.dwFlags := TME_LEAVE;
    mEvnt.hwndTrack := Handle;
    TrackMouseEvent(mEvnt);
    FMouseTracking := True;
  end;
end;

procedure TMyPanel.WMMouseLeave(var Msg: TMessage);
begin
  Msg.Result := 0;
  FMouseTracking := False;
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;
Run Code Online (Sandbox Code Playgroud)