Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с SetWindowsHookEx(WH_CallWndProc,...) [D7, WinXP]


Страницы:   1 2

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.
Желающим могу выслать тестовый пример.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо