c++ - EnableWindow(hWnd, false) 不禁用键盘输入

标签 c++ winapi

我试图在某些情况下使用 EnableWindow(hWnd, false);

禁用窗口

根据 the documentation ,这应该“禁用对指定窗口的鼠标和键盘输入”。

我看到的问题是它确实像它所说的那样禁用,除非光标当前位于窗口中的文本框内并且窗口具有不会被禁用的焦点。我也在考虑编写某种代码来将焦点也从窗口上移开。

有没有更好的方法来解决这个问题?

注意:被禁用的窗口是通过 _spawnl() 运行的二进制文件。

最佳答案

我不确定这是 Windows 功能还是错误。无论哪种方式,禁用前景窗口都不是一个好主意。

如果您能够修改以 _spawnl() 开头的程序,那么这是一个更好的解决方案。当你需要控制它时,你可以让它响应 WM_APP 或类似的东西。

如果它是第 3 方应用程序,那么您将面临黑客攻击。

您可以尝试使用 SetForegroundWindow 更改前景窗口,但这只有在您在线程失去前景锁定之前 _spawnl() 之后立即执行此操作时才有效。在 _spawnl() 之前使用 LockSetForegroundWindow 可能会帮助您更长时间地保持锁定。还有各种其他技巧可以用 AttachThreadInput 改变前景。等

如果您不想更改前景,我可以想出一个解决方法:

  ShellExecute(NULL, NULL, TEXT("Notepad"), NULL, NULL, SW_SHOW);
  Sleep(2000);
  HWND hNP = FindWindow(TEXT("Notepad"), NULL);
  Sleep(2000); // Start typing in Notepad now...
  if (hNP)
  {
    DWORD tid = GetWindowThreadProcessId(hNP, NULL);
    GUITHREADINFO gti;
    gti.cbSize = sizeof(gti);
    if (tid && GetGUIThreadInfo(tid, &gti))
    {
      HWND hChild = NULL;
      if (gti.hwndFocus != hNP && gti.hwndFocus)
      {
        EnableWindow(hChild = gti.hwndFocus, false);
      }
      if (GetForegroundWindow() == hNP)
      {
        SendNotifyMessage(hNP, WM_ACTIVATE, WA_INACTIVE, NULL);
        SendNotifyMessage(hNP, WM_ACTIVATE, WA_ACTIVE, NULL);
        SendNotifyMessage(hNP, WM_SETFOCUS, NULL, NULL);
        // SendNotifyMessage(hNP, WM_NCACTIVATE, false, NULL); // Uncomment to make it look like it is inactive
      }
      EnableWindow(hNP, false);
      if (hChild)
      {
        EnableWindow(hChild, true);
      }
    }
    MessageBox(NULL, TEXT("Done?"), NULL, MB_TOPMOST);
    SetForegroundWindow(hNP);
    PostMessage(hNP, WM_CLOSE, 0, 0);
  }

这当然不是最佳选择,它使记事本处于一种看起来已启用但实际上未启用的状态。这个想法是禁用获得焦点的子窗口并触发虚假的激活更改并强制更改焦点。它可能不适用于其他应用程序,谁知道呢。

如果您愿意冒死锁的风险,您可以这样做:

    DWORD tid = GetWindowThreadProcessId(hNP, NULL);
    GUITHREADINFO gti;
    gti.cbSize = sizeof(gti);
    if (tid && GetGUIThreadInfo(tid, &gti))
    {
      if (GetForegroundWindow() == hNP)
      {
        if (AttachThreadInput(GetCurrentThreadId(), tid, true))
        {
          SetFocus(NULL);
          AttachThreadInput(GetCurrentThreadId(), tid, false);
        }
      }
      EnableWindow(hNP, false);
    }

关于c++ - EnableWindow(hWnd, false) 不禁用键盘输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46780433/

相关文章:

perl - 如何在 Windows 上为 Perl 脚本的输出文本着色?

delphi - 最好的报告编写工具是什么?

c - 使用 Win32 API 安全删除 USB 驱动器?

c# - 使用serialport.open()时发生I/O异常错误

winapi - 在 C++ Win32 中的 TabControl 中将控件添加到特定选项卡页

c++ - 大小为 1 MB 的数组

c++ - 将 C++ 自定义类型公开给 QML

c++ - 不理解这些 C++ box2d 错误

c++ - 强类型语言能走多远?

c++ - 带 C++ 的 SystemC - 如何打印 sc_bigint 变量?