How to detect when the mouse move away from a TPanel in Delphi 6?
I am using the OnMouseMove event to detect when the mouse pointer is over my TPanel, is there a way to know when the mouse pointer had moved away from it?
I need the panel to change colour when the mouse pointer is over it and return to its original colour once it moved away from it?
I am using Delphi 6 by the way.
Please help.
Best Regards开发者_运维知识库.
You can use OnMouseEnter/OnMouseLeave event pair to detect mouse
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;
I can't test the following code in Delphi 6, but I hope it is OK
Updated
TrackMouseEvent code added - thanks to Sertac Akyuz answer
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.
Yet another solution, using TrackMouseEvent
to receive 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;
If you don't have OnMouseEnter and OnMouseLeave then use OnMouseMove and capture the mouse to your panel. Capturing the mouse is slightly more work but the effects are better.
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;
OnMouseLeave. Beware that you also need to see if the mouse left the whole application as I've had OnMouseLeave not fire when the panel was on the edge of the form and I went off the form.
Create your own component derived from the TCustomPanel
(or TPanel
), since Delphi 6 doesn't have the MouseEnter and MouseLeave events on by default, you can add them yourself. Add this to the private section of your declaration section:
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
Afterwards it is all about handling the mouseenter and mouseleave events:
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;
Hope this helps. If the color doesn't show up add this to your components constructor:
ControlStyle := ControlStyle - [csParentBackground] + [csOpaque];
thanks for the help. To me work very well, I make a new bitbtn control derived from original bitbtn and implements the mouseenter and mouse leave, with Delphi 7. Follow my code:
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 - Brazil
精彩评论