如何使用 Win32 API 阻止来自透明窗口的鼠标输入?

叶片

我在一个不属于我创建的程序的进程中有一个主窗口。我正在使用 aWindows Hook将一个 DLL 注入这个进程,目的是向这个主窗口添加一个子窗口。

我的最终目标是创建一个WS_EX_LAYERED窗口,允许我创建内部彩色边框,但允许中心部分透明并允许鼠标​​点击。这部分工作完美。

WNDCLASS wndClass = {};
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = OverlayProc;
wndClass.hInstance = g_TargetInstance;
wndClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 255, 255));
wndClass.lpszClassName = "OVERLAY";

RegisterClass(&wndClass);
g_Window = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, "OVERLAY", nullptr,
    WS_CHILDWINDOW, rect.left, rect.top, rect.right+1, rect.bottom+1, data->hwnd, nullptr, g_TargetInstance, nullptr);

SetLayeredWindowAttributes(g_Window, RGB(0, 255, 255), 0, LWA_COLORKEY);

ShowWindow(g_Window, SW_SHOW);
UpdateWindow(g_Window);

第二部分是我想有条件地阻止所有鼠标输入到父窗口。我无法使用WS_EX_LAYERED窗口的透明部分执行此操作,因此我尝试创建第二个透明STATIC控件作为主窗口的子窗口,但这也不会阻止鼠标输入。

我还通过调用PostMessage、传递WM_LBUTTONDOWN将模拟鼠标点击发送到父窗口WM_LBUTTONUP如何通过透明窗口阻止所有鼠标输入到父窗口?

叶片

使用在同级控件上绘制的简单透明窗口似乎无法做到这一点。我最终做的是在进程中SetWindowHookEx添加一个WH_GETMESSAGE钩子,我用来替换主窗口的 WndProc 函数并拦截鼠标消息。我用wParam参数中的特定值标记我的模拟鼠标消息,因此 proc 现在将模拟它并删除该值,将其传递给父窗口。

如果它没有在点击消息中检测到我的“标签”值,它将吞下鼠标消息,而不是将它传递给原始的 WndProc 函数。

注入的 WndProc 替换

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    switch (uMsg)
    {
        case WM_LBUTTONDOWN:
            wParam -= 11141008;
            if (wParam != MK_LBUTTON && !g_Paused)
                return 0;
            break;

        case WM_LBUTTONUP:
            wParam -= 11141008;
            if (wParam != 0 && !g_Paused)
                return 0;
            break;

        case WM_MOUSEHOVER:
        case WM_MOUSEMOVE:
            if (!g_Paused)
                return 0;
    }

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

来自 Windows Hook 函数的片段

//...
switch (data->message)
{
    case (WM_USER + 1):
    {
        g_Paused = FALSE;
        //...
        SetWindowSubclass(data->hwnd, WndProc, 1, 0);
        break;
    }

    case (WM_USER + 2):
    {
        RemoveWindowSubclass(data->hwnd, WndProc, 1);
        //...
        break;
    }
}
//...

窗口挂钩函数内的代码用于对主进程窗口进行子类化并注入我自己的 WndProc 函数,该函数又以我想要的方式处理鼠标输入。

这是用于“模拟”鼠标点击而无需在窗口中进行物理点击的代码。请注意添加的值,wParam以将此次点击标识为模拟的而不是由用户生成的。

void Window::LeftClick(DWORD x, DWORD y, DWORD delayMillis)
{
    LPARAM lparam = MAKELPARAM(x, y);

    lock_guard<mutex> lock(this->m_ClickMutex);

    PostMessage(this->m_Window, WM_LBUTTONDOWN, 11141008 + MK_LBUTTON, lparam);
    this_thread::sleep_for(std::chrono::milliseconds(delayMillis));
    PostMessage(this->m_Window, WM_LBUTTONUP, 11141008, lparam);
}

另外,对于评论中嘲笑我选择这个词的人simulated以及使用PostMessage模拟键盘输入的额外批评,这是我的键盘输入测试方法,它(出于我的目的)完美无缺且非常可靠

