让鼠标通过Windows C ++

时间:2012-10-25 13:29:46

标签: winapi mouse gdi pass-through

我正在开发一个Win32 C ++应用程序,我想忽略鼠标事件,让它传递到窗口下面的窗口。基本上我下面的窗口将处理鼠标事件。我不想使用SendMessage将鼠标消息发送到我下面的窗口或使用SetCapture。有没有办法基本上忽略鼠标事件,让它通过Windows API或样式传递?请注意,我的窗口不透明。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

所以我在尝试创建一个音乐播放器时发现了这个问题和其他问题,该音乐播放器覆盖屏幕上的图形显示而不影响任何其他交互,包括例如拖动窗户。

我尝试了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);

似乎记录了此行为here

  

分层窗口的命中测试基于窗口的形状和透明度。这意味着窗口中的颜色键区域或其alpha值为零的区域将允许鼠标消息通过。但是,如果分层窗口具有WS_EX_TRANSPARENT扩展窗口样式,则将忽略分层窗口的形状,并将鼠标事件传递到分层窗口下的其他窗口。

extended window style documentation也很有用。对于像我这样的应用程序,如果窗口不打算与之交互,WS_EX_NOACTIVATE也可能有用,因为它会阻止某些用户交互。

为了后人的缘故,我会注意到我用来确保我的窗口始终位于顶部的代码如下:

SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

答案 1 :(得分:1)

我会尝试处理WM_NCHITTEST并返回HTNOWHERE

我相信使用WS_EX_TRANSPARENT的方法会产生其他副作用,并且仅在底层窗口由同一个线程拥有时才有用。从问题来看,目前尚不清楚底层窗口是否属于同一个应用程序或下面的任何旧应用程序。

答案 2 :(得分:1)

我已经使用2个不同的第三方对2种不同的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;

一切都适用于其中一个。但它不适合其他人。

如果您有任何建议,我将不胜感激。

答案 3 :(得分:0)

基于Adrian McCarthy,但实际上对我有用(虽然只有当父母拥有子窗口时,否则窗口会再次抓住鼠标):

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 */