Форум: "WinAPI";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];
ВнизПроблема с SetWindowsHookEx(WH_CallWndProc,...) Найти похожие ветки
← →
KonstantinM © (2006-02-22 11:12) [0]В программе установлен хук SetWindowsHookEx(WH_CallWndProc,...). После этого перестает работать SendMessageW(UnicodeEditHandle, EM_GETLINE, ...) - всегда возвращает путую строку. Проблема также проявляется, если запустить внешнюю программу, устанавливающую этот хук - например Winspector Spy.
Кто-нибудь сталкивался с такой проблемой? Можно как-нибудь заставить SendMessageW работать?
← →
Сергей М. © (2006-02-22 11:18) [1]Устрани ошибки в коде обработчика хука WH_CallWndProc
← →
KonstantinM © (2006-02-22 11:29) [2]Установка:
HookHandle:= SetWindowsHookExW(WH_CALLWNDPROC, CallWndProcHook, 0, GetCurrentThreadId);
Обработчик:
function CallWndProcHook(Code: Integer; WParam: WPARAM; LParam: LPARAM): RESULT; stdcall;
begin
Result := CallNextHookEx(HookHandle, Code, WParam, LParam);
end;
После этого SendMessageW(UnicodeEditHandle, EM_GETLINE, ...) перестает работать. Сообщение EM_GETLINE до обработчика хука не доходит.
← →
Сергей М. © (2006-02-22 11:51) [3]Этот код даже скомпилирован быть не может, не говоря уже о его исполнении.
HookHandle:= SetWindowsHookExW(WH_CALLWNDPROC, @CallWndProcHook, 0, GetCurrentThreadId);
> Обработчик:
> function CallWndProcHook(Code: Integer; WParam: WPARAM;
> LParam: LPARAM): RESULT; stdcall;
Какой еще RESULT ?
Зачем изобретать сомнительные идентификаторы ? Ведь Result - зарезервированный идентификатор !
Чем HHOOK не угодил ?
← →
KonstantinM © (2006-02-22 11:57) [4]Опечатка вышла, должно быть LRESULT.
Желающим могу выслать тестовый пример.
← →
KonstantinM © (2006-02-22 12:07) [5]Вот, собственно и код примера. Все компилируется отлично.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TntComCtrls, ComCtrls, TntStdCtrls;
type
TForm3 = class(TForm)
btLine: TButton;
Label2: TLabel;
TntMemo1: TTntMemo;
procedure btLineClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
public
end;
var
Form3: TForm3;
var
HookHandle: HHOOK;
implementation
{$R *.dfm}
function CallWndProcHook(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
Result := CallNextHookEx(HookHandle, Code, WParam, LParam);
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
HookHandle := SetWindowsHookExW(WH_CALLWNDPROC, CallWndProcHook, 0, GetCurrentThreadId);
end;
procedure TForm3.FormDestroy(Sender: TObject);
begin
if HookHandle <> 0 then
UnhookWindowsHookEx(HookHandle);
end;
procedure TForm3.btLineClick(Sender: TObject);
var
Text :array[0..4095] of wideChar;
Len :Integer;
s: widestring;
begin
Word((@Text)^) := SizeOf(Text);
Len := SendMessageW(TntMemo1.Handle, EM_GETLINE, 0, Longint(@Text));
SetLength(s, Len);
if Len > 0 then
move(text, s[1], len * 2);
Label2.Caption:= s;
end;
end.
← →
Сергей М. © (2006-02-22 12:14) [6]
> должно быть LRESULT
Вообще-то в соответствии с Windows.pas должен быть HHOOK (= Longint), а не LRESULT (= Longword) .. Ну да это не принципиально .. В целом когда речь идет о хэндлах, лучше всего указывать тип THandle - он "универсален" и в восприятии-понимании и в совместимости
> Желающим могу выслать тестовый пример
В нем, надеюсь, "баран" (@CallWndProcHook) присутствует ?
В нем есть проверка-анализ результата вызова ф-ции SetWindowsHookExW() ?
← →
Сергей М. © (2006-02-22 12:20) [7]
> KonstantinM © (22.02.06 12:07) [5]
← →
KonstantinM © (2006-02-22 12:24) [8]Уважаемый Cергей, здесь можно как с "бараном", так и без него - код, по крайней мере в D7, компилируется одинаковый. И работает одинаково. И с результатом SetWindowsHookExW все в порядке.
← →
Сергей М. © (2006-02-22 12:27) [9]
> KonstantinM © (22.02.06 12:07) [5]
Твой код у меня расчудесно работает.
← →
Сергей М. © (2006-02-22 12:32) [10]
> здесь можно как с "бараном", так и без него
Это Зависит от объявления типа рез-та ф-ции CallWndProcHook() - стоит только изменить его на "HHOOK" (что естественно. поскольку var HookHandle: HHOOK), как твое утверждение в [8] не выдерживает критики.
← →
KonstantinM © (2006-02-22 12:39) [11]Да ничего не работает, как был результат SendMessageW равен 0 так и остался.
← →
Сергей М. © (2006-02-22 12:42) [12]т.е. ты утверждаешь, что если закомментировать строчку, устанавливающую хук, ф-ция SendMessageW() ведет себя совершенно иначе, т.е. возвращает ожидаемый "не ноль" ?
← →
KonstantinM © (2006-02-22 12:44) [13]Да. TntMemo1 содержит строку "TntMemo1"
← →
Сергей М. © (2006-02-22 12:47) [14]Так.
И кр. этого ты утверждаешь, что отладчик при успешно установленном хуке не "ловит" брейкпойнт в теле ф-ции CallWndProcHook() ?
← →
KonstantinM © (2006-02-22 12:56) [15]Ловит, но EM_GETLINE после SendMessageW там не появляется. Если послать с помощью SendMessage - работает.
Протестировал в Microsoft Virtual PC c Windows 2000 SP2 - и, надо же, работает c хуком нормально. До этого проверил на трех машинах с WinXP Sp1 и Sp2 - не работает ни в какую. У меня уже появилось подозрения, что на них установлена какая-то программа с некорректной реализацией хука, мешающая работе SendMessageW.
← →
Сергей М. © (2006-02-22 13:06) [16]
> KonstantinM © (22.02.06 12:56) [15]
На чудеса похоже это ..
> какая-то программа с некорректной реализацией хука
Но ты же сам говоришь, что без установки своего звена в цепи WH_CALLWNDPROC-хуков "на трех машинах с WinXP Sp1 и Sp2 " ф-ция SendMeassageW() работает как и положено ? Тогда причем здесь, спрашивается, другие хук-программы ?
Попробуй установить WH_CALLWNDPROCRET, посмотри что и как в этом случае меняется ...
← →
KonstantinM © (2006-02-22 13:14) [17]WH_CALLWNDPROCRET - тот же результат. Протестировал еще на нескольких компьютерах. На всех с WinXP не работает, на всех Win2000 - работает.
> Но ты же сам говоришь, что без установки своего звена в
> цепи WH_CALLWNDPROC-хуков "на трех машинах с WinXP Sp1
> и Sp2 " ф-ция SendMeassageW() работает как и положено ?
> Тогда причем здесь, спрашивается, другие хук-программы ?
>
Если хук не устанавливать SendMeassageW работает нормально на всех компьютерах, но если запустить Winspector Spy - на WinXP перестает работать, на Win2000 - работает.
← →
Сергей М. © (2006-02-22 13:19) [18]Что это за дрянь - Winspector Spy - я не знаю.
Не исключено что работает оно далеко не как положено.
Я предполагаю, что если не запускать тот самый Winspector Spy, то твой хук будет успешно работать в любой операционной среде.
← →
KonstantinM © (2006-02-22 13:22) [19]Winspector Spy http://www.windows-spy.com/ только для примера.
← →
KonstantinM © (2006-02-22 13:23) [20]
> Я предполагаю, что если не запускать тот самый Winspector
> Spy, то твой хук будет успешно работать в любой операционной
> среде
На всех с WinXP не работает
← →
Сергей М. © (2006-02-22 13:30) [21]
> KonstantinM © (22.02.06 13:23) [20]
> На всех с WinXP не работает
Ну и выкинь эту дрянь в мусор !
Она тебе зачем вообще-то ? Для отладки собственных вызовов есть встроенный в делфи отладчик. Для просмотра же любых (своих, чужих - не важно) вызовов есть проверенная временем SpyXX.exe из состава MSVS.
← →
Сергей М. © (2006-02-22 13:33) [22]
> На всех с WinXP не работает
Я, наверно, не понял - не работает именно ТВОЙ код как таковой ? Вне зависимости ни от чего ?
Или твой код не работает в этой опер.среде ТОЛЬКО в присутствии того самого Winspector"а ?
← →
Eraser © (2006-02-23 00:03) [23]
> KonstantinM © (22.02.06 11:12)
Вот пример библиотеки, в которой правильно реализован глобальный хук, хотя и не WH_CALLWNDPROC, но особой разницы нет.
http://kladovka.net.ru/index.cgi?pid=list&rid=195
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.018 c