Вверх ↑
Этот топик читают: Гость
Ответов: 1926
Рейтинг: 172
#1: 2016-02-10 12:01:45 ЛС | профиль | цитата
#pas
function hook(code,w,l:integer):Lresult; stdcall;
var str:string;
begin
str:=Int2Str(LoWord(w))+'_'+Int2Str(HiWord(w));
_hi_OnEvent(ev,str);
result := CallNextHookEx(H, code, w, l);
End;

ev определена как THI_Event в public THiAsmClass'а. Но при компиляции пишет:
компилятор писал(а):
C:\Program Files\HiAsm_AltBuild\Elements\delphi\code\hiInlineCode_1553EB0.pas(28) Error: Undeclared identifier: 'ev'


Понимаю, что из внешней процедуры метод объекта просто так не вызвать, но как это сделать?
карма: 9
0
Разработчик
Ответов: 4698
Рейтинг: 426
#2: 2016-02-10 12:33:41 ЛС | профиль | цитата
Функция hook должна получить доступ к экземпляру класса THiAsmClass. Если как-то можно передать это в функцию hook - так и делай. Иначе сложнее...
Если такой IC всего один, можно набыдлокодить глобальную переменную типа THiAsmClass и при инициализации компонента (в конструкторе) этой глобальной переменной присвоить self.
Если же таких IC много, нужно либо регистрировать несколько хуков в одной программе, либо делать глобальный (для разных IC) массив обработчиков, которые будут в цикле вызываться из hook().
карма: 10
1
Голосовали:3042
Ответов: 4630
Рейтинг: 749
#3: 2016-02-10 13:20:46 ЛС | профиль | цитата
Можно так:


#pas

var
CmpList: PList;

function Hook(Code, W, L: Integer): LResult; stdcall;
var
Str: string;
I: Integer;
begin
if CmpList <> nil then
begin
Str := Int2Str(LoWord(W))+'_'+Int2Str(HiWord(W));
for I := 0 to CmpList.Count - 1 do
_hi_OnEvent(THiAsmClass(CmpList.Items[I]).ev, Str);
end;

Result := CallNextHookEx(H, Code, W, L);
end;

procedure AddToList(Component: THiAsmClass);
begin
if CmpList = nil then
begin
CmpList := NewList;
SetWindowsHookEx(...); // Установили хук
end;
//if CmpList.IndexOf(Component) = -1 then // Защита от дублирования, если такое возможно
CmpList.Add(Component);
end;


procedure RemoveFromList(Component: THiAsmClass);
begin
if CmpList <> nil then
begin
CmpList.Remove(Component);
if CmpList.Count = 0 then
begin
UnhookWindowsHookEx(...); // Убрали хук, если нет слушающих компонентов
CmpList.Free;
CmpList := nil;
end;
end;
end;


1) Когда компонент хочет подписаться на сообщения - вызывает AddToList(Self)
2) Когда хочет отписаться - RemoveFromList(Self)
3) Хук устанавливается при первом подписчике, снимается, когда подписчиков не осталось.
карма: 26

1
Голосовали:3042
Разработчик
Ответов: 4698
Рейтинг: 426
#4: 2016-02-10 21:14:20 ЛС | профиль | цитата
Netspirit писал(а):
Можно так:

Только придется учесть, что если будет несколько компонентов IC (пусть даже с одним и тем же кодом) - это не сработает, будет просто создаваться куча ловушек и по 1-му подписчику, т.к. HiAsm на каждый IC генерирует уникальное имя модуля. Хотя, может, функция "копировать ссылку" решит эту проблему.
карма: 10
0
Ответов: 4630
Рейтинг: 749
#5: 2016-02-11 11:26:08 ЛС | профиль | цитата
Можно подправить код, чтобы в список добавлять не THiasmClass, а собственно THiEvent из свойства ev. Затем вынести приведенный код в отдельный модуль, который и подключать в IC.
карма: 26

0
Ответов: 1926
Рейтинг: 172
#6: 2016-02-11 12:47:33 ЛС | профиль | цитата
Я хотел сделать обработчик на боковые клавиши мыши, поставил хук, а теперь появилась идея добавить глобальный перехват в компонент MouseEvent (на все клавиши мыши). Протестируйте пока такой вариант:

code_36932.txt
Работает ли на Win7/8 и т.д. Может, есть идеи оптимизации кода. И вообще - нужны ли кому такие функции. Если всё нормально - буду доделывать компонент.

ps. Кстати, несмотря на то что в оригинале код вставлялся в dll, у меня заработало и в IC.
------------ Дoбавленo в 12.11:
Netspirit писал(а):
Можно подправить код, чтобы в список добавлять не THiasmClass, а собственно THiEvent из свойства ev. Затем вынести приведенный код в отдельный модуль, который и подключать в IC.


Что-то не получается:

Add(InlineCode,12360657,280,133)
{
WorkPoints=#7:sethook|10:removehook|
EventPoints=#2:ev|
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|17: ev:THI_Event;|0:|23: constructor Create;|48: procedure sethook(var dt:TData; index:word);|51: procedure removehook(var dt:TData; index:word);|0:|5: end;|0:|20:var H,wh,cw:THandle;|20: hacev:THI_Event;|0:|14:implementation|0:|31:constructor THiAsmClass.Create;|5:begin|18: inherited Create;|18: hacev := self.ev;|4:end;|0:|49:function hook(code,w,l:integer):Lresult; stdcall;|15:var str:string;|25: ll:tagMSLLHOOKSTRUCT;|5:begin|38: ll := tagMSLLHOOKSTRUCT(pointer(l)^);|64: str := Int2Str(LoWord(w))+' '+Int2Str(HiWord(ll.mouseData));|53: //str:=Int2Str(LoWord(w))+' '+Int2Str(HiWord(w));|43: {if w <> 512 then} _hi_OnEvent(hacev,str);|38: result := CallNextHookEx(H,code,w,l);|4:End;|0:|30:procedure THiAsmClass.sethook;|5:begin|48: H := SetWindowsHookEx(14, @hook, hInstance, 0);|70: if H = 0 then messagebox(0,'AAAAAA!!! ERROR!!!','ERROR',mb_iconhand);|4:end;|0:|33:procedure THiAsmClass.removehook;|5:begin|24: UnhookWindowsHookEx(H);|4:end;|0:|4:end.|
link(ev,7136822:doAdd,[])
}
Add(Button,6327570,210,154)
{
Left=15
Top=35
Width=85
Caption="removehook"
link(onClick,12360657:removehook,[(261,160)(261,146)])
}
Add(Button,14432370,210,105)
{
Left=15
Top=10
Width=85
Caption="sethook"
link(onClick,12360657:sethook,[(261,111)(261,139)])
}
Add(Memo,7136822,343,133)
{
Left=110
Top=5
Width=125
Height=260
AddType=1
ScrollBars=2
}
карма: 9
0
файлы: 1code_36932.txt [1.7KB] [632]
Ответов: 4630
Рейтинг: 749
#7: 2016-02-11 12:49:51 ЛС | профиль | цитата
На момент THiAsmClass.Create событие ev ещё не назначено. hacev := self.ev нужно делать позже, например, в THiAsmClass.sethook. Либо объявить ev как property, и присваивать в соответствующем set-ере.
карма: 26

0
Гость
Ответов: 17029
Рейтинг: 0
#8: 2016-02-11 13:04:06 правка | ЛС | профиль | цитата


Редактировалось 5 раз(а), последний 2021-05-21 06:12:34
карма: 0

0
Ответов: 1926
Рейтинг: 172
#9: 2016-02-11 13:37:31 ЛС | профиль | цитата
81.91.50.188 писал(а):
[url][/url]http://forum.hiasm.net/forum.html?q=3&p=200459

Эх, отстал я от времени...
То есть, нет смысла использовать хуки, надо сейчас переходить на RawInput, правильно я понял?
карма: 9
0
9
Сообщение
...
Прикрепленные файлы
(файлы не залиты)