Global Mouse Hook (опять)
От: spazhev_dima  
Дата: 21.02.07 14:58
Оценка:
Добрый день!

// Вопрос поднимся уже, и не раз.
// Я прочитал весь форум внимательно, все статьи и посты на эту темы, MSDN тоже,
// потратил два дня на это, поэтому писать снова не стыдно

Вопрос: я хочу поставить глобальный Mouse Hook.
Что я делаю неверно?

Возможно, наводящим вопросом будет:
Хук устанавливается, но не работает.
При попытке его освободить, говорит "Неверный дескриптор обработчика"
(Это при анализе GetLastError())

Исходный код:

//---------------------------------------------------------------------------
// DLL-Ка
//---------------------------------------------------------------------------

#include <clx.h>
#include <windows.h>

#pragma data_seg(".DIMA")
HWND hWnd = NULL;
#pragma data_seg()

HHOOK hHook;
HINSTANCE hInstance;

#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
hInstance = hinstDLL;
return 1;
}
//---------------------------------------------------------------------------

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMSG FirstParam = (LPMSG)wParam;

; // processing message

return CallNextHookEx(hHook, nCode, wParam, lParam);
}
//---------------------------------------------------------------------------


extern "C" __declspec(dllexport) BOOL CALLBACK SetMyHook(HWND AWnd)
{
hWnd = AWnd;
hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC) MouseHookProc, (HINSTANCE)hInstance, NULL);

if(hHook != NULL)
{
MessageBox(0, "Hook was SET.", "OK", MB_OK);
}

return 1;
}
//---------------------------------------------------------------------------


extern "C" __declspec(dllexport) BOOL CALLBACK ClearMyHook(HWND AWnd)
{
bool Result = UnhookWindowsHookEx(hHook);

if(Result) MessageBox(0, "Hook WAS deleted.", "OK", MB_OK);

return Result;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Проект
//---------------------------------------------------------------------------


// Types
typedef BOOL (CALLBACK *TSetMyHook)(HWND);
typedef BOOL (CALLBACK *TClearMyHook)(HWND);

//---------------------------------------------------------------------------


// В public-секции описания формы

TSetMyHook SetMyHook;
TClearMyHook ClearMyHook;
HINSTANCE hDllInstance;

//---------------------------------------------------------------------------


void __fastcall TCalendarMain::FormCreate(TObject *Sender)
{
AnsiString FName = ExtractFilePath(Application->ExeName) + "prjHookDLL\\prjHookDllMain.dll";

hDllInstance = LoadLibrary(FName.c_str());
if(!hDllInstance)
{
ShowMessage("Unable to load DLL ("+FName+")");
return;
}

SetMyHook = (TSetMyHook) GetProcAddress(hDllInstance, "SetMyHook");
if(!SetMyHook) ShowMessage("Unable to load procedure 'SetMyHook'");

ClearMyHook = (TClearMyHook) GetProcAddress(hDllInstance, "ClearMyHook");
if(!ClearMyHook) ShowMessage("Unable to load procedure 'ClearMyHook'");

if(!SetMyHook || !ClearMyHook)
{
FreeLibrary(hDllInstance);
return;
}

SetMyHook(this->Handle);
}

//---------------------------------------------------------------------------

void __fastcall TCalendarMain::FormClose(TObject *Sender,
TCloseAction &Action)
{
if(ClearMyHook) ClearMyHook(this->Handle);
FreeLibrary(hDllInstance);
}
//---------------------------------------------------------------------------
Re: Global Mouse Hook (опять)
От: Lonely Dog Россия  
Дата: 21.02.07 17:04
Оценка:
Здравствуйте, spazhev_dima, Вы писали:

Правильно ли я понимаю, что сегмент данных DIMA расшарен? В таком случае, мне не понятно, почему переменная hHook не в этом сегменте?
Re[2]: Global Mouse Hook (опять)
От: spazhev_dima  
Дата: 21.02.07 20:55
Оценка:
Здравствуйте, Lonely Dog, Вы писали:

LD>Здравствуйте, spazhev_dima, Вы писали:


LD>Правильно ли я понимаю, что сегмент данных DIMA расшарен? В таком случае, мне не понятно, почему переменная hHook не в этом сегменте?


Дык потому что хук, НАСКОЛЬКО Я ПОНИМАЮ, свой для каждого приложения...
И инстанс длл-ки тоже.

А вот окно-сервер -- одно для всех
Re[3]: Global Mouse Hook (опять)
От: Andrew S Россия http://alchemy-lab.com
Дата: 22.02.07 16:22
Оценка:
LD>>Здравствуйте, spazhev_dima, Вы писали:

LD>>Правильно ли я понимаю, что сегмент данных DIMA расшарен? В таком случае, мне не понятно, почему переменная hHook не в этом сегменте?


_>Дык потому что хук, НАСКОЛЬКО Я ПОНИМАЮ, свой для каждого приложения...

_>И инстанс длл-ки тоже.

Ну так и что тогда попадает в CallNextHookEx?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Global Mouse Hook (опять)
От: Alex Fedotov США  
Дата: 22.02.07 19:18
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Ну так и что тогда попадает в CallNextHookEx?


NULL.
-- Alex Fedotov
Re[5]: Global Mouse Hook (опять)
От: Andrew S Россия http://alchemy-lab.com
Дата: 22.02.07 19:29
Оценка:
AS>>Ну так и что тогда попадает в CallNextHookEx?

AF>NULL.


Продолжим
И что в этом случае будет на 9х?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[6]: Global Mouse Hook (опять)
От: Alex Fedotov США  
Дата: 23.02.07 05:49
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>>>Ну так и что тогда попадает в CallNextHookEx?


AF>>NULL.


AS>Продолжим

AS>И что в этом случае будет на 9х?

А мне все равно. Автору вопроса, скорее всего, тоже.

Это я к тому, что замечание про HHOOK конечно же верное, но оно не отвечает на вопросы автора.
-- Alex Fedotov
Re[7]: Global Mouse Hook (опять)
От: spazhev_dima  
Дата: 23.02.07 10:06
Оценка:
Это все очень мило, правда...
Но хотелось бы ответа. А не ребусы.

К стати, по существу вопроса, в моем случае неважно, что попадает в процедуру CallNextHookEx,
потому что при отладке видно, что вообще в процедуру обработки хука (мою) управление не передается вообще никогда.

Хотя хук ставится (при его установке {Set..Ex} возвращается указатель на него, в GetLastError тишина...)

Вот... Что, никто не хочет помочь?

// Флуд: я сам сильно удивлен, что не работает. уже все перепробовал. ужас какой-то.
Re[8]: Global Mouse Hook (опять)
От: Alex Fedotov США  
Дата: 23.02.07 11:20
Оценка:
Здравствуйте, spazhev_dima, Вы писали:

_>К стати, по существу вопроса, в моем случае неважно, что попадает в процедуру CallNextHookEx,

_>потому что при отладке видно, что вообще в процедуру обработки хука (мою) управление не передается вообще никогда.

Возможно, что ваша DLL не может быть загружена в другие процессы, поскольку зависит от других DLL, которых нет в стандартных каталогах, где ищет система (PATH, system32, и так далее). Список DLL, от которых зависит ваша DLL вы легко можете получить с помощью утилиты depends.exe из Platform SDK.
-- Alex Fedotov
Re[7]: Global Mouse Hook (опять)
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.02.07 11:30
Оценка:
AS>>>>Ну так и что тогда попадает в CallNextHookEx?

AF>>>NULL.


AS>>Продолжим

AS>>И что в этом случае будет на 9х?

AF>А мне все равно. Автору вопроса, скорее всего, тоже.


AF>Это я к тому, что замечание про HHOOK конечно же верное, но оно не отвечает на вопросы автора.


Частично — отвечает. Все складывается из мелочей. Например, кто там видет, что сегмент разделяемый? А ведь автора уже спрашивали об этом.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[8]: Global Mouse Hook (опять)
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.02.07 11:38
Оценка:
_>Это все очень мило, правда...
_>Но хотелось бы ответа. А не ребусы.

Да уж. Видимо, Сократ для вас не авторитет

_>К стати, по существу вопроса, в моем случае неважно, что попадает в процедуру CallNextHookEx,

_>потому что при отладке видно, что вообще в процедуру обработки хука (мою) управление не передается вообще никогда.

При отладке? А каким же способом вы отлаживаете? Вызовов Trace или OutputDebugString у вас в коде я не обнаружил.

_>Хотя хук ставится (при его установке {Set..Ex} возвращается указатель на него, в GetLastError тишина...)


_>Вот... Что, никто не хочет помочь?


В первую очередь, должны хотеть помочь себе вы. Для этого надо прочитать имеющиеся на сайте статьи и сделать соответствующие выводы. Пока что я вижу только удивленные восклицания, а не желание разобраться самостоятельно.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Global Mouse Hook (опять)
От: spazhev_dima  
Дата: 28.02.07 12:47
Оценка:
Здравствуйте, Alex Fedotov, Вы писали:

AF>Возможно, что ваша DLL не может быть загружена в другие процессы, поскольку зависит от других DLL, которых нет в стандартных каталогах, где ищет система (PATH, system32, и так далее). Список DLL, от которых зависит ваша DLL вы легко можете получить с помощью утилиты depends.exe из Platform SDK.


Проверил. Не зависит.
Переписал ее полностью на С, без использовании вообще чего-то Билдерововского.

Работать не стало

Немного измененный код: (C-style)

//---------------------------------------------------------------------------

#include <windows.h>

#pragma data_seg(".JOE")
HWND hWnd = NULL;
#pragma data_seg()

HHOOK hHook;
HINSTANCE hInstance;


#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
hInstance = hinstDLL;
return 1;
}
//---------------------------------------------------------------------------


