Страницы: 1 2 вся ветка
Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];




Вниз

Мышь на компоненте или в не его приделах. 


Immortal_Death   (2003-07-18 22:20) [0]

Нужно следующее, определить когда указатель мыши заходит на Button и когда сходит с него. Свойство OnMouseMove как раз подпадает под это требование, оно возникает когда мышь заходит или сходит с компонента, но там явно не указывается когда мышь зашла/покинула компонент, хотя там есть координаты мыши в момент вызова этой функции... Вопрос остается только как по координатам определить на каком компоненте находиться мышь...
И вообще насколько это будет продуктивная функция? Ведь при передвижении мыши по компоненту, это св-во вызывается не однократно. Может есть чего получше?



pavel_k   (2003-07-18 22:35) [1]

А зачем это надо?
В принципе, можно получать координаты курсора и проверять, на каком он компоненте (и для пущей радости повесить это на таймер, правда рациональным этот вариант не назовешь ).

Что понимается под "продуктивность"?



iXuSs   (2003-07-18 22:38) [2]

Вот я как-то спрашивал подобное, мне сказали, что через CM_MouseEnter и CM_MouseLeave можно без проблем написать потомка, что я в принципе и делал, но вот как повесить эти сообщения на определённый контрол? Только ли через ядро?



Immortal_Death   (2003-07-18 22:57) [3]

блин, а зачем вещать на таймер? как я предложил прооще.... событие возникает когда мышь сходит с компонента, ты проверяешь на этом она компоненте или уже неть...(это-же событие возникает когда мышь движеться на компоненте или только заходит на него).
Мне только не извесно как по координатам курсора получить над каким компонентом находиться мышь...

А потомка стряпать не охото... :(

Хотю сделать эффект, наводишь курсор на компонент всплывает надпись, уводишь мышь, надпись уплывает :), как сделано в 7 опере, на кнопках. да и потом спидбуттнноны же умеют сами выделятьься когда на них курсор наводишь и снимать свое выдиление, когда курсор с них сползает...



Immortal_Death   (2003-07-18 23:01) [4]

а продуктивность :) процессорнное время занимаемое на эту операцию, с таймером это как раз будет побольше :)



iXuSs   (2003-07-19 01:08) [5]

Видимо, придётся вешать обработку на оконную процедуру, но здесь я тебе не помощник.



Goblinus   (2003-07-19 02:20) [6]


> мне сказали, что через CM_MouseEnter и CM_MouseLeave можно
> без проблем написать потомка, что я в принципе и делал,
> но вот как повесить эти сообщения на определённый контрол?
> Только ли через ядро?


" -Как приготовить тушеного гиппопотама?
-Берете гиппопотама и тушите."

Не понял, в чем проблема. Просто отнаследуйся и добавь в раздел protected нового класса две процедуры:

procedure CMMouseEnter( var Msg: TMessage); message CM_MouseEnter;
procedure CMMouseLeave( var Msg: TMessage); message CM_MouseLeave;


Если имеется ввиду, что на некоторые контролы надо вешать эти сообщения, а на некоторые нет и влом новые классы создавать - можно через хуки.



Immortal_Death   (2003-07-19 11:17) [7]

хм... вот так всегда, с этими массагами какая-нибудь трабла :(. Если кнопка находиться на панели, массага возвращает не кнопку, а пенель :(
Есть какой-нибудь способ это обойти? :)

(Идентификатор компонента, получал параметром LParam переменной msg, остальные параметры не катят.)



ЮЮ   (2003-07-19 14:22) [8]

>Хотю сделать эффект, наводишь курсор на компонент всплывает надпись, уводишь мышь, надпись уплывает

А не хотишь обратить внимание на TControl.Hint ?



Alec   (2003-07-19 15:37) [9]

Я не мастер, но попробую ответить.
Надо создать две процедуры Move1 и Move2, которые повесить на Button1.OnMouseMove и Form1.OnMouseMove соответственно.
В Move1 помимо нужных действий
Form1.OnMouseMove := Move2;
а в Move2 помимо нужных действий
Form1.OnMouseMove := Nil;
это позволит не тратить время процессора на постоянную обработку
MouseMove на Форме.
Только не надо это делать ради простого Hint/



Marser   (2003-07-19 15:43) [10]

Самый простой способ - RXLib. Там для ленивых есть такие события



Immortal_Death   (2003-07-19 16:34) [11]

Alec,
Я думал над такой возможностью, но она глючная. представь себе, что юзер резко дернул мышь :), курсор резко проскакивает форму, и Form1.OnMouseMove срабатывать не успивает :(, надпесь не куда не исчезает, а остаеться как есть :(. Такая-же лажа будет если в винде включено авто перемещение курсора при открытии нового окна на активную кнопку. Есть и другие траблы в этом способе... :(

Marser,
Я не линивый :). Не люблю стороние компоненты :( - по извесным причинам.

ЮЮ,
Hint - это не то :), избито ужо, да гемороя с ними не кокого :), а мы же легких путей не ищем.

Goblinus
А хуки какие катят под это дело? (ууу, опять хуки, вот это геморой дак геморой)...



iXuSs   (2003-07-19 19:51) [12]

> Если имеется ввиду, что на некоторые контролы надо вешать эти сообщения, а на некоторые нет и влом новые классы создавать - можно через хуки.

Вот это и имелось ввиду. Можно хоть как-то на готовом примере?



Alec   (2003-07-20 01:20) [13]

Проверил. Согласен. В общем.
Перебрал много вариантов (избавления от глюков).
Простого не нашел.
Остаются (мое субъективное мнение) только хуки.



Alec   (2003-07-20 01:32) [14]


> она глючная. представь себе, что юзер резко дернул мышь
> :), курсор резко проскакивает форму, и Form1.OnMouseMove
> срабатывать не успивает

Если кнопка не стоит в упор к краям формы, то я не успевал ее так быстро дергать, чтобы OnMouseMove не успевал срабатывать. Основная проблема была Alt+Tab. Извиняюсь, не смог что-то придумать из похожей серии(не используя Timer, что, я так думаю, не устроит). (Хотя, может еще денек).



3APA3A   (2003-07-20 03:47) [15]

Хм, у TLabel есть обработчики OnMouseLeave и OnMouseEnter. Почему бы не содрать код (или принцип) оттуда?



TankMan   (2003-07-20 04:25) [16]

Да что вы все еще обсуждаете я ни пойму?!?!?
Вам Goblinus ясно понятно дал решение этой задачи... какие еще могут быть проблемы?
Если не понятно вот пример, который раньше давали мне...(почти такой)
type TMyLabel = class(TLabel)
private
FOnMouseEnter: TNotifyEvent;
FOnMouseLeave: TNotifyEvent;
procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
protected
procedure DoMouseEnter; dynamic;
procedure DoMouseLeave; dynamic;
published
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
end;

А далее...

procedure TMysLabel.CMMouseEnter(var Msg: TMessage);
begin
inherited;
TLabel(self).font.color:=$C63745;
Screen.Cursor:=crHandPoint;
DoMouseEnter;
end;

procedure TMysLabel.CMMouseLeave(var Msg: TMessage);
begin
inherited;
TLabel(self).font.color:=$0;
Screen.Cursor:=crDefault;
DoMouseLeave;
end;

procedure TMyLabel.DoMouseEnter;
begin
if Assigned(FOnMouseEnter) then FOnMouseEnter(Self)
end;

procedure TMyLabel.DoMouseLeave;
begin
if Assigned(FOnMouseLeave) then FOnMouseLeave(Self)
end;

Вобщем это работает... вовсяком случае, мой компонент на этом работает....



Романов Р.В.   (2003-07-20 10:33) [17]


> Immortal_Death (18.07.03 22:57)
> А потомка стряпать не охото... :(


В таком случае можно подменить оконную процедуру WindowProc и в ней обрабатывать сообщения CM_MOUSEENTER/CM_MOUSELEAVE



Immortal_Death   (2003-07-20 11:21) [18]

Щас поглядел, как пашит Tlabel, принцип тот-же, что и предложил TankMan, но ведь это создание целого компонента... бррр...
Кстати TankMan, ты прочитай еще раз то, что предложил Goblinus, он не предлогал создаватьь не сввоих унаследованых классов, не компонентов, там все проще...
TankMan, а можешь скинуть свой компонент? Поближе хотю глянуть:).

