窗口监听鼠标事件钩子
可以判断鼠标在xx事件类型下,不在某个窗口范围内,可以隐藏,或者在xx范围内,可以执行某些行为
其实感觉可以不用钩子,用qt的事件循环也可以的,能不用尽量不用吧
代码示例
可以在控件的showEvent中
#ifdef Q_OS_WIN
TestCyMouseHook::hook();
#endif
可以在控件的hideEvent中
#ifdef Q_OS_WIN
TestCyMouseHook::unHook();
#endif
对应的wrapper 鼠标钩子类
#ifndef Q_OS_UNIX
class TestCyMouseHook
{
public:
static bool hook();
static bool unHook();
private:
static LRESULT CALLBACK HookMouseProc(
int code, WPARAM wparam, LPARAM lparam);
static HHOOK s_preMouseHook;
static int s_nHookCount;
};
#endif
cpp
#ifndef Q_OS_UNIX
HHOOK TestCyMouseHook::s_preMouseHook;
int TestCyMouseHook::s_nHookCount;
bool TestCyMouseHook::hook()
{
if (s_nHookCount < 0)
{
return false;
}
if (s_preMouseHook == NULL && s_nHookCount == 0)
{
s_preMouseHook = ::SetWindowsHookEx(WH_MOUSE_LL,
&TestCyMouseHook::HookMouseProc,
GetModuleHandle(NULL), 0);
}
++s_nHookCount;
return true;
}
bool TestCyMouseHook::unHook()
{
if (s_nHookCount <= 0)
{
return false;
}
--s_nHookCount;
if (s_preMouseHook != NULL && s_nHookCount == 0)
{
::UnhookWindowsHookEx(s_preMouseHook);
s_preMouseHook = NULL;
}
return true;
}
LRESULT CALLBACK TestCyMouseHook::HookMouseProc(
int code, WPARAM wparam, LPARAM lparam)
{
if (TestMgr::instance())
{
TestMgr::instance()->onHookeMouseMsg(code, wparam, lparam);
}
return CallNextHookEx(s_preMouseHook, code, wparam, lparam);
}
#endif
TestMgr::onHookedMouseMsg是针对鼠标钩子事件的真正实现
void onHookeMouseMsg(int code, WPARAM wparam, LPARAM lparam);
void onHookeMouseMsg(int code, WPARAM wparam, LPARAM lparam)
{
#ifdef Q_OS_WIN
switch (wparam)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN:
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
case WM_NCXBUTTONDOWN:
{
QPoint pt = QCursor::pos();
if (subWidget->frameGeometry().contains(pt))
{
return;
}
if (!frameGeometry().contains(pt))
{
close();
}
}
break;
}
#endif
}