Я использую событие OnMouseMove для обнаружения, когда указатель мыши по моему TPanel, есть ли способ знать, когда указатель мыши переехал от него?
Мне нужна панель для изменения цвета, когда указатель мыши по нему, и возвратитесь к его исходному цвету, после того как это переехало от него?
Я использую Delphi 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;
Вы можете использовать пару событий 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.
Если у вас нет 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;
Создайте свой собственный компонент, производный от 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];
OnMouseLeave. Имейте в виду, что вам также нужно проверить, покинула ли мышь все приложение, так как у меня OnMouseLeave не срабатывал, когда панель находилась на краю формы, а я выходил за ее пределы.