Хуки в Win32 (народ помогите!!!)
Посмеотрел разные исходники и везде всё по разному. Как правильно не как не пойму.
Проблема:
Cделал DLL в которой фильтрующая функция к примеру для хука WH_MOUSE выглядет след. образом:
LRESULT CALLBACK MouseFunc(int nCode, WPARAM wParam, LPARAM lParam)
{
MessageBox(0,"Yes","Dll",MB_OK);
if (nCode == HC_ACTION)
{
if (wParam == WM_RBUTTONDOWN)
Beep(500, 200);
}
return nCode < 0 ? CallNextHookEx (hMouseHook, nCode, wParam, lParam) : -1;
}
//Пример взял с рабочего исходника
Параметр hMouseHook устанавоивается при помощи функции (в .h файле для неё поставил extern "C"):
void WINAPI InstallMouseFunc(HHOOK hHook)
{
hMouseHook = hHook;
}
которую я вызываю в главном приложении через
указатель определённый так:
typedef void (WINAPI *pInstallMouseFunc)(HHOOK hHook);
pInstallMouseFunc pfInstallMouseFunc;
Сам вызов писать не буду.
Перед вызовом вышеописанной функции вызвал:
//хук ставлю с системной областью видимости
hhkKbdHook = SetWindowsHookEx(параметры...)
hhkKbdHook-- вернула NULL, значит произошел error
Решил проверить на ошибки:
Так вот GetLastError()
и получил ---ERROR_INVALID_FILTER_PROC
т.е. типа Неверная фильтрующая функция.
Долго я ещё извращался над своей Dll ---
и __declspec(dllexport) юзал для функций,
и в def файле в EXPORTS-х прописывал фильтрующие функции(но тогда ошибки при линковании выдавались), и #pragma заюзал для соответствующих данных. Короче упарился я чего-то.
Люди подскажите пожалуйста как правильно сделать или хотя бы где ещё инфу по этому делу достать.
Ну так покажи с какими параметрами ты ее вызываешь!
Цитата:
On 2002-03-27 0549, Fantasist wrote
Ну так покажи с какими параметрами ты ее вызываешь!
Функцию InstallMouseFunc( ) я вызываю с хэндлом хука, полученного от SetWindowsHookEx
Если ты про эту функцию говоришь.
Проект HookDLL
//---- .cpp ---//
#include "stdafx.h"
HWND Parent=0;
HHOOK HookHandle;
LRESULT WINAPI HookProc(int code,WPARAM wParam,LPARAM lParam)
{
MessageBox(Parent,"Hook","Hook",MB_OK);
return CallNextHookEx(HookHandle,code,wParam,lParam);
};
int __stdcall SetHook(int HookType, HWND AParent)
{
Parent=AParent;
HookHandle=SetWindowsHookEx(HookType,HookProc,0,0);
return (int)HookHandle;
}
void __stdcall RemoveHook()
{
UnhookWindowsHookEx(HookHandle);
};
//------ .def -------//
; HookDLL.def : Declares the module parameters.
LIBRARY "HookDLL.DLL"
EXPORTS
SetHook @1
RemoveHook @2
HookProc @3
Потом в другом приложениии:
HMODULE _Mod;
void CTestAppDlg::OnButton1()
{
FARPROC SetHook;
_Mod=LoadLibrary("HookDLL.dll");
SetHook=GetProcAddress(_Mod,"SetHook");
if (SetHook!=0)
((int (__stdcall *)(int,HWND))SetHook)(WH_KEYBOARD,m_hWnd);
}
void CTestAppDlg::OnButton2()
{
FARPROC RemoveHook=GetProcAddress(_Mod,"RemoveHook");
if (RemoveHook!=0)
RemoveHook();
FreeLibrary(_Mod);
}
Можно, конечно, экспортировать и статически.
Только будь осторожен, вот так:
HookHandle=SetWindowsHookEx(HookType,HookProc,0,0);
на самом деле делать нельзя, последние два параметра одновременно 0 не должны равняться. Если ты ставишь глобальную ловушку, то должно быть так:
HookHandle=SetWindowsHookEx(HookType,HookProc,<HInstance модуля(этой dll)>,0);
если на поток то:
HookHandle=SetWindowsHookEx(HookType,HookProc,0,<ThreadID>);
В принципе в большинстве случаев будет работать и ...0, 0) но с глюками (недопустимая операция).
Да, в принципе можно это делать и без .dll а внутри твоего проекта. Есть с этим ограничения, как ты знаешь, но зато ничего больше не нужно.