9

I am working on an Win32 C++ application where I want to ignore the mouse events and let is pass through to the window beneath my window. Basically the window below mine will handle the mouse event. I would prefer not to send the mouse message using SendMessage to the window beneath mine or use SetCapture. Is there a way basically to ignore the mouse event and let it pass through with Windows APIs or with styles? Note that my window is not transparent.

Thanks in advance for the help.

4

4 回答 4

9

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

我已经尝试了这两种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);
于 2018-05-09T04:26:11.193 回答
1

我一直在通过 2 个不同的 3rd 方使用 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;

一切都适用于其中之一。但它不适合另一个。

如果您有什么建议,我将不胜感激。

于 2012-10-26T14:28:58.793 回答
1

我会尝试处理WM_NCHITTEST并返回HTNOWHERE.

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

于 2012-10-25T16:51:09.280 回答
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 */
于 2016-11-12T16:59:59.573 回答