OberonCore https://forum.oberoncore.ru/ |
|
Прокрутка Крысой https://forum.oberoncore.ru/viewtopic.php?f=2&t=3391 |
Страница 1 из 4 |
Автор: | ilovb [ Пятница, 15 Апрель, 2011 13:44 ] |
Заголовок сообщения: | Прокрутка Крысой |
Мерцает текст при прокрутке колесом мыши. Раздражает. Проблема, как я понял, в сообщении WM_MOUSEWHEEL. Т.е. посылается куча этих сообщений и BlackBox их старательно последовательно пытается обработать. Думаю, что их нужно толкать в буфер и схлопывать. Вопрос: Будет ли правильным навесить HOOK? Ну и в нем это обрабатывать, а окну посылать обычный скрол. Или есть другое решение? |
Автор: | ilovb [ Понедельник, 18 Апрель, 2011 10:08 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
В модуле WinApi неправильно описан хэндлер хука. Должно быть так: Код: HOOKPROC* = PROCEDURE (p1: INTEGER; p2: WPARAM; p3: LPARAM): INTEGER;
|
Автор: | Евгений Темиргалеев [ Понедельник, 18 Апрель, 2011 10:32 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Сталкивался. Если правильно припоминаю, то это универсальный тип (чтобы не описывать все виды хуков). Для винапи нужен только адрес, сигнатура роли не играет... |
Автор: | ilovb [ Понедельник, 18 Апрель, 2011 11:01 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Еще мелкий трабл: не могу поставить локальный хук. Глобальный нормально ставится. |
Автор: | ilovb [ Понедельник, 18 Апрель, 2011 11:08 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Код: MODULE SmartMWheel; IMPORT WinApi, StdLog, HostWindows; VAR thrd: WinApi.HANDLE; mhook: WinApi.HHOOK; Handler: PROCEDURE(code: INTEGER; wparam: WinApi.WPARAM; lparam: WinApi.LPARAM): INTEGER; hinst: WinApi.HINSTANCE; PROCEDURE Do*(); BEGIN mhook := WinApi.SetWindowsHookEx(14, Handler, 0, thrd); StdLog.Int(mhook); END Do; PROCEDURE Undo*; BEGIN IF WinApi.UnhookWindowsHookEx(mhook) = 0 THEN StdLog.String("Hook NOT deleted"); ELSE StdLog.String("Hook deleted"); END; END Undo; PROCEDURE HandlerProc(code: INTEGER; wparam: WinApi.WPARAM; lparam: WinApi.LPARAM): INTEGER; VAR wnd: HostWindows.Window; msg: WinApi.MSG; res: INTEGER; BEGIN wnd := HostWindows.dir.First(); CASE wparam OF | WinApi.WM_MOUSEWHEEL: StdLog.String("Wheel"); StdLog.Ln; RETURN -1; (*WinApi.CallNextHookEx(WinApi.WM_NULL, code, wparam, lparam);*) ELSE RETURN WinApi.CallNextHookEx(WinApi.WM_NULL, code, wparam, lparam); END; END HandlerProc; BEGIN Handler := HandlerProc; thrd := WinApi.GetCurrentThreadId(); StdLog.Int(thrd); END SmartMWheel. SmartMWheel.Do SmartMWheel.Undo Что не так делаю? |
Автор: | ilovb [ Понедельник, 18 Апрель, 2011 11:10 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Если mhook := WinApi.SetWindowsHookEx(14, Handler, 0, thrd); заменить на: mhook := WinApi.SetWindowsHookEx(14, Handler, 0, 0); То будет глобальный, и будет работать. А локальный никак |
Автор: | Александр Ильин [ Понедельник, 18 Апрель, 2011 12:04 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
ilovb писал(а): Если mhook := WinApi.SetWindowsHookEx(14, Handler, 0, thrd); заменить на: mhook := WinApi.SetWindowsHookEx(14, Handler, 0, 0); То будет глобальный, и будет работать. А локальный никак А справку почитать? Цитата: The scope of a hook depends on the hook type. Some hooks can be set only with global scope; others can also be set for only a specific thread, as shown in the following table. У вас вместо именованной константы используется число (буу!!) 14, это соответствует WH_MOUSE_LL.
Hook Scope ... WH_MOUSE Thread or global WH_MOUSE_LL Global only |
Автор: | ilovb [ Понедельник, 18 Апрель, 2011 12:09 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
ТОЧНО!!! ЗАРАБОТАЛО! Спасибо большое |
Автор: | ilovb [ Четверг, 21 Апрель, 2011 08:52 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Еще в модуле WinApi не хватает структуры появившейся в Win2k: Код: MouseHookStructEx = POINTER TO RECORD [untagged] pt*: WinApi.POINT; hwnd*: WinApi.HWND; wHitTestCode*: INTEGER; dwExtraInfo*: INTEGER; mousedata*: INTEGER; END; Это расширение MouseHookStruct с добавленным полем mousedata (в старшем слове хранится информация о прокрутке колесом) |
Автор: | Евгений Темиргалеев [ Четверг, 21 Апрель, 2011 09:25 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Чего не хватает в WinApi можно спокойно организовать в дополнительном инт-м модуле. WinHdrs - дополнительные интерфейсные модули WinAPI --- тут модуль WinApiEx. Можете добавить |
Автор: | ilovb [ Четверг, 21 Апрель, 2011 15:33 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Вот родил уродца: ОСТОРОЖНО ЭКСПЕРИМЕТНАЛЬНЫЙ ГОВНОКОД. ПРОВЕРОК ВЫХОДА ЗА ГРАНИЦЫ НЕТ Код: MODULE SmartMWheel; IMPORT WinApi, StdLog, HostWindows, SYSTEM; TYPE MouseHookStructEx = POINTER TO RECORD [untagged] pt*: WinApi.POINT; hwnd*: WinApi.HWND; wHitTestCode*: INTEGER; dwExtraInfo*: INTEGER; mousedata*: INTEGER; END; VAR thrd, mythrd: WinApi.HANDLE; mhook: WinApi.HHOOK; Handler: PROCEDURE(code: INTEGER; wparam: WinApi.WPARAM; lparam: WinApi.LPARAM): INTEGER; hinst: WinApi.HINSTANCE; ticks: INTEGER; lpThreadId: INTEGER; Stop: BOOLEAN; wnd: HostWindows.Window; bufdelta: INTEGER; PROCEDURE ThreadRoutine(lpThreadParameter: WinApi.PtrVoid): INTEGER; VAR a: INTEGER; Pos, res: INTEGER; BEGIN WHILE ~Stop DO Pos := WinApi.GetScrollPos(wnd.wnd, WinApi.SB_VERT); IF bufdelta # 0 THEN (*res := WinApi.SetScrollPos(wnd.wnd, WinApi.SB_VERT, y + bufdelta, 1);*) res := WinApi.PostMessageW(wnd.wnd, WinApi.WM_VSCROLL, WinApi.SB_THUMBPOSITION + 10000H * (Pos - bufdelta * 5), 0); bufdelta:= 0; (*a := WinApi.Beep(100,100);*) END; WinApi.Sleep(0); END; RETURN 0; END ThreadRoutine; PROCEDURE Do*(); BEGIN Stop := FALSE; mhook := WinApi.SetWindowsHookEx(WinApi.WH_MOUSE, Handler, 0, thrd); mythrd := WinApi.CreateThread(NIL, WinApi.NULL, ThreadRoutine, 0, {}, lpThreadId); END Do; PROCEDURE Undo*; BEGIN Stop := TRUE; IF WinApi.UnhookWindowsHookEx(mhook) = 0 THEN StdLog.String("Hook NOT deleted"); ELSE StdLog.String("Hook deleted"); END; StdLog.Int(bufdelta); END Undo; PROCEDURE HandlerProc(code: INTEGER; wparam: WinApi.WPARAM; lparam: WinApi.LPARAM): INTEGER; VAR res, delta: INTEGER; msg2: WinApi.PtrMOUSEHOOKSTRUCT; msg3: MouseHookStructEx; BEGIN wnd := HostWindows.dir.First(); CASE wparam OF | WinApi.WM_MOUSEWHEEL: msg3 := SYSTEM.VAL(MouseHookStructEx, lparam); delta := msg3.mousedata DIV 10000H; bufdelta := bufdelta + delta; StdLog.String("Wheel"); StdLog.Ln; ticks := WinApi.GetTickCount(); StdLog.Int(bufdelta); StdLog.Ln; RETURN -1; (*WinApi.CallNextHookEx(WinApi.WM_NULL, code, wparam, lparam);*) ELSE RETURN WinApi.CallNextHookEx(WinApi.WM_NULL, code, wparam, lparam); END; END HandlerProc; BEGIN ticks := 0; Handler := HandlerProc; thrd := WinApi.GetCurrentThreadId(); Stop := FALSE; CLOSE IF mhook # WinApi.NULL THEN Undo END; END SmartMWheel. SmartMWheel.Do SmartMWheel.Undo Можно проверить на WinApi. Говнокод прокручивает без мерцания ![]() С удовольствием приму советы по доведению этого г до ума |
Автор: | ilovb [ Вторник, 03 Май, 2011 15:03 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Победить не удалось. В BlackBox слишком сильно все привязано на инкремент/декремент одной линии. Даже враппер не поможет. Вообще победить можно, но нужно много править TextViews. У меня желания пока нет |
Автор: | Иван Кузьмицкий [ Вторник, 03 Май, 2011 18:06 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Объясните, пожалуйста, как выглядит упомянутое мерцание при прокрутке колесом? Что-то не наблюдал у себя. Или не туда смотрю. |
Автор: | ilovb [ Среда, 04 Май, 2011 08:17 ] | ||
Заголовок сообщения: | Re: Прокрутка Крысой | ||
Вот скриншот из CamStudio
|
Автор: | Иван Кузьмицкий [ Среда, 04 Май, 2011 08:37 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
На скриншоте смущают размытые пиксели. ББ не занимается размытием, точно говорю ![]() |
Автор: | ilovb [ Среда, 04 Май, 2011 08:47 ] | ||
Заголовок сообщения: | Re: Прокрутка Крысой | ||
просматривать лучше в замедленном режиме
|
Автор: | Сергей Губанов [ Среда, 04 Май, 2011 14:29 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Иван Кузьмицкий писал(а): На скриншоте смущают размытые пиксели. ББ рисует посредством GDI. В Windows-7 GDI реализован как обёртка над новым графическим движком. Древние программы в Windows-7 выглядят как новенькие.
|
Автор: | ilovb [ Среда, 04 Май, 2011 14:40 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
У меня Win7. [оффтоп]: Хорошая ось. Реально хорошая |
Автор: | Евгений Темиргалеев [ Среда, 04 Май, 2011 14:59 ] | ||
Заголовок сообщения: | Re: Прокрутка Крысой | ||
ilovb, Вы случайно не про такое "мерцание"?
|
Автор: | ilovb [ Среда, 04 Май, 2011 15:30 ] |
Заголовок сообщения: | Re: Прокрутка Крысой |
Да да. Я удивляюсь как Иван не заметил. Фишка в том, что сообщения Wheel не буферизуются Собсна вот виновник: Код: PROCEDURE WheelScroll (wnd: WinApi.HANDLE; wParam, lParam: INTEGER); VAR w: Window; res, lines, delta, keys: INTEGER; msg: Controllers.WheelMsg; p: WinApi.POINT; BEGIN delta := wParam DIV 10000H; keys := wParam MOD 10000H; w := ThisWindow(wnd); lines := 3; res := WinApi.SystemParametersInfoW(104 (*SPI_GETWHEELSCROLLLINES*), 0, SYSTEM.ADR(lines), 0); p.x := lParam MOD 65536; p.y := lParam DIV 65536; res := WinApi.ScreenToClient(wnd, p); msg.x := p.x * w.port.unit; msg.y := p.y * w.port.unit; msg.nofLines := 0; msg.op := -1; IF lines > 10 THEN (* scroll pages *) INC(w.wheelPos, delta); IF w.wheelPos >= 120 THEN msg.op := Controllers.decPage; DEC(w.wheelPos, 120) ELSIF w.wheelPos <= -120 THEN msg.op := Controllers.incPage; INC(w.wheelPos, 120) END ELSIF lines > 0 THEN INC(w.wheelPos, delta * lines); WHILE w.wheelPos >= 120 DO msg.op := Controllers.decLine; INC(msg.nofLines); DEC(w.wheelPos, 120) END; WHILE w.wheelPos <= -120 DO msg.op := Controllers.incLine; INC(msg.nofLines); INC(w.wheelPos, 120) END END; msg.done := FALSE; IF msg.op >= 0 THEN w.ForwardCtrlMsg(msg) END; IF ~msg.done THEN (* scroll document *) CASE msg.op OF | Controllers.decPage: w.Scroll(WinApi.SB_PAGEUP, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)) | Controllers.incPage: w.Scroll(WinApi.SB_PAGEDOWN, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)) | Controllers.decLine: WHILE msg.nofLines > 0 DO w.Scroll(WinApi.SB_LINEUP, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)); DEC(msg.nofLines) END | Controllers.incLine: WHILE msg.nofLines > 0 DO w.Scroll(WinApi.SB_LINEDOWN, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)); DEC(msg.nofLines) END ELSE END (* IF lines > 10 THEN (* scroll pages *) INC(w.wheelPos, delta); IF w.wheelPos >= 120 THEN w.Scroll(WinApi.SBPageUp, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)); DEC(w.wheelPos, 120) ELSIF w.wheelPos <= -120 THEN w.Scroll(WinApi.SBPageDown, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)); INC(w.wheelPos, 120) END ELSIF lines > 0 THEN INC(w.wheelPos, delta * lines); WHILE w.wheelPos >= 120 DO w.Scroll(WinApi.SBLineUp, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)); DEC(w.wheelPos, 120) END; WHILE w.wheelPos <= -120 DO w.Scroll(WinApi.SBLineDown, 0, ODD(keys DIV 8), ~ODD(keys DIV 4)); INC(w.wheelPos, 120) END END *) END END WheelScroll; Особенно циклы улыбают ![]() Буфер конечно не тут должен быть, а в диспетчере над вьюхой. С другой стороны можно и тут... вот только другие вьюхи потеряют возможность получать детальный Wheel |
Страница 1 из 4 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |