Вверх ↑
Этот топик читают: Гость
Ответов: 1926
Рейтинг: 172
#1: 2020-04-02 18:32:10 ЛС | профиль | цитата
Add(MainForm,2953706,217,343)
{
Position=1
Point(onKeyDown)
link(onKeyDown,3830916:doCase,[])
}
Add(InlineCode,10339731,266,196)
{
@Hint=#24:Глобальный перехват мыши|
EventPoints=#11:onMouseMove|13:onLButtonDown|11:onLButtonUp|13:onRButtonDown|11:onRButtonUp|11:onWheelDown|9:onWheelUp|8:onScroll|14:onX1ButtonDown|11:onX1BttonUp|14:onX2ButtonDown|11:onX2BttonUp|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|38:uses kol,Share,Debug,windows,messages;|0:|4:type|27: tagMSLLHOOKSTRUCT = record|12: pt:TPoint;|18: mouseData:dword;|14: flags:dword;|13: time:dword;|23: dwExtraInfo:^Cardinal|5: end;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|26: onMouseMove:THI_Event;|28: onLButtonDown:THI_Event;|26: onLButtonUp:THI_Event;|28: onRButtonDown:THI_Event;|26: onRButtonUp:THI_Event;|26: onWheelDown:THI_Event;|24: onWheelUp:THI_Event;|23: onScroll:THI_Event;|29: onX1ButtonDown:THI_Event;|27: onX1ButtonUp:THI_Event;|29: onX2ButtonDown:THI_Event;|27: onX2ButtonUp:THI_Event;|0:|23: constructor Create;|33: destructor Destroy; override;|0:|5: end;|0:|14:var H:THandle;|20: hac:THiAsmClass;|0:|14:implementation|0:|49:function hook(code,w,l:integer):Lresult; stdcall;|15:var str:string;|25: ll:tagMSLLHOOKSTRUCT;|15: d:LongWord;|5:begin|38: ll := tagMSLLHOOKSTRUCT(pointer(l)^);|0:|26: d := ll.mouseData shr 16;|46: if d and $8000 ‹› 0 then d := d or $FFFF0000;|0:|10: case w of|36: 512: _hi_OnEvent(hac.onMouseMove);|38: 513: _hi_OnEvent(hac.onLButtonDown);|36: 514: _hi_OnEvent(hac.onLButtonUp);|38: 516: _hi_OnEvent(hac.onRButtonDown);|36: 517: _hi_OnEvent(hac.onRButtonUp);|36: 519: _hi_OnEvent(hac.onWheelDown);|34: 520: _hi_OnEvent(hac.onWheelUp);|45: 522: _hi_OnEvent(hac.onScroll, int2str(d));|12: 523: begin|17: case d of|44: 1: _hi_OnEvent(hac.onX1ButtonDown);|44: 2: _hi_OnEvent(hac.onX2ButtonDown);|12: end;|11: end;|12: 524: begin|17: case d of|42: 1: _hi_OnEvent(hac.onX1ButtonUp);|42: 2: _hi_OnEvent(hac.onX2ButtonUp);|12: end;|11: end;|5: end;|38: result := CallNextHookEx(H,code,w,l);|4:end;|0:|31:constructor THiAsmClass.Create;|5:begin|18: inherited Create;|13: hac := self;|48: H := SetWindowsHookEx(14, @hook, hInstance, 0);|82: if H = 0 then messagebox(ReadHandle,'Ошибка перехвата мыши','ERROR',mb_iconhand);|4:end;|0:|31:destructor THiAsmClass.Destroy;|5:begin|24: UnhookWindowsHookEx(H);|19: inherited Destroy;|4:end;|0:|4:end.|
link(onX1ButtonDown,6694040:doEvent1,[])
}
Add(PictureStream,12249112,448,252)
{
FileName=".\photo.jpg"
link(onLoad,8590706:doLoad,[])
}
Add(Image,8590706,511,252)
{
Left=20
Top=15
Width=350
Height=230
}
Add(Hub,6694040,343,252)
{
InCount=2
OutCount=3
link(onEvent1,12249112:doLoad,[])
link(onEvent3,12312137:doTimer,[(381,272)(381,300)])
}
Add(Timer,12312137,448,294)
{
Enable=1
AutoStop=1
link(onTimer,8590706:doClear,[(496,300)(496,265)])
}
Add(Case,3830916,266,364)
{
Value=Integer(13)
link(onTrue,6694040:doEvent2,[(320,377)(320,265)])
}
Вот такой простой код и рядом прикреплён файл изображения, на котором тестировалось.

Суть в том, что программа загружает картинку, отображает (и стирает через секунду - это нужно для эксперимента).
Загрузка происходит как при нажатии одной из боковых кнопок мыши, так и при нажатии на Enter. Так вот, Enter всегда работает отлично. А вот хук мыши слетает после нескольких нажатий на боковую кнопку, причём только если картинка достаточно больших размеров и JPG (как в примере). На маленьких картинках хук не слетает. Причём в XP всё работало отлично, в 7 - слетает.

