我正在使用OnMouseMove事件来检测鼠标指针何时在我的TPanel上,是否有办法知道鼠标指针何时离开它?
当鼠标指针悬停在面板上时,我需要面板改变颜色,一旦它离开它就会恢复原来的颜色吗?
我顺便使用Delphi 6。
请帮忙。
最诚挚的问候。
答案 0 :(得分: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;
我无法在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.
答案 1 :(得分: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;
答案 2 :(得分:4)
如果您没有OnMouseEnter和OnMouseLeave,请使用OnMouseMove并将鼠标捕获到面板。捕获鼠标稍微多一些,但效果更好。
procedure Form1.Panel1MouseMove(Sender:TObject; Shift:TShiftState; X,Y:Integer);
begin
if (X >= 0) and (Y >= 0) and (X < Panel1.Width) and (Y < Panel1.Height) then
begin
// Movement within the panel
if GetCapture <> Panel1.Handle then
begin
// The mouse just moved over the panel. Do your "on enter" stuff
// over here.
SetCapture(Panel1.Handle); // Capture the mouse so we'll receive
// mouse move messages even if the cursor
// is no longer over our panel.
end;
end
else
begin
// Movement outside the panel! This is possible because I've previously
// captured the mouse.
// Do your "move out" stuff over here.
ReleaseCapture; // release mouse capture
end;
end;
答案 3 :(得分:2)
OnMouseLeave在。请注意,您还需要查看鼠标是否已离开整个应用程序,因为当面板位于表单边缘并且我离开表单时,OnMouseLeave不会触发。
答案 4 :(得分:1)
创建自己的TCustomPanel
(或TPanel
)派生的组件,因为Delphi 6默认情况下没有启用MouseEnter和MouseLeave事件,您可以自己添加它们。将其添加到声明部分的私有部分:
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
之后就是处理mouseenter和mouseleave事件了:
procedure TMyPanel.CMMouseEnter(var msg: TMessage);
begin
inherited;
Color := clBlue;
{ Do Whatever }
end;
procedure TMyPanel.CMMouseLeave(var msg: TMessage);
begin
inherited;
Color := clRed;
{ Do Whatever }
end;
希望这会有所帮助。如果颜色没有显示,请将其添加到组件构造函数中:
ControlStyle := ControlStyle - [csParentBackground] + [csOpaque];
答案 5 :(得分:1)
感谢您的帮助。为了让我工作得很好,我使用Delphi 7创建了一个新的bitbtn控件,该控件源自原始bitbtn并实现了mouseenter和mouse leave。遵循我的代码:
TBitBtnPanel = class(TBitBtn) private { Private declarations } FOnMouseLeave: TNotifyEvent; FOnMouseEnter: TNotifyEvent; FActivateMouseLeave: boolean; procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER; procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE; protected { Protected declarations } public { Public declarations } constructor Create(AOwner: TComponent); override; published { Published declarations } property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave; property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter; end; { TBitBtnPanel } procedure TBitBtnPanel.CMMouseEnter(var Msg: TMessage); begin Msg.Result := WM_CANCELMODE; FActivateMouseLeave:=True; if Assigned(FOnMouseEnter) then FOnMouseEnter(Self); end; procedure TBitBtnPanel.CMMouseLeave(var Msg: TMessage); begin if (FActivateMouseLeave) then begin Msg.Result := WM_CANCELMODE; FActivateMouseLeave:=False; if Assigned(FOnMouseLeave) then FOnMouseLeave(Self); end; end; constructor TBitBtnPanel.Create(AOwner: TComponent); begin FActivateMouseLeave:=True; inherited; end;
Hugo Barros - 巴西