extern __declspec(dllexport) LRESULT CALLBACK _stdcall MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMSG FirstParam = (LPMSG)wParam;

if(FirstParam->wParam == MK_LBUTTON)
{
LPMSG SecondParam = (LPMSG)lParam;
int x = SecondParam->pt.x;
int y = SecondParam->pt.y;

::MessageBox(0, "test", "OK", MB_OK);
}
return ::CallNextHookEx(hHook, nCode, wParam, lParam);
}
//---------------------------------------------------------------------------

extern __declspec(dllexport) BOOL CALLBACK SetMyHook(HWND AWnd)
{
hWnd = AWnd;
hHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC) MouseHookProc, (HINSTANCE)hInstance, NULL);

if(hHook != NULL)
{
::MessageBox(0, "Hook was SET.", "OK", MB_OK);
} else
{
switch(::GetLastError())
{
case ERROR_INVALID_HOOK_FILTER: ::MessageBox(0, "ERROR_INVALID_HOOK_FILTER", "OK", MB_OK); break;
case ERROR_HOOK_NEEDS_HMOD: ::MessageBox(0, "ERROR_HOOK_NEEDS_HMOD", "OK", MB_OK); break;
case ERROR_GLOBAL_ONLY_HOOK: ::MessageBox(0, "ERROR_GLOBAL_ONLY_HOOK", "OK", MB_OK); break;
case ERROR_INVALID_PARAMETER: ::MessageBox(0, "ERROR_INVALID_PARAMETER", "OK", MB_OK); break;
case ERROR_JOURNAL_HOOK_SET: ::MessageBox(0, "ERROR_JOURNAL_HOOK_SET", "OK", MB_OK); break;
default: ::MessageBox(0, "UNKNOWN error", "OK", MB_OK); break;
}
}

return 1;
}
//---------------------------------------------------------------------------


