Как я могу вызвать событие, когда мышь покидает мой контроль? - PullRequest
5 голосов
/ 27 апреля 2011

Как мне создать событие OnMouseLeave?

Ответы [ 2 ]

8 голосов
/ 27 апреля 2011

Другой альтернативой решению Andreas является использование VCL-сообщения CM_MOUSELEAVE, которое уже определено в delphi 7.

. Проверьте этот пример, используя класс интерпозера для TButton

type
  TButton = class(StdCtrls.TButton)
  private
    FOnMouseLeave: TNotifyEvent;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;


  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private
     procedure ButtonMouseLeave(Sender: TObject);
  public
  end;

//handle the message and call the event handler
procedure TButton.CMMouseLeave(var Message: TMessage);
begin
  if (Message.LParam = 0) and Assigned(FOnMouseLeave) then
      FOnMouseLeave(Self);
end;


procedure TForm1.ButtonMouseLeave(Sender: TObject);
begin
   //your code goes here   
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //assign the event
  Button1.OnMouseLeave:=ButtonMouseLeave;
end;
6 голосов
/ 27 апреля 2011

Вы можете указать Windows отправлять вам сообщение, в частности, сообщение WM_MOUSELEAVE, когда мышь покидает элемент управления.Для этого вызовите функцию TrackMouseEvent.В структуре TRACKMOUSEEVENT укажите флаг TME_LEAVE.

По запросу, некоторый код:

Когда элемент управления создани когда мышь находится внутри клиентской области элемента управления, сообщите Windows, что вы хотите получать уведомления о выходе мыши из элемента управления:

procedure TMyControl.SetMouseEvent;
var
  tme: TTrackMouseEvent;
begin
  tme.cbSize := sizeof(tme);
  tme.dwFlags := TME_LEAVE;
  tme.hwndTrack := Self.Handle;
  TrackMouseEvent(tme);
end;

Вызовите эту процедуру, когда элемент управления будет создан, а мышьвнутри контроля.Теперь вам просто нужно послушать сообщение WM_MOUSELEAVE.В вашей WndProc процедуре (защищенный член класса) добавьте WM_MOUSELEAVE case.

procedure TMyControl.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
    WM_MOUSELEAVE:
      beep;
  end;
end;

Я думаю, что Windows удаляет запрос уведомления, когда сообщение создано, поэтому вам нужноповторно запросить уведомление, когда вы получили сообщение.Вы не можете вызвать SetMouseEvent в WndProc, потому что при вызове TrackMouseEvent мышь должна находиться внутри клиентской области элемента управления.Я думаю, что вы можете поместить свой SetMouseEvent в OnMouseMove элемента управления:

procedure TMyControl.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
    WM_MOUSELEAVE:
      beep;
    WM_MOUSEMOVE:
      SetMouseEvent;
  end;
end;

Я не проверял код выше себя, потому что я использую более новую версию Delphi, Delphi 2009, котораяделает подобные вещи негласно (я думаю, потому что теперь в элементах управления есть OnMouseLeave событие), и я думаю, что это будет мешать.

...