void GameWindow::KeyPress(UINT vkCode) const
{
    UINT scanCode = MapVirtualKey(vkCode, MAPVK_VK_TO_VSC);
    LPARAM lparam1 = MAKELPARAM(1, scanCode);
    LPARAM lparam2 = MAKELPARAM(1, 0xC000 | scanCode);

    PostMessage(this->m_Window, WM_KEYDOWN, vkCode, lparam1);
    this_thread::sleep_for(chrono::milliseconds(25));
    PostMessage(this->m_Window, WM_KEYUP, vkCode, lparam2);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何禁用按钮-Win32 API

来自分类Dev

GetGuiResources WIn32 API使用

来自分类Dev

GetGuiResources WIn32 API使用

来自分类Dev

WIN32 API中WM_MOUSEHOVER上的POPUP窗口-如何关闭它?

来自分类Dev

WIN32 API中WM_MOUSEHOVER上的POPUP窗口-如何关闭它?

来自分类Dev

有什么办法使用win32 api通过其标题获取窗口句柄?

来自分类Dev

Windows:如何拦截Win32磁盘I / O API

来自分类Dev

如何为Win32 API声明变量?

来自分类Dev

如何清除Win32 API中的屏幕

来自分类Dev

在Python中使用WIN32 API CreateProcessAsUser

来自分类Dev

使用C ++ Win32 API启用视觉样式吗?

来自分类Dev

使用Win32 API绘制笛卡尔系统

来自分类Dev

PRINTER_INFO_6无法使用WIn32 API

来自分类Dev

Win32 API-如何检查指定的句柄是否是窗口?(并且不是窗口内的控件)

来自分类Dev

如何在PowerShell环境中使用Win32 API FindWindow()在Windows 8.1 Update 2 OS中查找桌面窗口(按窗口名称)?

来自分类Dev

如何使用Win32 API获取任何线程的堆栈大小和堆栈限制

来自分类Dev

如何使用WIN32 API for C ++更改文本的颜色和大小?

来自分类Dev

C ++如何使用Win32 API通过线程从文本框中获取文本

来自分类Dev

如何使用Win32 API获取任何线程的堆栈大小和堆栈限制

来自分类Dev

如何使用Win32 API从INI文件中删除部分?

来自分类Dev

如何使用Win32在Windows中创建窗口焦点侦听器

来自分类Dev

Win32 API:如何读取序列,如果不是数据,如何在超时内退出

来自分类Dev

C ++ Win32 API GDI:矩形抗锯齿在透明背景下无法正常工作

来自分类Dev

使用Win32 API时,要使用哪些数据类型?

来自分类Dev

使用Win32 API使用Windows属性存储(元数据)创建文件

来自分类Dev

Win32 API:打开对话框窗口后,应用程序冻结

来自分类Dev

Win32 API:如何在Edit控件中捕获转义键?

来自分类Dev

如何仅通过Win32 API实现.NET Process.Exited事件

来自分类Dev

如何从MFC应用程序调用函数的Win32 API版本?

Related 相关文章

  1. 1

    如何禁用按钮-Win32 API

  2. 2

    GetGuiResources WIn32 API使用

  3. 3

    GetGuiResources WIn32 API使用

  4. 4

    WIN32 API中WM_MOUSEHOVER上的POPUP窗口-如何关闭它?

  5. 5

    WIN32 API中WM_MOUSEHOVER上的POPUP窗口-如何关闭它?

  6. 6

    有什么办法使用win32 api通过其标题获取窗口句柄?

  7. 7

    Windows:如何拦截Win32磁盘I / O API

  8. 8

    如何为Win32 API声明变量?

  9. 9

    如何清除Win32 API中的屏幕

  10. 10

    在Python中使用WIN32 API CreateProcessAsUser

  11. 11

    使用C ++ Win32 API启用视觉样式吗?

  12. 12

    使用Win32 API绘制笛卡尔系统

  13. 13

    PRINTER_INFO_6无法使用WIn32 API

  14. 14

    Win32 API-如何检查指定的句柄是否是窗口?(并且不是窗口内的控件)

  15. 15

    如何在PowerShell环境中使用Win32 API FindWindow()在Windows 8.1 Update 2 OS中查找桌面窗口(按窗口名称)?

  16. 16

    如何使用Win32 API获取任何线程的堆栈大小和堆栈限制

  17. 17

    如何使用WIN32 API for C ++更改文本的颜色和大小?

  18. 18

    C ++如何使用Win32 API通过线程从文本框中获取文本

  19. 19

    如何使用Win32 API获取任何线程的堆栈大小和堆栈限制

  20. 20

    如何使用Win32 API从INI文件中删除部分?

  21. 21

    如何使用Win32在Windows中创建窗口焦点侦听器

  22. 22

    Win32 API:如何读取序列,如果不是数据,如何在超时内退出

  23. 23

    C ++ Win32 API GDI:矩形抗锯齿在透明背景下无法正常工作

  24. 24

    使用Win32 API时,要使用哪些数据类型?

  25. 25

    使用Win32 API使用Windows属性存储(元数据)创建文件

  26. 26

    Win32 API:打开对话框窗口后,应用程序冻结

  27. 27

    Win32 API:如何在Edit控件中捕获转义键?

  28. 28

    如何仅通过Win32 API实现.NET Process.Exited事件

  29. 29

    如何从MFC应用程序调用函数的Win32 API版本?

热门标签

归档