IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Отловить вращение колеса прокрутки (https://www.imho.ws/showthread.php?t=32969)

Dialer 24.06.2003 19:16

Отловить вращение колеса прокрутки
 
Требуется отлавливать вращение колесика мыши не только в окне программы, но и вообще во всей системе. По логике веще нужно ставить хук с помощью функции SetWindowsHookEx на WH_MOUSE и отлавливать в этой функции событие WM_MOUSEWHEEL (522), что я и делаю. НО при таком раскладе невозиожно определить в какую сторону вращается колесо, т.к. в эту функцию не возвращается параметр zDelta. Или я не прав и он там всё-таки как-то доступен?? Если нет, то как ещё можно отловить вращение колеса в системе?
ПРИМ: дело происходит на сях.

alexey_ma 25.06.2003 10:04

Из MSDN к WM_MOUSEWHEEL :
Код:

....
Syntax

WM_MOUSEWHEEL

    WPARAM wParam
    LPARAM lParam
....

Remarks

Use the following code to get the information in the wParam parameter:

fwKeys = GET_KEYSTATE_WPARAM(wParam);
zDelta = GET_WHEEL_DELTA_WPARAM(wParam);

Use the following code to obtain the horizontal and vertical position:

xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);

....


Dialer 25.06.2003 12:03

PHP код:

zDelta GET_WHEEL_DELTA_WPARAM(wParam); 

Да, но ведь это функция работает только в Windows NT/2000/XP, а мне нужно чтобы и в Win9x работала.

alexey_ma 25.06.2003 12:09

Читаем дальше MSDN :
Код:

Windows 95, Windows NT 3.51: Support for the mouse wheel is
provided through a separately-running module, MSWheel, that
generates a MSH_MOUSEWHEEL message. The MSWheel module,
which consists of MSWheel.exe and MSWheel.dll, is installed with
the IntelliPoint software that is shipped with the IntelliMouse®
pointing device. In addition, MSH_MOUSEWHEEL is defined in the
header file (ZMouse.h) that an application must use to implement
support for the wheel via the MSWheel module.

MSH_MOUSEWHEEL
zDelta = (int) wParam; // wheel rotation
xPos = LOWORD(lParam); // horizontal position of pointer
yPos = HIWORD(lParam); // vertical position of pointer

Note, there is no fwKeys for MSH_MOUSEWHEEL. Otherwise, the
 parameters are exactly the same as for WM_MOUSEWHEEL.


donatas 25.06.2003 21:53

можно например глобал хук поставить :) тогда везде работать будет :)))

Dialer 25.06.2003 23:52

Цитата:

Как писал donatas
можно например глобал хук поставить :) тогда везде работать будет :)))
Ага, и при этом потерять в производительности системы... об этом даже в МСДНе написано :contract:, поэтому это не покатит.

alexey_ma 26.06.2003 09:41

Глобальный хук все равно придеться ставить. По другому не сделаешь.

donatas 26.06.2003 13:26

совершенно точно :) по другому никак =\
да и не сильно там потеряется....если правильно сделать :)

Dialer 26.06.2003 15:59

Похоже я вас не так понял. Под "глобальным хуком" я подразумевал хук типа WH_CALLWNDPROC, который перехватывает всё виды сообщений сисетмы :dont: , что еснно вызывает тормоза.

А вообще я тик использую "глобалный хук" в вашем понимании.

donatas 26.06.2003 20:04

WH_MOUSE?
не?

Dialer 26.06.2003 20:55

donatas
WH_MOUSE_LL

Flex256 14.07.2003 08:30

хуки, хуки... :) главное хвост!
ловим WM_MOUSEWHEEL
if(HIWORD(wParam)>32512) - колесо крутится в одну сторону
else - в другую...

Dialer 14.07.2003 18:07

Цитата:

Как писал Flex256
хуки, хуки... :) главное хвост!
ловим WM_MOUSEWHEEL
if(HIWORD(wParam)>32512) - колесо крутится в одну сторону
else - в другую...

У меня этот параметр почему-то всегда равен нулю :-/
Приведите плиз кусок кода который реально у вас отлавливает прокрутку.

Flex256 15.07.2003 08:27

