![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Hook: что неправильно? [D5, Win2k]
Alx2 © (2002-02-13 11:58:00)Делаю hook из DLL:
Function SetHook: HHOOK; Stdcall;
Begin
If (AInstance = LongWord( - 1)) Then
AInstance := HInstance;
hhk := SetWindowsHookEx(WH_CBT,
@ShellProc,
HInstance,
0
);
Result := hhk;
End;
Вот ShellProc, которая не работает для других приложений, а для родного, вызывающего SetHook, работает:
Function ShellProc(nCode: Integer; WPARAM, LPARAM: Integer): Integer; Stdcall;
Var
Str : String;
CBTCreateWnd: PCBTCreateWnd Absolute LPARAM;
Begin
Result := CallNextHookEx(hhk, nCode, WPARAM, LPARAM);
If (nCode = HCBT_CREATEWND) And (Pointer(LPARAM) <> Nil) And (CBTCreateWnd^.lpCs <> Nil) Then
Begin
If MyWindow = 0 Then
MyWindow := FindWindow("TWatcherForm", "WatcherForm");
Str := CBTCreateWnd^.lpCs^.lpszClass;
SendMessage(MyWindow, WM_SETTEXT, 8101973, Integer(PChar(Str)));
End;
End;
А если исправить так:
Function ShellProc(nCode: Integer; WPARAM, LPARAM: Integer): Integer; Stdcall;
Var
Str : String;
CBTCreateWnd: PCBTCreateWnd Absolute LPARAM;
Begin
Result := CallNextHookEx(hhk, nCode, WPARAM, LPARAM);
If (nCode = HCBT_CREATEWND) And (Pointer(LPARAM) <> Nil) And (CBTCreateWnd^.lpCs <> Nil) Then
Begin
If MyWindow = 0 Then
MyWindow := FindWindow("TWatcherForm", "WatcherForm");
SendMessage(MyWindow, WM_SETTEXT, 8101973, Integer(CBTCreateWnd^.lpCs^.lpszClass));
End;
End;
- работает всегда.
Что делаю не так? Где грабли?
Что сделать, чтобы работал первый (именно нужный мне) вариант?
Alx2 (2002-02-15 15:25:00) [1]И все-таки где причина глюка?
Alx2 (2002-02-14 07:47:00) [2]Как же быть с проблемой, описанной в сообщении Alx2 © (13.02.02 13:16)?
Alx2 (2002-02-13 13:26:00) [3]> Fellomena (13.02.02 13:18)
Привет! :))
>А почему бы не попробывать для главного приложения
>в которое ты отправляешь сообщение определить WM_USER+666
>и пользоваться им из DLL ? Может поможет ?
Попробую, хотя и не уверен в успехе.
Вот сейчас юзаю казенный wm_copydata, но глюк сохранился :(
>Для передачи дескриптора установленного hook
>используй memory mapped files.
Спасибо, это я не учел :))
Fellomena (2002-02-13 13:18:00) [4]А почему бы не попробывать для главного приложения в которое ты отправляешь сообщение определить WM_USER+666 и пользоваться им из DLL ? Может поможет ? (у меня работало нормально)
Result := CallNextHookEx(hhk, nCode, WPARAM, LPARAM); - если твою DLL загрузит другой процесс, то следующий hook из цепочки не вызовется, потому что hhk в другом процессе будет инициализирована 0 при отображении DLL на адресное пространства процесса, загружающего твою DLL.
Для передачи дескриптора установленного hook используй memory mapped files.
Alx2 (2002-02-13 13:18:00) [5]Сейчас проверил без Delphi - то же самое :(
Alx2 (2002-02-13 13:16:00) [6]>иначе сообщения придут в другое окно.
Да ну и пусть идут. Не должно же это убивать проги, на которые хуки расставились.
Нет, Виктор. Думаю, дело в другом. Ведь все работает, если я
Делаю так:
Str := intToStr(Random(1000000));
SendMessage(MyWindow, WM_SETTEXT, 8101973, Integer(PChar(Str)));
И никогда не работает (для чужих приложений: они не могут создать окна и валятся кто-как: кто - по недопустимым операциям, кто - просто молча исчезает, а со своим приложением - все ok) если делаю так:
Str := CBTCreateWnd^.lpCs^.lpszClass;
SendMessage(MyWindow, WM_SETTEXT, 8101973, Integer(PChar(Str)));
А вот так - снова всегда работает:
SendMessage(MyWindow, WM_SETTEXT, 8101973, Integer(CBTCreateWnd^.lpCs^.lpszClass));
Получается, глюк рождается при попытке считать внутрь Str этот CBTCreateWnd^.lpCs^.lpszClass, или, даже, при попытке посчитать его длину через strlen (уже параноиком становлюсь, но специально это проверял).
Виктор Щербаков (2002-02-13 13:02:00) [7]1. Насчет адресного пространства я был не прав.
Для WM_SETTEXT это безразлично.
2. FindWindow может находить в точности такое же окно в
IDE Delphi (у формы такое же имя класса). А вот искать по
заголовку я бы не советовал, т.к. он меняется.
Попробуй убрать в FindWindow заголовок окна (т.е. nil
поставить) и не запускай программу вместе с Delphi, иначе сообщения придут в другое окно.
Alx2 (2002-02-13 12:42:00) [8]Попробовал с wm_copydata. Та же самая проблема.
Видимо, стоит попробовать memory mapped files.
Но, почему ТАК происходит?
Alx2 (2002-02-13 12:19:00) [9]Да уж... причем этот интерес - главная часть проблемы, так как передачу данных более или менее коряво можно сделать. А тут такая разница.
Виктор Щербаков (2002-02-13 12:12:00) [10]>Хорошо, а почему тогда всегда работает такой вот бред
А вот это действительно интересно.
Alx2 (2002-02-13 12:08:00) [11]>Виктор Щербаков © (13.02.02 12:04)
>Используй WM_COPYDATA для передачи строки целиком.
Спасибо, сейчас попробую...
>В первом варианте указатель на что ты передаешь?
Хорошо, а почему тогда всегда работает такой вот бред:
Function ShellProc(nCode: Integer; WPARAM, LPARAM: Integer): Integer; Stdcall;
Var
Str : String;
CBTCreateWnd: PCBTCreateWnd Absolute LPARAM;
Begin
Result := CallNextHookEx(hhk, nCode, WPARAM, LPARAM);
If (nCode = HCBT_CREATEWND) And (Pointer(LPARAM) <> Nil) And (CBTCreateWnd^.lpCs <> Nil) Then
Begin
If MyWindow = 0 Then
MyWindow := FindWindow("TWatcherForm", "WatcherForm");
Str := intToStr(Random(1000000));
SendMessage(MyWindow, WM_SETTEXT, 8101973, Integer(PChar(Str)));
End;
End;
Виктор Щербаков (2002-02-13 12:04:00) [12]В первом варианте указатель на что ты передаешь?
В каком он адресном пространстве?
Используй WM_COPYDATA для передачи строки целиком.