Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.034 c
14-1123161652
oldman
2005-08-04 17:20
2005.08.28
Улыбайтесь, господа...


9-1114111199
Lostcoder
2005-04-21 23:19
2005.08.28
Разрушаемые объекты


14-1122965493
Игорь Шевченко
2005-08-02 10:51
2005.08.28
Наши программисты победили в Йокогаме


9-1114794185
Warchief
2005-04-29 21:03
2005.08.28
lightmap


14-1123051609
syte_ser78
2005-08-03 10:46
2005.08.28
Глюк при запуске от имени





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский