我正在尝试使用EnableWindow(hWnd, false);
根据the documentation,这应该“禁用指定窗口的鼠标和键盘输入”。
我看到的问题是,事实上它确实像它所说的那样禁用,除非光标当前位于窗口中的文本框内,并且窗口的焦点不会被禁用。我正在考虑做一些代码来关注窗口。
有没有更好的方法来解决这个问题?
注意:被禁用的窗口是通过_spawnl()
运行的二进制文件。
答案 0 :(得分:2)
我不确定这是Windows功能还是错误。无论哪种方式,禁用前景窗口都不是一个好主意。
如果您能够以_spawnl()
开头修改程序,那么这是一个更好的解决方案。当你需要控制它时,你可以让它响应WM_APP或类似的东西。
如果是第三方应用程序,那么你就会被黑客攻击。
您可以尝试使用SetForegroundWindow
更改前景窗口,但只有在线程失去前台锁之前_spawnl()
之后很快就会执行此操作。在LockSetForegroundWindow
之前使用_spawnl()
可能会帮助您延长锁定时间。还有其他各种黑客用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, >i))
{
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, >i))
{
if (GetForegroundWindow() == hNP)
{
if (AttachThreadInput(GetCurrentThreadId(), tid, true))
{
SetFocus(NULL);
AttachThreadInput(GetCurrentThreadId(), tid, false);
}
}
EnableWindow(hNP, false);
}