![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Мышь над/вне компанентом(формой) [D7]
mmms © (2005-08-07 00:13:00)Здравствуйте! Не сложный код, определяю, мышь над формой или нет. Эффект срабатывает на 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.
Tigraman (2005-08-09 08:25:00) [1]А как определить находиься мышь над image или она его покинула?
mmms (2005-08-09 08:07:00) [2]предусмотреть место над memo.
Тогда не сработает код выше, если я выйду с мемо. Т.е. показ панели, когда мышь над мемо. Сейчас попробую реализовать.
GuAV (2005-08-08 20:19:00) [3]
> как у IE6 всплывающая панель над картинкой.
Там нужно уместить панель инструментов возле картинки, чтобы она была ассоциирована с ней, при этом своодного места вокруг нет, всё занято страницей. На форме можно предусмотреть место над memo.
mmms (2005-08-08 19:15:00) [4]Сама идея такая же, как у IE6 всплывающая панель над картинкой.
Игорь Шевченко (2005-08-08 18:03:00) [5]GuAV © (08.08.05 17:54) [6]
Нет, SetCapture делать при входе мыши в область контрола по WM_MOUSExxxx - при этом все сообщения WM_MOUSExxxx отправляются окну, выполнившему захват мыши. Если мышь при этом вышла за пределы контрола, то обычно выполняется ReleaseCapture и действия по выходу мыши за пределы контрола. А по WM_CAPTURECHANGED выполняются действия по выходу мыши за пределы без вызова ReleaseCapture.
GuAV (2005-08-08 17:54:00) [6]
> Весьма помогает SetCapture/ReleaseCapture и
> WM_CAPTURECHANGED
Т.е. SetCapture и при CM_MOUSELEAVE делать ReleaseCapture, а реагировать уже на WM_CAPTURECHANGED в не зависимости пришло ли CM_MOUSELEAVE ?
Как-то не думал, что SetCapture не обязательно только при зажатии кнопки мыши..
Игорь Шевченко (2005-08-08 17:37:00) [7]
>
> Что касается первого вопроса, то CM_MOUSELEAVE и CM_MOUSEENTER
> генерируются в Application.DoMouseIdle, и поэтому, могут
> и не приходить при каждом перемещении мыши. В случае если
> движение по неклиентской части формы не сгенерит сообщения
> (при быстром движении мыши из формы), CM_MOUSELEAVE не сгенерируется.
>
> Поэтому IMHO следует избегать каких-либо действий при CM_MOUSELEAVE
> и CM_MOUSEENTER, максимум - "цацки", но не управление.
Весьма помогает SetCapture/ReleaseCapture и WM_CAPTURECHANGED
GuAV (2005-08-08 17:11:00) [8]
> Сейчас у меня получается, что btn1 мелькает. Различные
> ухищрения с knopka (boolean) что то не приводят к
> желаемому результату.
Всё правильно если кнопка не вставлена вMemo, а лежит поверхMemo. См. код. TApplication.DoMouseIdle.
> Причем, btn1 лежит на Memo1, в правом верхнем углу.
Не очень удачное решение. Кнопка может закрывать текст и скрол.
mmms (2005-08-08 09:39:00) [9]Код от 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.
mmms (2005-08-08 09:00:00) [10]GuAV © (07.08.05 00:38)
Спасибо большое! сейчас поэксперементирую.
GuAV (2005-08-07 00:38:00) [11]Чтобы обрабатывать сообщения контрола на форме достаточно подменить 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, максимум - "цацки", но не управление.