Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.28;
Скачать: CL | DM;

Вниз

Мышь над/вне компанентом(формой)   Найти похожие ветки 

 
mmms   (2005-08-07 00:13) [0]

Здравствуйте! Не сложный код, определяю, мышь над формой или нет. Эффект срабатывает на 70%. То есть не всегда корректно отрабатывает код. Часто "выходишь" мышью с формы, а надпись не меняется.  Может я что упустил? подскажите плз. И второй вопрос, можно ли тоже самое, но над компанентом TMemo, например сделать? Т.е. как над TMemo определить, над ним мышь, или уже вышла из компанента. Надо как то привязать TMemo 2 обработчика, это сделать в constructor? Заранее благодарю.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   procedure HHMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
   procedure HHMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
 private
   WHover: Boolean;
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.HHMouseLeave(var Message: TMessage);
begin
 Caption:="Мышь не над формой!!!";
end;

procedure TForm1.HHMouseEnter(var Message: TMessage);
begin
 Caption:="Мышь находится над формой!!!";
end;

end.


 
GuAV ©   (2005-08-07 00:38) [1]

Чтобы обрабатывать сообщения контрола на форме достаточно подменить WindowProc.

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
   FMemoOldWndProc: TWndMethod;
   procedure MemoNewWndProc(var Message: TMessage);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 FMemoOldWndProc := Memo1.WindowProc;
 Memo1.WindowProc := MemoNewWndProc;
end;

procedure TForm1.MemoNewWndProc(var Message: TMessage);
begin
 case Message.Msg of
   CM_MOUSELEAVE: Caption:="Мышь не над Memo!!!";
   CM_MOUSEENTER: Caption:="Мышь над Memo!!!";
 end;
 FMemoOldWndProc(Message);
end;

Можно написать компонент-наследник Memo, и сделать как в TForm1.

Что касается первого вопроса, то CM_MOUSELEAVE и CM_MOUSEENTER генерируются в Application.DoMouseIdle, и поэтому, могут и не приходить при каждом перемещении мыши. В случае если движение по неклиентской части формы не сгенерит сообщения (при быстром движении мыши из формы), CM_MOUSELEAVE не сгенерируется.

Поэтому IMHO следует избегать каких-либо действий при CM_MOUSELEAVE и CM_MOUSEENTER, максимум - "цацки", но не управление.


 
mmms   (2005-08-08 09:00) [2]

GuAV ©   (07.08.05 00:38)
Спасибо большое! сейчас поэксперементирую.


 
mmms   (2005-08-08 09:39) [3]

Код от GuAV очень помог, хотел ещё спросить, делаю как, на форме Memo1 и btn1. Причем, btn1 лежит на Memo1, в правом верхнем углу. Задача, при наведении мыши на Memo1 показать btn1, и дать возможность нажать на btn1. И при выходе с Memo1 убрать(скрыть) btn1. Сейчас у меня получается, что btn1 мелькает. Различные ухищрения с knopka (boolean) что то не приводят к желаемому результату. knopka - становится в True, если над btn1 находится мышь.


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   btn1: TButton;                //кнопка. Находится над Memo1
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
  knopka : boolean;              //показывает мышь над кнопкой или нет
  FMemoOldWndProc: TWndMethod;
  FBtnOldWndProc: TWndMethod;
  procedure MemoNewWndProc(var Message: TMessage);
  procedure BtnNewWndProc(var Message: TMessage);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
FMemoOldWndProc := Memo1.WindowProc;
Memo1.WindowProc := MemoNewWndProc;

FBtnOldWndProc := Btn1.WindowProc;
Btn1.WindowProc := BtnNewWndProc;

btn1.Visible := False;         //установим по умолчанию не в Visible
knopka := False;               //флаг соответственно тоже в False
end;

procedure TForm1.MemoNewWndProc(var Message: TMessage);
begin
if knopka <> True then          //если мышь не над кнопкой, то
case Message.Msg of
  CM_MOUSELEAVE:
   begin
    Caption:="Мышь не над Memo!!!";
    btn1.Visible:=False;
   end;
  CM_MOUSEENTER:
   begin
    Caption:="Мышь над Memo!!!";
    btn1.Visible:=True;
   end;
end;
FMemoOldWndProc(Message);
end;

procedure TForm1.BtnNewWndProc(var Message: TMessage);
begin
case Message.Msg of          //узнаем, что мышь над кнопкой
  CM_MOUSELEAVE: knopka:=False;
  CM_MOUSEENTER: knopka:=True;
end;
FBtnOldWndProc(Message);
end;

end.


 
GuAV ©   (2005-08-08 17:11) [4]


> Сейчас у меня получается, что btn1 мелькает. Различные
> ухищрения с knopka (boolean) что то не приводят к
> желаемому результату.


Всё правильно если кнопка не вставлена в Memo, а лежит поверх Memo. См. код. TApplication.DoMouseIdle.


> Причем, btn1 лежит на Memo1, в правом верхнем углу.

Не очень удачное решение. Кнопка может закрывать текст и скрол.


 
Игорь Шевченко ©   (2005-08-08 17:37) [5]


>
> Что касается первого вопроса, то CM_MOUSELEAVE и CM_MOUSEENTER
> генерируются в Application.DoMouseIdle, и поэтому, могут
> и не приходить при каждом перемещении мыши. В случае если
> движение по неклиентской части формы не сгенерит сообщения
> (при быстром движении мыши из формы), CM_MOUSELEAVE не сгенерируется.
>
> Поэтому IMHO следует избегать каких-либо действий при CM_MOUSELEAVE
> и CM_MOUSEENTER, максимум - "цацки", но не управление.


Весьма помогает SetCapture/ReleaseCapture и WM_CAPTURECHANGED


 
GuAV ©   (2005-08-08 17:54) [6]


> Весьма помогает SetCapture/ReleaseCapture и
> WM_CAPTURECHANGED


Т.е. SetCapture и при CM_MOUSELEAVE делать ReleaseCapture, а реагировать уже на WM_CAPTURECHANGED в не зависимости пришло ли CM_MOUSELEAVE ?

Как-то не думал, что SetCapture не обязательно только при зажатии кнопки мыши..


 
Игорь Шевченко ©   (2005-08-08 18:03) [7]

GuAV ©   (08.08.05 17:54) [6]

Нет, SetCapture делать при входе мыши в область контрола по WM_MOUSExxxx - при этом все сообщения WM_MOUSExxxx отправляются окну, выполнившему захват мыши. Если мышь при этом вышла за пределы контрола, то обычно выполняется ReleaseCapture и действия по выходу мыши за пределы контрола. А по WM_CAPTURECHANGED выполняются действия по выходу мыши за пределы без вызова ReleaseCapture.


 
mmms   (2005-08-08 19:15) [8]

Сама идея такая же, как у IE6 всплывающая панель над картинкой.


 
GuAV ©   (2005-08-08 20:19) [9]


> как у IE6 всплывающая панель над картинкой.

Там нужно уместить панель инструментов возле картинки, чтобы она была ассоциирована с ней, при этом своодного места вокруг нет, всё занято страницей. На форме можно предусмотреть место над memo.


 
mmms   (2005-08-09 08:07) [10]

предусмотреть место над memo.
Тогда не сработает код выше, если я выйду с мемо. Т.е. показ панели, когда мышь над мемо. Сейчас попробую реализовать.


 
Tigraman   (2005-08-09 08:25) [11]

А как определить находиься мышь над image или она его покинула?



Страницы: 1 вся ветка

Текущий архив: 2005.08.28;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.024 c
14-1122904640
oldman
2005-08-01 17:57
2005.08.28
Кто нибудь боролся с Яхой?


4-1117686064
Sir
2005-06-02 08:21
2005.08.28
Серийный номер видеокарты &amp; материнской платы


9-1115313088
Кефир87
2005-05-05 21:11
2005.08.28
OpenGL грузится одна и та же текстура (?)


1-1123404272
Ксардас
2005-08-07 12:44
2005.08.28
Как получить номер верхней видной строки в РичЭдите?


14-1123483701
SPeller
2005-08-08 10:48
2005.08.28
Что такое Up-Link на хабах?