Форум: "Основная";
Текущий архив: 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