Т.е. последовательность действий такая:
1. Положить картинку JPG во вложении рядом с программой (или попробовать свою JPG, размерами не меньше 3648*2736).
2. Запустить программу в Win7 (или, возможно, выше), понажимать на одну из боковых кнопок мыши - картинка будет загружаться и исчезать.
3. Через несколько нажатий хук перестаёт работать, тогда как по Enter работать продолжает.
С загрузкой картинок других форматов такой проблемы нет.

Проблема обнаружилась совершенно случайно, перерыл всё, что знал, но не могу её решить. В чём может быть дело?

Редактировалось 2 раз(а), последний 2020-04-02 18:38:42
карма: 9
0
файлы: 1photo.rar [1MB] [373]
Ответов: 16884
Рейтинг: 1239
#2: 2020-04-02 18:42:38 ЛС | профиль | цитата
... hiInlineCode_4A7FA40.pas(52) Error: Illegal character in input file: '<' ($8B)
После исправления работает нормально. w10.
Если путь к файлу картинки .\photo.jpg , то это не
3042 писал(а):
Положить картинку JPG во вложении рядом с программой


Редактировалось 2 раз(а), последний 2020-04-02 19:02:32
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 2268
Рейтинг: 677
#3: 2020-04-02 19:37:46 ЛС | профиль | цитата
Tad писал(а):
hiInlineCode_4A7FA40.pas(52) Error: Illegal character in input file: '<' ($8B)
Это форум коверкает знаки больше и меньше.
3042 писал(а):
понажимать на одну из боковых кнопок мыши - картинка будет загружаться и исчезать.
У меня на этом этапе не работает. Ни одного нажатия не срабатывает. По enter загружает. win7
карма: 11

0
Ответов: 1926
Рейтинг: 172
#4: 2020-04-02 20:41:13 ЛС | профиль | цитата
sla8a, на обе боковые пробовал нажимать? Потому что подключено к одной из них.
карма: 9
0
Ответов: 163
Рейтинг: 33
#5: 2020-04-02 21:20:19 ЛС | профиль | цитата
Очень плохо вызывать долгие операции в том же потоке, в котором вызван обработчик хука. У низкоуровневых хуков есть таймаут выполнения. Начиная с Windows7, если обработчик не укладывается в этот таймаут, система молча снимает хук. Для решения проблемы в приведенной схеме надо загрузку картинки сделать через отдельный поток. Таймер подключить на onSyncExec.
карма: 3

1
Голосовали:3042
Ответов: 8926
Рейтинг: 823
#6: 2020-04-02 21:34:10 ЛС | профиль | цитата
3042, что бы было понятнее замечание GreM вот схемка (сделал переключение из кучи картинок. Всё работает. Win-10
(не забудьте "<>" исправить и свой путь к куче картинок)


Add(MainForm,6594676,266,196)
{
Position=1
Point(onKeyDown)
link(onCreate,6066342:doWork2,[])
link(onKeyDown,3830916:doCase,[])
}
Add(InlineCode,10339731,315,119)
{
@Hint=#24:Глобальный перехват мыши|
EventPoints=#11:onMouseMove|13:onLButtonDown|11:onLButtonUp|13:onRButtonDown|11:onRButtonUp|11:onWheelDown|9:onWheelUp|8:onScroll|14:onX1ButtonDown|11:onX1BttonUp|14:onX2ButtonDown|11:onX2BttonUp|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|38:uses kol,Share,Debug,windows,messages;|0:|4:type|27: tagMSLLHOOKSTRUCT = record|12: pt:TPoint;|18: mouseData:dword;|14: flags:dword;|13: time:dword;|23: dwExtraInfo:^Cardinal|5: end;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|26: onMouseMove:THI_Event;|28: onLButtonDown:THI_Event;|26: onLButtonUp:THI_Event;|28: onRButtonDown:THI_Event;|26: onRButtonUp:THI_Event;|26: onWheelDown:THI_Event;|24: onWheelUp:THI_Event;|23: onScroll:THI_Event;|29: onX1ButtonDown:THI_Event;|27: onX1ButtonUp:THI_Event;|29: onX2ButtonDown:THI_Event;|27: onX2ButtonUp:THI_Event;|0:|23: constructor Create;|33: destructor Destroy; override;|0:|5: end;|0:|14:var H:THandle;|20: hac:THiAsmClass;|0:|14:implementation|0:|49:function hook(code,w,l:integer):Lresult; stdcall;|15:var str:string;|25: ll:tagMSLLHOOKSTRUCT;|15: d:LongWord;|5:begin|38: ll := tagMSLLHOOKSTRUCT(pointer(l)^);|0:|26: d := ll.mouseData shr 16;|46: if d and $8000 <> 0 then d := d or $FFFF0000;|0:|10: case w of|36: 512: _hi_OnEvent(hac.onMouseMove);|38: 513: _hi_OnEvent(hac.onLButtonDown);|36: 514: _hi_OnEvent(hac.onLButtonUp);|38: 516: _hi_OnEvent(hac.onRButtonDown);|36: 517: _hi_OnEvent(hac.onRButtonUp);|36: 519: _hi_OnEvent(hac.onWheelDown);|34: 520: _hi_OnEvent(hac.onWheelUp);|45: 522: _hi_OnEvent(hac.onScroll, int2str(d));|12: 523: begin|17: case d of|44: 1: _hi_OnEvent(hac.onX1ButtonDown);|44: 2: _hi_OnEvent(hac.onX2ButtonDown);|12: end;|11: end;|12: 524: begin|17: case d of|42: 1: _hi_OnEvent(hac.onX1ButtonUp);|42: 2: _hi_OnEvent(hac.onX2ButtonUp);|12: end;|11: end;|5: end;|38: result := CallNextHookEx(H,code,w,l);|4:end;|0:|31:constructor THiAsmClass.Create;|5:begin|18: inherited Create;|13: hac := self;|48: H := SetWindowsHookEx(14, @hook, hInstance, 0);|82: if H = 0 then messagebox(ReadHandle,'Ошибка перехвата мыши','ERROR',mb_iconhand);|4:end;|0:|31:destructor THiAsmClass.Destroy;|5:begin|24: UnhookWindowsHookEx(H);|19: inherited Destroy;|4:end;|0:|4:end.|
link(onX1ButtonDown,9595726:doWork2,[])
}
Add(PictureStream,12249112,609,182)
{
link(onLoad,9021919:doEvent1,[])
}
Add(Image,8590706,686,182)
{
Left=20
Top=15
Width=350
Height=230
}
Add(Case,3830916,315,217)
{
Value=Integer(13)
link(onTrue,6066342:doWork3,[(375,230)])
}
Add(HubEx,9595726,371,175)
{
link(onEvent,7191634:doEvent1,[])
}
Add(HubEx,6066342,371,210)
{
Angle=3
link(onEvent,9595726:doWork3,[])
}
Add(Math,406566,518,182)
{
Op2=1
ResultType=0
Default=7167
link(onResult,15127642:doString,[])
link(Op1,406566:Result,[(524,173)(510,173)(510,222)(524,222)])
}
Add(FormatStr,15127642,560,182)
{
DataCount=1
Mask="C:\Users\LA\МоиРис\Крым2015\IMG_%1.JPG"
Point(FString)
link(onFString,12249112:doLoad,[])
}
Add(Hub,7191634,385,175)
{
link(onEvent1,16316145:doStart,[(410,181)(410,230)])
link(onEvent2,5848490:doStart,[])
}
Add(TimeCounter,16316145,686,224)
{
link(onStop,6594676:doCaption,[(725,237)(725,265)(270,265)(270,202)])
}
Add(Hub,9021919,651,182)
{
link(onEvent1,8590706:doLoad,[])
link(onEvent2,16316145:doStop,[(676,195)(676,237)])
}
Add(Thread,5848490,420,182)
{
Delay=0
FastStop=0
link(onExec,5904980:doStart,[])
}
Add(Thread,5904980,469,182)
{
Delay=0
FastStop=0
link(onExec,406566:doOperation,[])
}

карма: 19

1
Голосовали:3042
Ответов: 163
Рейтинг: 33
#7: 2020-04-02 21:48:51 ЛС | профиль | цитата
Кстати, с этим нововведением в Windows7 появляется еще одна не очевидная проблема. На самом деле таймаут распространяется не на отдельный обработчик хука, а на все обработчики, которые были зарегистрированы на данный тип хука. В результате может возникнуть следующая ситуация. Пришло событие, система вызывает первый обработчик в цепочке. Допустим это наша программа. Она быстренько делает что задумано и вызывает CallNextHookEx. Допустим следующий в цепочке обработчик находится в чужой программе, и он не укладывается в таймаут. Система тихо снимат первый хук в цепочке (то есть наш). Получается что мы пострадали из-за нерасторопности чужой программы.
карма: 3

0
Ответов: 1926
Рейтинг: 172
#8: 2020-04-02 23:34:38 ЛС | профиль | цитата
Действительно, есть проблема: https://www.cyberforum.ru/win-api/thread915456.html
Но я решил ставить не поток, а просто
увеличение значения LowLevelHooksTimeout в ветке HKCU\Control Panel\Desktop реестра...

Это можно делать и программно. Поставил 10 000 мс. Пока полёт нормальный.
карма: 9
0
8
Сообщение
...
Прикрепленные файлы
(файлы не залиты)