![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с SetWindowsHookEx(WH_CallWndProc,...) [D7, WinXP]
KonstantinM © (2006-02-22 11:12:00)В программе установлен хук SetWindowsHookEx(WH_CallWndProc,...). После этого перестает работать SendMessageW(UnicodeEditHandle, EM_GETLINE, ...) - всегда возвращает путую строку. Проблема также проявляется, если запустить внешнюю программу, устанавливающую этот хук - например Winspector Spy.
Кто-нибудь сталкивался с такой проблемой? Можно как-нибудь заставить SendMessageW работать?
Eraser (2006-02-23 00:03:00) [1]
> KonstantinM © (22.02.06 11:12)
Вот пример библиотеки, в которой правильно реализован глобальный хук, хотя и не WH_CALLWNDPROC, но особой разницы нет.
http://kladovka.net.ru/index.cgi?pid=list&rid=195
Сергей М. (2006-02-22 13:33:00) [2]
> На всех с WinXP не работает
Я, наверно, не понял - не работает именно ТВОЙ код как таковой ? Вне зависимости ни от чего ?
Или твой код не работает в этой опер.среде ТОЛЬКО в присутствии того самого Winspector'а ?
Сергей М. (2006-02-22 13:30:00) [3]
> KonstantinM © (22.02.06 13:23) [20]
> На всех с WinXP не работает
Ну и выкинь эту дрянь в мусор !
Она тебе зачем вообще-то ? Для отладки собственныхвызовов есть встроенный в делфи отладчик. Для просмотра же любых(своих, чужих - не важно) вызовов есть проверенная временем SpyXX.exe из состава MSVS.
KonstantinM (2006-02-22 13:23:00) [4]
> Я предполагаю, что если не запускать тот самый Winspector
> Spy, то твой хук будет успешно работать в любой операционной
> среде
На всех с WinXP не работает
KonstantinM (2006-02-22 13:22:00) [5]Winspector Spy http://www.windows-spy.com/только для примера.
Сергей М. (2006-02-22 13:19:00) [6]Что это за дрянь - Winspector Spy - я не знаю.
Не исключено что работает оно далеко не как положено.
Я предполагаю, что если не запускать тот самый Winspector Spy, то твой хук будет успешно работать в любой операционной среде.
KonstantinM (2006-02-22 13:14:00) [7]WH_CALLWNDPROCRET - тот же результат. Протестировал еще на нескольких компьютерах. На всех с WinXP не работает, на всех Win2000 - работает.
> Но ты же сам говоришь, что без установки своего звена в
> цепи WH_CALLWNDPROC-хуков "на трех машинах с WinXP Sp1
> и Sp2 " ф-ция SendMeassageW() работает как и положено ?
> Тогда причем здесь, спрашивается, другие хук-программы ?
>
Если хук не устанавливать SendMeassageW работает нормально на всех компьютерах, но если запустить Winspector Spy - на WinXP перестает работать, на Win2000 - работает.
Сергей М. (2006-02-22 13:06:00) [8]
> KonstantinM © (22.02.06 12:56) [15]
На чудеса похоже это ..
> какая-то программа с некорректной реализацией хука
Но ты же сам говоришь, что без установки своегозвена в цепи WH_CALLWNDPROC-хуков "на трех машинах с WinXP Sp1 и Sp2 " ф-ция SendMeassageW() работает как и положено ? Тогда причем здесь, спрашивается, другие хук-программы ?
Попробуй установить WH_CALLWNDPROCRET, посмотри что и как в этом случае меняется ...
KonstantinM (2006-02-22 12:56:00) [9]Ловит, но EM_GETLINE после SendMessageW там не появляется. Если послать с помощью SendMessage - работает.
Протестировал в Microsoft Virtual PC c Windows 2000 SP2 - и, надо же, работает c хуком нормально. До этого проверил на трех машинах с WinXP Sp1 и Sp2 - не работает ни в какую. У меня уже появилось подозрения, что на них установлена какая-то программа с некорректной реализацией хука, мешающая работе SendMessageW.
Сергей М. (2006-02-22 12:47:00) [10]Так.
И кр. этого ты утверждаешь, что отладчик при успешно установленном хуке не "ловит" брейкпойнт в теле ф-ции CallWndProcHook() ?
KonstantinM (2006-02-22 12:44:00) [11]Да. TntMemo1 содержит строку 'TntMemo1'
Сергей М. (2006-02-22 12:42:00) [12]т.е. ты утверждаешь, что если закомментировать строчку, устанавливающую хук, ф-ция SendMessageW() ведет себя совершенно иначе, т.е. возвращает ожидаемый "не ноль" ?
KonstantinM (2006-02-22 12:39:00) [13]Да ничего не работает, как был результат SendMessageW равен 0 так и остался.
Сергей М. (2006-02-22 12:32:00) [14]
> здесь можно как с "бараном", так и без него
Это Зависит от объявления типа рез-та ф-ции CallWndProcHook() - стоит только изменить его на "HHOOK" (что естественно. поскольку var HookHandle: HHOOK), как твое утверждение в [8] не выдерживает критики.
Сергей М. (2006-02-22 12:27:00) [15]
> KonstantinM © (22.02.06 12:07) [5]
Твой код у меня расчудесно работает.
KonstantinM (2006-02-22 12:24:00) [16]Уважаемый Cергей, здесь можно как с "бараном", так и без него - код, по крайней мере в D7, компилируется одинаковый. И работает одинаково. И с результатом SetWindowsHookExW все в порядке.
Сергей М. (2006-02-22 12:20:00) [17]
> KonstantinM © (22.02.06 12:07) [5]
Сергей М. (2006-02-22 12:14:00) [18]
> должно быть LRESULT
Вообще-то в соответствии с Windows.pas должен быть HHOOK (= Long int), а не LRESULT (= Long word) .. Ну да это не принципиально .. В целом когда речь идет о хэндлах, лучше всего указывать тип THandle - он "универсален" и в восприятии-понимании и в совместимости
> Желающим могу выслать тестовый пример
В нем, надеюсь, "баран" ( @CallWndProcHook) присутствует ?
В нем есть проверка-анализ результата вызова ф-ции SetWindowsHookExW() ?
KonstantinM (2006-02-22 12:07:00) [19]Вот, собственно и код примера. Все компилируется отлично.
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.
KonstantinM (2006-02-22 11:57:00) [20]Опечатка вышла, должно быть LRESULT.
Желающим могу выслать тестовый пример.