OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 29 Март, 2024 00:13

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Прокрутка Крысой
СообщениеДобавлено: Пятница, 15 Апрель, 2011 13:44 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Мерцает текст при прокрутке колесом мыши. Раздражает.

Проблема, как я понял, в сообщении WM_MOUSEWHEEL.
Т.е. посылается куча этих сообщений и BlackBox их старательно последовательно пытается обработать.

Думаю, что их нужно толкать в буфер и схлопывать.

Вопрос: Будет ли правильным навесить HOOK? Ну и в нем это обрабатывать, а окну посылать обычный скрол. Или есть другое решение?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 10:08 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
В модуле WinApi неправильно описан хэндлер хука.
Должно быть так:
Код:
HOOKPROC* = PROCEDURE (p1: INTEGER; p2: WPARAM; p3: LPARAM): INTEGER;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 10:32 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Сталкивался. Если правильно припоминаю, то это универсальный тип (чтобы не описывать все виды хуков). Для винапи нужен только адрес, сигнатура роли не играет...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 11:01 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Еще мелкий трабл: не могу поставить локальный хук.

Глобальный нормально ставится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 11:08 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Код:
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


Что не так делаю?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 11:10 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Если

mhook := WinApi.SetWindowsHookEx(14, Handler, 0, thrd);

заменить на:

mhook := WinApi.SetWindowsHookEx(14, Handler, 0, 0);

То будет глобальный, и будет работать. А локальный никак


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 12:04 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
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.
Hook Scope
...
WH_MOUSE Thread or global
WH_MOUSE_LL Global only
У вас вместо именованной константы используется число (буу!!) 14, это соответствует WH_MOUSE_LL.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Понедельник, 18 Апрель, 2011 12:09 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
ТОЧНО!!! ЗАРАБОТАЛО!

Спасибо большое


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Четверг, 21 Апрель, 2011 08:52 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Еще в модуле WinApi не хватает структуры появившейся в Win2k:
Код:
MouseHookStructEx = POINTER TO RECORD [untagged]
      pt*: WinApi.POINT;
      hwnd*: WinApi.HWND;
      wHitTestCode*: INTEGER;
      dwExtraInfo*: INTEGER;
      mousedata*: INTEGER;
      END;


Это расширение MouseHookStruct с добавленным полем mousedata (в старшем слове хранится информация о прокрутке колесом)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Четверг, 21 Апрель, 2011 09:25 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Чего не хватает в WinApi можно спокойно организовать в дополнительном инт-м модуле.

WinHdrs - дополнительные интерфейсные модули WinAPI --- тут модуль WinApiEx. Можете добавить


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Четверг, 21 Апрель, 2011 15:33 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Вот родил уродца: ОСТОРОЖНО ЭКСПЕРИМЕТНАЛЬНЫЙ ГОВНОКОД. ПРОВЕРОК ВЫХОДА ЗА ГРАНИЦЫ НЕТ
Код:
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. Говнокод прокручивает без мерцания :lol:

С удовольствием приму советы по доведению этого г до ума


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Вторник, 03 Май, 2011 15:03 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Победить не удалось. В BlackBox слишком сильно все привязано на инкремент/декремент одной линии. Даже враппер не поможет.

Вообще победить можно, но нужно много править TextViews.

У меня желания пока нет


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Вторник, 03 Май, 2011 18:06 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Объясните, пожалуйста, как выглядит упомянутое мерцание при прокрутке колесом? Что-то не наблюдал у себя. Или не туда смотрю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 08:17 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Вот скриншот из CamStudio


Вложения:
стоп_кадр.png
стоп_кадр.png [ 128.84 КБ | Просмотров: 17788 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 08:37 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
На скриншоте смущают размытые пиксели. ББ не занимается размытием, точно говорю :) Может, видео выложите куда-нибудь?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 08:47 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
просматривать лучше в замедленном режиме


Вложения:
blik.7z [2.8 МБ]
Скачиваний: 574
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 14:29 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Иван Кузьмицкий писал(а):
На скриншоте смущают размытые пиксели.
ББ рисует посредством GDI. В Windows-7 GDI реализован как обёртка над новым графическим движком. Древние программы в Windows-7 выглядят как новенькие.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 14:40 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
У меня Win7.

[оффтоп]: Хорошая ось. Реально хорошая


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 14:59 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
ilovb, Вы случайно не про такое "мерцание"?


Вложения:
scr.png
scr.png [ 27.44 КБ | Просмотров: 17767 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Прокрутка Крысой
СообщениеДобавлено: Среда, 04 Май, 2011 15:30 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Да да. Я удивляюсь как Иван не заметил.

Фишка в том, что сообщения 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;


Особенно циклы улыбают :D

Буфер конечно не тут должен быть, а в диспетчере над вьюхой.
С другой стороны можно и тут... вот только другие вьюхи потеряют возможность получать детальный Wheel


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB