Крюк WH_GETMESSAGE сообщение

87
10

Я пытаюсь подключить WH_GETMESSAGE из моего класса, чтобы определить момент изменения размера конкретного окна. Тем не менее, похоже, что крючок не установлен.

Класс, откуда я пытаюсь подключить:

class WindowDisplayHelper : // public ...
{
public:
// some other public methods here
void SetMsgHook();
protected:
LRESULT CALLBACK GetMsgProcHook(int code, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK MsgPoc(int code, WPARAM wParam, LPARAM lParam);
private:
// some other private members there
HWND m_windowHandle;
bool m_isWindowResizing = false;
static HHOOK m_msgHook;
static WindowsDisplayHelperMasterWindow* m_pThis;
};

Файл .cpp:

WindowDisplayHelper* WindowDisplayHelper ::m_pThis = nullptr;
HHOOK WindowDisplayHelper ::m_msgHook = NULL;

void WindowDisplayHelper ::SetMsgHook()
{
m_pThis = this;
m_msgHook = SetWindowsHookEx(WH_GETMESSAGE, MsgPoc, NULL, 0);
}

LRESULT CALLBACK WindowDisplayHelper::MsgPoc(int code, WPARAM wParam, LPARAM lParam)
{
if (m_pThis != nullptr)
{
return m_pThis->GetMsgProcHook(code, wParam, lParam);
}
return CallNextHookEx(0, code, wParam, lParam);
}

LRESULT CALLBACK WindowDisplayHelper::GetMsgProcHook(int code, WPARAM wParam, LPARAM lParam)
{
DUMPER_INFO("Hooked");
if (code < 0)
{
return CallNextHookEx(0, code, wParam, lParam);
}
MSG* lpmsg = (MSG*)lParam;
DUMPER_INFO("Hooked for HWND: %p. Current window %p", lpmsg->hwnd, m_windowHandle);
if (lpmsg->hwnd != m_windowHandle)
{
return CallNextHookEx(0, code, wParam, lParam);
}
if (lpmsg->message == WM_ENTERSIZEMOVE && !m_isWindowResizing)
{
DUMPER_INFO("Start window resizing");
m_isWindowResizing = true;
}
else if (lpmsg->message == WM_EXITSIZEMOVE && m_isWindowResizing)
{
DUMPER_INFO("Stop window resizing");
m_isWindowResizing = false;
}

return CallNextHookEx(0, code, wParam, lParam);
}

Вот как я создаю объект WindowDisplayHelper:

bool DisplayManager::CreateWindowDisplay(TDisplayId displayId, void * windowHandle)
{
auto helper = boost::make_shared<WindowDisplayHelper>(windowHandle);
helper->SetMsgHook();
AddDisplayHelper(displayId, helper);

return true;
}

Хотя я вызываю SetMsgHook() после создания объекта, похоже, что ловушка не установлена, потому что я не вижу никаких отладочных выходов в моем файле журнала и переменная m_isWindowResizing всегда == false. Итак, вопрос в том, почему мой крючок не работает? Благодарю.

спросил(а) 2021-01-19T16:38:26+03:00 2 месяца, 3 недели назад
1
Решение
123

m_msgHook = SetWindowsHookEx(WH_GETMESSAGE, MsgPoc, NULL, 0);

Эта строка выдает системную ошибку ERROR_HOOK_NEEDS_HMOD (1428). Это означает, что невозможно установить нелокальный хук без дескриптора модуля. Если вы установите параметр dwThreadId в ноль, процедура подключения будет связана со всеми существующими потоками, работающими на том же рабочем столе, что и вызывающий поток. Это не загружаемый хук, вам нужно указать правильный параметр hmod. Вам нужно поместить код подключения в DLL, как указывал @Remy Lebeau.

Или установите действительный параметр dwThreadId используя GetCurrentThreadId(), как указано @rudolfninja.

Я тестирую на основе шаблона приложения для рабочего стола Windows со следующим кодом. Оно работает. Вы можете попробовать.

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
// ...

HHOOK m_msgHook = SetWindowsHookEx(WH_GETMESSAGE, MsgPoc, NULL, GetCurrentThreadId());
DWORD errCode = GetLastError();

MSG msg;

// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int) msg.wParam;
}

LRESULT CALLBACK MsgPoc(int code, WPARAM wParam, LPARAM lParam)
{
OutputDebugString(L"Hooked");
if (code < 0)
{
return CallNextHookEx(0, code, wParam, lParam);
}
MSG* lpmsg = (MSG*)lParam;
//OutputDebugString("Hooked for HWND: %p. Current window %p", lpmsg->hwnd, m_windowHandle);
if (lpmsg->hwnd != m_windowHandle)
{
return CallNextHookEx(0, code, wParam, lParam);
}
if (lpmsg->message == WM_ENTERSIZEMOVE && !m_isWindowResizing)
{
OutputDebugString(L"Start window resizing");
m_isWindowResizing = true;
}
else if (lpmsg->message == WM_EXITSIZEMOVE && m_isWindowResizing)
{
OutputDebugString(L"Stop window resizing");
m_isWindowResizing = false;
}

return CallNextHookEx(0, code, wParam, lParam);
}

ответил(а) 2021-01-19T16:38:26+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема