简体   繁体   English

EnableWindow(hWnd,false)不会禁用键盘输入

[英]EnableWindow(hWnd, false) doesn't disable keyboard input

I am attempting to disable a window under certain conditions using EnableWindow(hWnd, false); 我试图在某些情况下使用EnableWindow(hWnd, false);禁用窗口EnableWindow(hWnd, false);

According to the documentation , this should "disable mouse and keyboard input to the specified window". 根据文档 ,这应该“禁用对指定窗口的鼠标和键盘输入”。

The problem I am seeing is that it does, in fact, disable like it says, except if the cursor is currently inside of a text box in the window and the window has the focus that does not get disabled. 我所看到的问题是,实际上,它确实像它说的那样禁用,除非光标当前位于窗口中的文本框中,并且窗口具有未禁用的焦点。 I was thinking of doing some sort of code to take the focus off of the window as well. 我当时正在考虑做某种代码来将焦点从窗口移开。

Is there a better way to go about this? 有没有更好的方法来解决这个问题?

Note: The window being disabled is a binary ran via _spawnl() . 注意:禁用的窗口是通过_spawnl()进行的二进制运行。

I'm not sure if this is a Windows feature or a bug. 我不确定这是Windows功能还是bug。 Either way, disabling the foreground window is not a good idea. 无论哪种方式,禁用前景窗口都不是一个好主意。

If you are able to modify the program you start with _spawnl() then that is a better solution. 如果您能够修改程序,则以_spawnl()开始,那么这是一个更好的解决方案。 You could make it respond to WM_APP or something like that when you need to control it. 您可以在需要控制它时使其响应WM_APP或类似的响应。

If it is a 3rd-party application then you are left with hacks. 如果它是第三方应用程序,那么您将遭受黑客攻击。

You could try to change the foreground window with SetForegroundWindow but this will only work if you do it very soon after _spawnl() before your thread loses the foreground lock. 您可以尝试使用SetForegroundWindow更改前台窗口,但这仅在_spawnl()之后不久在线程丢失前台锁之前执行此操作才有效。 Using LockSetForegroundWindow before _spawnl() might be able to help you keep the lock longer. _spawnl()之前使用LockSetForegroundWindow可能可以帮助您将锁保持更长的时间。 There are also various other hacks to change the foreground with AttachThreadInput etc. 还有其他各种技巧可以通过AttachThreadInput等更改前景。

If you don't want to change the foreground I was able to come up with a workaround: 如果您不想更改前景,我可以提供一种解决方法:

  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);
  }

This is certainly not optimal, it leaves Notepad in a state where it looks like it is enabled but it is really not. 这当然不是最佳选择,它使记事本处于看起来已启用但实际上不是的状态。 The idea is to disable the focused child window and trigger a fake activation change and forcing the focus to change. 这个想法是禁用聚焦的子窗口并触发伪激活更改并强制更改焦点。 It might not work with other applications, who knows. 知道,它可能无法与其他应用程序一起使用。

If you are willing to risk a deadlock you can do this instead: 如果您愿意冒险陷入僵局,可以这样做:

    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);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM