Пытаюсь отловить WM_ENTERSIZEMOVE
и WM_EXITSIZEMOVE
сообщения для окна, дескриптор которого является членом класса. Для этого использую SetWindowsHookExA
с параметром WH_GETMESSAGE
. Второй параметр функции (HOOKPROC
) указывает на функцию, внутри моего класса:
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
:
auto helper = boost::make_shared<WindowDisplayHelper>(windowHandle);
helper->SetMsgHook();
AddDisplayHelper(displayId, helper);
return true;
И хотя я и вызываю SetMsgHook
после создания объекта WindowDisplayHelper
, выглядит так, будто хук не устанавливается: m_isWindowResizing
все время == false и логов не видно этих. Т.к. обработчик хука находится внутри класса, то пришлось прибегнуть к приемам со статическим указателем на this, но что-то это не сработало. Пробовал указать id потока (результат GetCurrentThreadId
), но это тоже не помогло.
Подскажите, пожалуйста, почему не срабатывает моя функция обработки оконных сообщений?
Если я правильно понял ваш вопрос, то эта проблема обычно решается немного иначе. В частности, для хранения ссылки на экземпляр класса используется не статическое поле, а само окно.
Адрес экземпляра класса указывается при создании окна как аргумент CreateWindowEx
:
m_hwndControl = ::CreateWindowEx(WS_EX_CLIENTEDGE, MY_WINDOW_CLASS, _TEXT(""),
WS_CHILD | WS_TABSTOP | WS_VISIBLE,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
m_hwndParent, (HMENU)uID, hInstance, this);
А связывание с экземпляром класса выполняется в оконной процедуре.
// WndProc является статической функцией-членом!
LRESULT CALLBACK MyWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
// Get pointer to self
MyWindow *pSelf;
if (uMsg == WM_CREATE) {
pSelf = (MyWindow*)(((CREATESTRUCT*)lParam)->lpCreateParams);
::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pSelf);
}
else
pSelf = (MyWindow*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
// Здесь вызываются классовые функции-обработчики, например так:
// Dispatch message
switch (uMsg) {
HANDLE_MSG(hWnd, WM_CREATE, pSelf->OnCreate);
HANDLE_MSG(hWnd, WM_DESTROY, pSelf->OnDestroy);
HANDLE_MSG(hWnd, WM_ERASEBKGND, pSelf->OnEraseBkgnd);
HANDLE_MSG(hWnd, WM_PAINT, pSelf->OnPaint);
. . .
(HANDLE_MSG
- это message cracker из windowx.h. Использовать крекеры, разумеется, не обязательно.)
В таком виде все будет корректно работать и для нескольких окон.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Пытаюсь подключить свой шрифт для приложенияНо он подключается, только если я поверну экран или уйду на другую активити
Задача: В одном каталоге с jar-файлом лежит properties файл, который нужно прочитать
Имеется класс ScoreCardActivity где описана работа с библиотекой MPAndroidChart а именно работа с PieChart (круглая диаграмма) Студия подсвечивает красным такие...
я пытаюсь получить результат сканирования QR-кода во фрагменте, при использовании activity все работает, но после передачи, результат получить...