Ну, я попробовал другое решение моей проблемы, но оно просто не работает.
Я вызываю SetWindowsHookExA, а затем, когда я нажимаю клавишу, окно сообщения не отображается. Что делать?
это мой код (это DLL, которая загружается другой DLL, загружаемой программой):
#include <Windows.h>
HINSTANCE gl_hThisInstance = NULL;
HHOOK hHook = NULL;
LRESULT CALLBACK KeyHit(int code,WPARAM wParam,LPARAM lParam);
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
gl_hThisInstance = (HINSTANCE)hModule;
hHook = SetWindowsHookExA(
WH_KEYBOARD,
KeyHit,
//(HWND)gl_hThisInstance//not working
0,//not working
//(DWORD)gl_hThisInstance//not working
//GetCurrentThreadId()//even not working with this
0//not working
);
break;
}
return TRUE;
}
LRESULT CALLBACK KeyHit(int code,WPARAM wParam,LPARAM lParam)
{
MessageBox(0,"PRESSED","PRESSED",0);
return CallNextHookEx(hHook,code,wParam,lParam);
}
У меня были проблемы с подключением раньше. На самом деле это не проблема, но то, как я это сделал, не предполагалось.
Прежде всего, вы должны иметь 2 экспортированные функции из DLL, SetHook
а также RemoveHook
, SetHook
функция будет вызывать SetWindowsHookEx()
оттуда. Если вы когда-нибудь попытаетесь позвонить SetWindowsHookEx()
изнутри или DLLMain
вашей DLL, функция не возвращает ошибок, но функция обратного вызова никогда не будет вызываться. Мне иногда приходилось это понимать.
Здесь размещен мой рабочий код, чтобы поймать WH_GETMESSAGE
Вы можете сослаться отсюда.
Вот моя рабочая экспортированная функция SetHook () из DLL.
bool __declspec(dllexport) __stdcall SetHook(DWORD myWnd)
{
mySavedHook = SetWindowsHookEx(WH_GETMESSAGE,
GetMsgProc,
infoContainer.DllHModule,
myWnd);
int errorID = GetLastError();
if (errorID != 0)
{
MessageBoxA(NULL, "Failed to implement hook", "Failed", 0);
MessageBoxA(NULL, to_string(errorID).c_str(), "Error ID", 0);
return false;
}
else
{
return true;
}
}
infoContainer.DllHModule
: экземпляр DLL, который является первым параметром DllMain()
,
myWnd:
мой идентификатор потока (не идентификатор процесса) — получить его от GetWindowThreadProcessId(window_handle, NULL)
, Чтобы реализовать глобальный хук, используйте 0 как myWnd
,
И вот моя функция обратного вызова.
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
LPMSG msg = (LPMSG)lParam;
if (msg->message == WM_CALLFUNCTION)
{
MessageBoxA(NULL, "Receive WM_CALLFUNTION", "Good news", 0);
}
}
//Doesn't matter, just call this function and return it.
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
Функция обратного вызова должна иметь CALLBACK
Ключевое слово для работы.
Из внешнего приложения позвоните SetHook()
из библиотеки DLL и используйте идентификатор потока в качестве параметра.
Других решений пока нет …