Как определить, когда мышь отходит от TPanel в Delphi 6?
Я использую событие OnMouseMove, чтобы определить, когда указатель мыши находится над моим TPanel, есть ли способ узнать, когда указатель мыши отошел от него?
Мне нужно, чтобы панель меняла цвет, когда указатель мыши находится над ней, и возвращался к исходному цвету, как только он отошел от нее?
Я использую Delphi 6, кстати.
Пожалуйста помоги.
С уважением.
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 - благодаря ответу Сертака Акьюза
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;
OnMouseLeave. Помните, что вам также нужно проверить, не ушла ли мышь из приложения целиком, поскольку OnMouseLeave не срабатывал, когда панель находилась на краю формы, а я ушел из формы.
Создайте свой собственный компонент, полученный из 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];
Спасибо за помощь. Для меня очень хорошо, я создаю новый элемент управления bitbtn, полученный из оригинального bitbtn и реализующий mouseenter и отпуск мыши, с Delphi 7. Следуйте моему коду:
TBitBtnPanel = class (TBitBtn) частный {Частные объявления} FOnMouseLeave: TNotifyEvent; FOnMouseEnter: TNotifyEvent; FActivateMouseLeave: логическое значение; процедура CMMouseEnter(var Msg: TMessage); сообщение CM_MOUSEENTER; процедура CMMouseLeave(var Msg: TMessage); сообщение CM_MOUSELEAVE; защищенный {Защищенные декларации} общественности {Публичные декларации} конструктор Create(AOwner: TComponent); переопределить; опубликованный {Опубликованные объявления} свойство OnMouseLeave: TNotifyEvent читать FOnMouseLeave писать FOnMouseLeave; свойство OnMouseEnter: TNotifyEvent читать FOnMouseEnter писать FOnMouseEnter; конец; { TBitBtnPanel } процедура TBitBtnPanel.CMMouseEnter(var Msg: TMessage); начать Msg.Result:= WM_CANCELMODE; FActivateMouseLeave:=True; если назначено (FOnMouseEnter), то FOnMouseEnter(Self); конец; процедура TBitBtnPanel.CMMouseLeave(var Msg: TMessage); начать if (FActivateMouseLeave) тогда начать Msg.Result:= WM_CANCELMODE; FActivateMouseLeave:=False; если назначено (FOnMouseLeave), то FOnMouseLeave(Self); конец; конец; конструктор TBitBtnPanel.Create(AOwner: TComponent); начать FActivateMouseLeave: = True; наследуется; конец;
Уго Баррос - Бразилия