extern __declspec(dllexport) BOOL CALLBACK ClearMyHook(HWND AWnd)
{
int Result = ::UnhookWindowsHookEx(hHook);

if(Result) ::MessageBox(0, "Hook WAS deleted.", "OK", MB_OK);
else
{
LPVOID lpMsgBuf;
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
::MessageBox(0, (char *)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
::LocalFree( lpMsgBuf );
}

return Result;
}
//---------------------------------------------------------------------------
Re[10]: Global Mouse Hook (опять)
От: Andrew S Россия http://alchemy-lab.com
Дата: 28.02.07 12:52
Оценка:
AF>>Возможно, что ваша DLL не может быть загружена в другие процессы, поскольку зависит от других DLL, которых нет в стандартных каталогах, где ищет система (PATH, system32, и так далее). Список DLL, от которых зависит ваша DLL вы легко можете получить с помощью утилиты depends.exe из Platform SDK.

_>Проверил. Не зависит.

_>Переписал ее полностью на С, без использовании вообще чего-то Билдерововского.

_>Работать не стало


Вы читаете, что вам тут пишут? Посмотрите статью http://www.rsdn.ru/article/baseserv/hookdll.xml
Автор(ы): Dr. Joseph M. Newcomer
Дата: 25.04.2001
Статья посвящена реализации глобальных хуков. В ней рассматриваются типичные проблемы, связанные
с различием виртуальных адресов перехватывающей DLL в адресных пространствах различных процессов, описывается
способ создания разделяемого сегмента данных, приводится пример DLL, реализующей глобальный хук.

и обратите внимание на то, каким образом сегмент делают _разделяемым_. Надо _явно_ указать это линкеру.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Global Mouse Hook (опять)
От: Аноним  
Дата: 28.02.07 12:59
Оценка:
_>>потому что при отладке видно, что вообще в процедуру обработки хука (мою) управление не передается вообще никогда.
AS>При отладке? А каким же способом вы отлаживаете? Вызовов Trace или OutputDebugString у вас в коде я не обнаружил.

Отлаживать dll'ки можно в среде VC++, например. Это не есть проблема.

AS>В первую очередь, должны хотеть помочь себе вы. Для этого надо прочитать имеющиеся на сайте статьи и сделать соответствующие выводы. Пока что я вижу только удивленные восклицания, а не желание разобраться самостоятельно.


Согласен. Похоже на тролля, кстати.
Re[10]: Global Mouse Hook (опять)
От: Andrew S Россия http://alchemy-lab.com
Дата: 28.02.07 13:25
Оценка:
_>>>потому что при отладке видно, что вообще в процедуру обработки хука (мою) управление не передается вообще никогда.
AS>>При отладке? А каким же способом вы отлаживаете? Вызовов Trace или OutputDebugString у вас в коде я не обнаружил.

А>Отлаживать dll'ки можно в среде VC++, например. Это не есть проблема.


Которые загружены непонятно в какой процесс? Интересный вариант

AS>>В первую очередь, должны хотеть помочь себе вы. Для этого надо прочитать имеющиеся на сайте статьи и сделать соответствующие выводы. Пока что я вижу только удивленные восклицания, а не желание разобраться самостоятельно.


А>Согласен. Похоже на тролля, кстати.


Ага.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[11]: Global Mouse Hook (опять)
От: Аноним  
Дата: 28.02.07 13:47
Оценка:
А>>Отлаживать dll'ки можно в среде VC++, например. Это не есть проблема.
AS>Которые загружены непонятно в какой процесс? Интересный вариант

Почему же "непонятно в какой"? В качестве Executable for debug session прописываешь приложение, которое в любом случае подцепит dll'ку и вперёд. А можно и к уже существующему процессу приаттачиться. Уж сколько раз так делал, не вижу проблемы. Главное, не забыть бряки где надо расставить.
Re[9]: Global Mouse Hook (опять)
От: spazhev_dima  
Дата: 01.03.07 06:48
Оценка:
AF>Возможно, что ваша DLL не может быть загружена в другие процессы, поскольку зависит от других DLL, которых нет в стандартных каталогах, где ищет система (PATH, system32, и так далее).

Проверил. Не зависит.
Но все равно спасибо за...
Re[8]: Global Mouse Hook (опять)
От: spazhev_dima  
Дата: 01.03.07 06:52
Оценка:
AS>Все складывается из мелочей. Например, кто там видет, что сегмент разделяемый? А ведь автора уже спрашивали об этом.

Похоже, ошибка как раз в разделяемом сегменте. Я их не делал никогда, код взял из примера. Я же под Билдером работаю... А примерчек, кохоже, с Visual Studio:

#pragma data_seg(".DIMA")
HWND hWnd = NULL;
HHOOK hHOOK = NULL;
#pragma data_seg()

В общем, надо изучить, как делаются разделяемые сегменты данных в Builder 6.
Re[9]: Global Mouse Hook (опять)
От: Alex Fedotov США  
Дата: 01.03.07 06:55
Оценка: +1
Здравствуйте, spazhev_dima, Вы писали:

_>Похоже, ошибка как раз в разделяемом сегменте. Я их не делал никогда, код взял из примера. Я же под Билдером работаю... А примерчек, кохоже, с Visual Studio:


_>#pragma data_seg(".DIMA")

_>HWND hWnd = NULL;
_>HHOOK hHOOK = NULL;
_>#pragma data_seg()

_>В общем, надо изучить, как делаются разделяемые сегменты данных в Builder 6


http://www.rsdn.ru/Forum/Message.aspx?mid=14199&amp;only=1
Автор: Alex Fedotov
Дата: 25.11.01

.
-- Alex Fedotov
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.