А вообще, реально, сделать так как написал TankMan, без создания компонента?



Immortal_Death   (2003-07-20 11:23) [19]

Романов Р.В., а подробнее?



Романов Р.В.   (2003-07-20 11:28) [20]

var
OldProcLV: TWndMethod;
...

procedure TForm1.FormCreate(Sender: TObject);
begin
OldProcLV:=ListView1.WindowProc;
ListView1.WindowProc:=NewProcLV;
end;

procedure TForm1.NewProcLV(var Msg: TMessage);
begin
OldProcLv(Msg);
if Msg.Msg = CM_MouseEnter then
ShowMessage("CMMouseEnter");
end;



Immortal_Death   (2003-07-20 12:16) [21]

Романов Р.В.,
а каким образом инкапсулировать процедуру:
procedure NewProcLV(var Msg: TMessage);



Романов Р.В.   (2003-07-20 12:27) [22]

А зачем ее инкапсулировать? Речь шла об изменении поведения компонента без создания потомков.



Immortal_Death   (2003-07-20 12:49) [23]

ладно зададим вопрос по иному. как ее обьявить? т.е.

type
TForm1 = class(TForm)
...
...
...
private
как обьявить :)
and;

если я ее так и обьявляю procedure NewProcLV(var Msg: TMessage); она отказываеться компилиться.



Романов Р.В.   (2003-07-20 12:59) [24]

Какую ошибку выдает компилятор?



Immortal_Death   (2003-07-20 13:13) [25]

Illegal character in input file:"" ($<A0>)



Goblinus   (2003-07-20 14:15) [26]


> 2 Immortal_Death:
> А хуки какие катят под это дело? (ууу, опять хуки, вот это геморой дак геморой)...


WH_GETMESSAGE, вроде бы... Читай MSDN на эту тему. Кстати, в JEDI VCL есть компонент какой-то для работы с хуками.
Хотя, хуки - это не есть хорошо. Они замедляют работу компа и пользоваться ими стоит лишь в случае, если другого выхода нет. Так что, ИМХО, лучше отнаследоваться.


> Вот это и имелось ввиду. Можно хоть как-то на готовом примере?


Есть готовые примеры на C, в "Азбуке программирования в Win32 API". Скачать, вроде, на Delphi Plus можно... ИМХО, все доволно понятно объяснено, на Delphi перевести большого труда не составит.



Immortal_Death   (2003-07-20 14:23) [27]

А, ну тут понятно. с касяком разобрался. Я копировал от сюда и вставлял в редактор дельфей, и там до перевода корретки затесывался еще один символ, который не видно(может люнековсая переводка коретки?). Первый раз такая фигня :).



Immortal_Death   (2003-07-20 15:05) [28]

Протестил вариант, Романов Р.В., и пока не нашел не одного косяка :). Единственное плохо глобальных переменных будет столько, на сколько компонентоов это повешаем :), но ИМХО это все-же лудьше, чем стряпать свои компоненты.

Goblinus,
на счет хуков я с тобой согласен, но знать не когда не помешает, и где ссылки? MSDN ладно, каждый знает, а "Азбука программирования в Win32 API" и Delphi Plus, что это? где это?



Goblinus pos('-', s)-   (2003-07-20 15:20) [29]

http://www.delphiplus.org, там ищи книжку "Азбука программирования..." в разделе "Докуметация", вроде...



Immortal_Death   (2003-07-20 19:59) [30]

А касяк в варианте предложином, Романов Р.В., все-же нашелся...
если прорцедура UpFont в ниже приведенном коде выполняеться достаточно долго, и в момент когда она еще выполняеться убратьь мышь с компонента, то процедура DownFont, так и не будет выполнена :(.

procedure TForm1.NewProcLV(var Msg: TMessage);
begin
OldProcLv(Msg);
case Msg.Msg of
CM_MouseEnter: UpFont;
CM_MOUSELEAVE: DownFont;
end;
end;


Можит есть способ избавиться от этой траблы?



Романов Р.В.   (2003-07-20 20:13) [31]

Попробуй захватить мышь "Mouse Capture" и в OnMouseMove отслеживать выход курсора за граници компонента



Immortal_Death   (2003-07-20 21:15) [32]

идея :), только я не знаю как определить по кординатам курсора над каким компонентом находиться мышь :(



Романов Р.В.   (2003-07-20 21:40) [33]

> только я не знаю как определить по кординатам курсора над
> каким компонентом находиться мышь :(

ControlAtPos

PS: По моему достаточно отслеживать то что мышь вышла за пределы контрола, который ее захватил



Immortal_Death   (2003-07-20 22:16) [34]

опять-же спрошу, как? %)



Immortal_Death   (2003-07-21 06:04) [35]

C ControlAtPos, не че сколько-нибудь сурьезного не получилось....

Сделал так: так как оконная функция предложеная, Романов Р.В. ©, умеет не только правельно определять момент когда на кннопку "заходит" курсор, но и момент "схода" курсора с кнопки - вот ей то я и доверил следить за этим моментом, а за "заходом" курсора на кнопку следит событие OnMouseMove.



Aldor   (2003-07-23 21:20) [36]

> то процедура DownFont, так и не будет выполнена :(.

Если в процедуре процедуре UpFont содержится долговыполняемый цикл, который и задерживает всю работу, вставь в него
Application.ProcessMessages



Immortal_Death   (2003-07-24 00:12) [37]

Aldor ©,
это было паервым делом, что я подумал сделать... не помогает :).
"зависания", точнее не выполнение процедуры DownFont в некоторых случаях продолжает наблюдаться.
А вот то, что я предложил сделать в //Immortal_Death (21.07.03 06:04)// вполне работает :).

Тут следует сказать еще вот что: если я эту процедуру (Immortal_Death (20.07.03 19:59)) вешаю на обычный Button, то все работает как надо, а вот если на SpeedButton, то тут то глюки и появляються :(. И не важно делаю я Application.ProcessMessages или нет.

Кстати процедуры (UpFont и DownFont)с самим контролом на который вешаю процедуру procedure TForm1.NewProcLV(var Msg: TMessage); не работают, они работают с др. компонентом! эт на всякий ;)



Yanis   (2003-07-24 01:23) [38]

function PtInRect(const lprc: TRect; pt: TPoint): BOOL
Разве так нельзя проверить?



KSergey   (2003-07-24 06:48) [39]

Immortal_Death (19.07.03 16:34)
Я не линивый :). Не люблю стороние компоненты :( - по извесным причинам.


По каким же? А свои собственные - это сторонние?

ЮЮ,
Hint - это не то :), избито ужо, да гемороя с ними не кокого :), а мы же легких путей не ищем.


А может напрасно?
Окно хинта можно переопределить, может на этом сыграть?
Как именно - напрягаться сейчас лень, но видел компоненты (например, 4th GUI Library, там есть TFourthHintPanel - для показа всплывающих подсказок; он в исходниках, можно посмотреть как именно это реализовано).



Andrey007   (2003-07-24 10:41) [40]

А разве эта проблема не решается через использование SetCapture/ReleaseCapture?




Страницы: 1 2 вся ветка
Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.82 MB
Время: 0.074 c
3-20397           ruslan_as             2003-07-16 09:31  2003.08.07  
Как создать уникальное значение поля в InterBase


1-20521           GreySerg              2003-07-25 18:41  2003.08.07  
Создание коллекции объектов


1-20561           bkatrin               2003-07-23 19:02  2003.08.07  
QReport


3-20380           AkaSaint              2003-07-14 18:15  2003.08.07  
Как в ADOTable обновить из БД только одну запись?


6-20649           blackgrin             2003-06-02 02:16  2003.08.07  
Connection Closed Gracefully?!