我正在开发一个Win32 C++应用程序,在这个应用程序中,我希望忽略鼠标事件,让它们穿透到我的窗口下面的窗口。基本上,我的下面的窗口将处理鼠标事件。我宁愿不使用SendMessage将鼠标消息发送到我的下面的窗口,也不使用SetCapture。是否有一种方法可以忽略鼠标事件,并让它们通过Windows API或样式来传递?请注意,我的窗口不是透明的。
提前感谢您的帮助。
提前感谢您的帮助。
我在尝试创建一个音乐播放器时发现了这个问题,以及其他问题。该播放器可以在屏幕上覆盖图形显示,而不影响任何其他交互,包括拖动窗口等。
我已经尝试了WM_NCHITTEST
方法和简单地向我的窗口添加WS_EX_TRANSPARENT
,但这两种方法都似乎捕获了鼠标点击事件,这是我不想要的。
然而,纯粹出于巧合,我成功地找到了一组标志,可以传递给SetWindowLong(..., GWL_EXSTYLE, ...)
,看起来能够解决问题,代码如下:
LONG cur_style = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, cur_style | WS_EX_TRANSPARENT | WS_EX_LAYERED);
看起来这种行为在此文档 这里 有说明:
分层窗口的点击测试基于窗口的形状和透明度。这意味着窗口中颜色键掉或者alpha值为零的区域将鼠标消息传递。但是,如果分层窗口具有WS_EX_TRANSPARENT扩展窗口样式,则分层窗口的形状将被忽略,并且鼠标事件将传递到分层窗口下面的其他窗口。
扩展窗口样式文档也非常有用。对于像我的应用程序一样不希望与之交互的窗口,WS_EX_NOACTIVATE
也可能很有用,因为它可以防止某些用户交互操作。
出于纪念的目的,我将注明我使用的代码以确保我的窗口始终位于顶部:
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
HTNOWHERE
。我已经使用两个不同的第三方RDC解决方案进行测试。每个解决方案可能以不同的方式创建自己的窗口,具有不同的样式等。如果我在WindowProc中执行以下操作:
case WM_MOUSEMOVE:
{
std::cout << "WM_MOUSEMOVE" << std::endl;
VideoWindowWin32* window = reinterpret_cast<VideoWindowWin32*> (GetWindowLongPtr (hWnd, GWL_USERDATA));
if (window)
{
HWND rParent = GetParent(window->window);
SetCapture(window->parent);
//SendMessage(window->parent, uMsg, wParam, lParam);
}
}
break;
其中一个可以正常工作,但另一个却不能。
如果您有任何建议,我将不胜感激。
case WM_NCHITTEST: return HTTRANSPARENT;
HTNOWHERE
导致窗口的 LoadCursor() 不再显示。
这些值似乎是可能的:
#ifndef NONCMESSAGES
/*
* WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
*/
#define HTERROR (-2)
#define HTTRANSPARENT (-1)
#define HTNOWHERE 0
#define HTCLIENT 1
#define HTCAPTION 2
#define HTSYSMENU 3
#define HTGROWBOX 4
#define HTSIZE HTGROWBOX
#define HTMENU 5
#define HTHSCROLL 6
#define HTVSCROLL 7
#define HTMINBUTTON 8
#define HTMAXBUTTON 9
#define HTLEFT 10
#define HTRIGHT 11
#define HTTOP 12
#define HTTOPLEFT 13
#define HTTOPRIGHT 14
#define HTBOTTOM 15
#define HTBOTTOMLEFT 16
#define HTBOTTOMRIGHT 17
#define HTBORDER 18
#define HTREDUCE HTMINBUTTON
#define HTZOOM HTMAXBUTTON
#define HTSIZEFIRST HTLEFT
#define HTSIZELAST HTBOTTOMRIGHT
#if(WINVER >= 0x0400)
#define HTOBJECT 19
#define HTCLOSE 20
#define HTHELP 21
#endif /* WINVER >= 0x0400 */
/*
* SendMessageTimeout values
*/
#define SMTO_NORMAL 0x0000
#define SMTO_BLOCK 0x0001
#define SMTO_ABORTIFHUNG 0x0002
#if(WINVER >= 0x0500)
#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0600)
#define SMTO_ERRORONEXIT 0x0020
#endif /* WINVER >= 0x0600 */
#if(WINVER >= 0x0602)
#endif /* WINVER >= 0x0602 */
#endif /* !NONCMESSAGES */