Элвис покинул здание (wm_MouseLeave)

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Элвис покинул здание (wm_MouseLeave)

Сообщение and » 23.05.2011 18:05:01

В Лазаревской прилоге не получается гарантировано (т.е. включая выверты с Alt+Tab etc) отловить уход мыши из контрола.
Под Delphi5 делал обработчик wm_MouseLeave - и вуаля, всегда знал, что мышь окно покинула. А под Лазарем не удаётся получать это сообщение никакими (известными мне) способами: ни впрямую обработчиком (message wm_MouseLeave), ни через перекрытие оконной функции. С wm_NCHitTest второй способ работает, а wm_MouseLeave - не приходит.
Any ideas?
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение Maxizar » 23.05.2011 18:29:03

какая ОС? и какой Lazarus, потому что вот у меня lazarus 0.9.30 и Windows XP SP3, делаю типа так:
Код: Выделить всё

procedure TForm1.Panel1MouseLeave(Sender: TObject);
begin
  Panel1.Caption:='Мышь ушла';
end;

procedure TForm1.Panel1MouseEnter(Sender: TObject);
begin
   Panel1.Caption:='Мышь пришла';
end;
     

И все работает! Может у вас Контрол какой нибудь редкий?...
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение and » 24.05.2011 04:18:16

WinXPSP3rus, снэпшот 0.9.31, FPC 2.5.1. Контрол любой: панель, форма...

Maxizar, проведите plz такой эксперимент:
1) запустите "Notepad" или любой другое приложение;
2) разместите его так, чтобы его окно частично закрывало тестовую панель;
3) переключитесь на тестовое приложение ("Блокнот" уходит на задний план);
4) передвиньте мышь в ту часть панели, которая пересекается с notepad'ным окном;
5) по <Alt>+<Tab> переклчитесь на "Блокнот".

Неужели событие Panel1MouseLeave дёрнулось? 8-O

Добавлено спустя 13 минут 44 секунды:
Ха! События MouseEnter/MouseLeave - ерунда полная, даже вывертов с <Alt>+<Tab> не надо, достаточно выводить курсор через чужое окно. На скрине стрелкой движение мыши; по caption'у, она всё ещё над панелью.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение Nik » 24.05.2011 09:35:31

2and
Набросайте аналогичный пример в Delphi. Если там будет более логичное поведение, смело постите баг-репорт и прикладывайте к нему оба примера (Delphi+Lazarus).
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение Maxizar » 24.05.2011 10:37:04

Ну вот скажем как можно победить <Alt>+<Tab> :

Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  Messages,LMessages;

type

  { TForm1 }

  TForm1 = class(TForm)
    Panel1: TPanel;
    procedure Panel1MouseEnter(Sender: TObject);
    procedure Panel1MouseLeave(Sender: TObject);
  private
     procedure Focuskill(var Message : Tmessage); message LM_KILLFOCUS;
     procedure FocusSet(var Message : Tmessage); message LM_SETFOCUS;
    { private declarations }
  public

    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Panel1MouseEnter(Sender: TObject);
begin
  caption:='Мышь пришла'
end;

procedure TForm1.Panel1MouseLeave(Sender: TObject);
begin
  caption:='Мышь ушла'
end;

procedure TForm1.Focuskill(var Message: Tmessage);
begin
  inherited;
  //Насильно посылаем сообщение панели что мышь ушла, при потери фокуса формы.
  Panel1.Perform(CM_MOUSELEAVE, 0, 0);

end;

procedure TForm1.FocusSet(var Message: Tmessage);
begin
  inherited;
// но нужно добавить находится ли указатель над панаелью а то чушь получится
  Panel1.Perform(CM_MOUSEENTER, 0, 0);
end;

end.


Поведение простого ухода мышки при не активном окне на другое... тут нужно подумать, по идее наверное сама ОС забивает, ведь мы уже над другим приложением, наверное так!... хотя утверждать я этого не буду.
Решение с Табом я привел, если необходимо вообще решить проблему и с уходом мыши на другое приложение при не активности нашего, и если ОС реально забивает на этот случай, то наверное решением будет Ловить сообщение ОС о передвижении мыши, и тупо пересчитывать координаты в координаты приложения + координаты нужного нам контрола и уже посылать насильно сообщения мол пришла\ушла как я сделал при потере фокуса при Альт + Таб... Больше умных мыслей нету :(
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение and » 24.05.2011 19:04:30

2Nik: События/методы_дистпетчеризации в Delphi работают, насколько я помню, не лучше - т.е. не всегда. Но в D5 я писАл так:
Код: Выделить всё
Procedure WMMouseLeave(var msg:tMessage); message wm_MouseLeave;
и получал желаемое. В Лазарусе номер не проходит, увы: wm_MouseLeave кто-то сжирает по дороге.
Насколько я знаю, wm_NCHitTest такой же "вкусный" и сжираемый, но с ним проходит номер с перекрытием оконной функции. А вот искомый wm_MouseLeave в эту функцию всё равно не приходит :-(

Maxizar, спасибо, попробую с lm_KillFocus побарахтаться.
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение vada » 25.05.2011 14:26:42

Ха! События MouseEnter/MouseLeave - ерунда полная, даже вывертов с <Alt>+<Tab> не надо, достаточно выводить курсор через чужое окно. На скрине стрелкой движение мыши; по caption'у, она всё ещё над панелью.

Я Вашу логику не пойму. У Вас на скриншоте активным окном является калькулятор. Исходя их чего, Вы считаете что водя мышкой над Form1 в вашем прилажении какие-то события пролетать должны??????
По <Alt>+<Tab> вы перебросили фокус в другое приложение. Все! Ваша прилада отработала, операционка тоже отработала. Фокус теперь в другом окне. Оно теперь ловит и обрабатывает события и от мышки и от клавиатуры... Что Вы хотите-то? Чтоб Form1 продолжал состояние мыши отслеживать? Таки не должно такого быть.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение and » 27.05.2011 17:47:18

2vada:
Вы б может сначала попробовали? Примерчик за 10с делается. А потОм ужЕ о фокусах рассказывали.
Попадание в обработчик OnMouseLeave не зависит от того, какое приложение активно. Если в примере выше при активном калькуляторе выводить курсор не вниз, а влево, caption панели сменится на 'Мышь ушла'. Логичность такого поведения несколько спорна, согласен. С другой стороны, ОС отсылает мышиные сообщения окну, над которым фактически находится мышь, а не только активному окну активного приложения.

Ну, и главное.
vada писал(а):Исходя их чего, Вы считаете что водя мышкой над Form1 в вашем прилажении какие-то события пролетать должны??????
По <Alt>+<Tab> вы перебросили фокус в другое приложение.
Именно! И об этой потере моё окно должно быть уведомлено. А такого не происходит: мышь ушла, а сообщение об этом сожрали.
vada писал(а):Что Вы хотите-то? Чтоб Form1 продолжал состояние мыши отслеживать?
Ничего из ряда вон выходящего в этом не вижу. Для этого глабальные хуки существуют. Но в данном случае хочу я совсем другого: чтобы окно получило последнее сообщение в цепочке получение_фокуса - перемещения-клики-etc - потеря_фокуса. Логично, не находите?

Добавлено спустя 21 минуту 52 секунды:
И ещё об активных окнах и событиях. Если мышь выводить резким рывком, в OnMouseLeave не попадаем вообще, даже при единственном запущенном приложении - нашем - с единственным окном. Лучше всего видно при Panel1.align:=alClient - иначе (если вокруг панели есть широкий бордюр из формы) дёргать придётся очень быстро :-)
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь

Re: Элвис покинул здание (wm_MouseLeave)

Сообщение and » 01.06.2011 16:43:34

Всё оказалось просто до безобразия :-)
Лазарь не глотает wm_MouseLeave бесследно - вместо него он отправляет окну lm_MouseLeave.
Всем спасибо, проблема решена.
Аватара пользователя
and
постоялец
 
Сообщения: 124
Зарегистрирован: 16.09.2009 17:11:01
Откуда: г. Гомель, Беларусь


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 37

Рейтинг@Mail.ru