хм... ну можно и реальный кусок:
procedure WMMouseWheel(var Msg: TMessage); message WM_MOUSEWHEEL;
....
procedure TFormTTF.WMMouseWheel(var Msg: TMessage);
begin
if(HIWORD(msg.WParam)>32512)then begin
if StringGrid1.Row<(StringGrid1.RowCount-1) then StringGrid1.Row:=StringGrid1.Row+1;end
else if StringGrid1.Row>1 then StringGrid1.Row:=StringGrid1.Row-1;
inherited;
end;
Как можно заметить - это Дельфи (3, если это имеет какое-то значение). Сей кусок позволяет перемещаться по StringGrid-у с помощью колеса прокрутки.

На С должно выглядеть примерно так:
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg){
case WM_MOUSEWHEEL:
if(HIWORD(wParam)>32512){}/*что-то важное делаем здесь*/
else {}/*не менее важное делаем здесь*/
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
Правда С-шный код я не проверял (у меня на работе мышь без колесика)
А вот еще кусочек из примеров lcc:
LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMSG lpMsg;
unsigned int i;

lpMsg = (LPMSG)lParam;

if (lpMsg->message == WM_MOUSEWHEEL)
{
if ((short) HIWORD(lpMsg->wParam) > 0)
{
for (i = 0; i < g_nLNumber; i++)
{
SendMessage(lpMsg->hwnd, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), (LPARAM)NULL);
}
}
else
{
for (i = 0; i < g_nLNumber; i++)
{
SendMessage(lpMsg->hwnd, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM)NULL);
}
}
}

return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam) ;
}
В данном случае вешается хук для того что-бы добавить возможность управления колесиком в !!!чужой!!! программе.
Это вкратце... :)

Dialer 15.07.2003 10:07

Flex256
Рассмотрим последнюю функцию. Для удобства немного сократим её:
Код:

LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam){
        LPMSG lpMsg;
        unsigned int i;

        lpMsg = (LPMSG)lParam;

        if (lpMsg->message == WM_MOUSEWHEEL){
                if ((short) HIWORD(lpMsg->wParam) > 0){
                        MessageBox(0, "iff", "", MB_OK);
                } else {
                        MessageBox(0, "else", "", MB_OK);
                }
        }
        return CallNextHookEx(0, nCode, wParam, lParam);
}

Для какого типа хуков вы предполагаете её использовать? Я пытался ставить её на WH_MOUSE и он не работала. Для того чтобы она заработала мне пришлось поменять
Код:

if (lpMsg->message == WM_MOUSEWHEEL)
на
Код:

if (wParam == WM_MOUSEWHEEL)
но и в этом случае постоянно выводится сообщение "iff", хоть вверх крути хоть вниз :(

Flex256 15.07.2003 11:36

стоп, стоп, стоп
мышиное колесо обрабатывается в !!!своей!!! программе, потому использование хуков в данном случае - мягко говоря плохой тон!
Но тем не менее хук ставится примерно так:
g_Hook=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MsgHookProc, g_hInst, dwThreadID);
Но вернемся к нашим баранам:
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg){
case WM_MOUSEWHEEL:
if(HIWORD(wParam)>32512) MessageBox(hwnd, "if", "", MB_OK);
else MessageBox(hwnd, "else", "", MB_OK);
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
попробуй лучше такой вариант. Я думаю он правилен.
К сожалению сам проверить этот кусочек не могу - нет колесика на мыши.
Могу проверить только вечером дома.
А дельфийский вариант 100% работает.

Dialer 15.07.2003 13:49

а мне как раз и нужно, чтобы колесо отлавливалось ВЕЗДЕ, во всей системе вообще, а не толко в моей программе!

>g_Hook=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MsgHookProc, g_hInst, dwThreadID);

WH_GETMESSAGE.. хмм.. а не кажется ли тебе что это слишком ставить хук такого типа? Он вебь будет жрать больше ресурсов чем WH_MOUSE.

Flex256 15.07.2003 14:23

я думаю, что можно поставить и на WH_MOUSE
только посмотри, что передается в HIWORD(wParam)
и в ссответствии с этим поставь if
Скорее всего за направление отвечает всего один бит

Flex256 15.07.2003 14:25

зы предположительно старший :)
(судя по ифам)


Часовой пояс GMT +4, время: 15:43.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.