更新程序后,SetForgroundWindow()失败
SetForgroundWindow() fails after program was Updated
我写了一个图像匹配C++工具,它是一个通知区域工具(没有可见窗口)。它获得了另一个窗口的句柄并将其聚焦,然后进行了保存的图像匹配。现在这个工具正在完善,但我关注的程序的制作者(不是我写的)推送了一个更新,这对他们的程序有很大的改变。
因此,我似乎无法再设置程序的焦点(将它放在所有窗口的顶部)。我试着以管理员的身份运行,但没有成功。我可以看到任务栏中的图标闪烁橙色,这意味着它处于活动状态,但窗口不会出现在前台。
这是我的工具的隐形硬件:
hwnd = CreateWindowEx (0, className,
TEXT( "" ),
WS_OVERLAPPEDWINDOW,
0, 0,
0, 0,
NULL, NULL,
hInstance, NULL);
这是我在进行图像匹配的函数顶部的代码:
ShowWindow(handle, SW_SHOWDEFAULT); //maximize handle
SetForegroundWindow(handle); //bring to foreground
我使用SW_SHOWDEFAULT,而不是SW_SHOW和showWindow,因为这修复了我遇到的一个问题,即如果最小化该工具,它将无法匹配图像,因为窗口是隐藏的。
看起来SetForegroundWindow()在以前工作时现在返回0(fail)。我找不到有效的在线解决方案。
唯一起作用的是:
ShowWindow(handle, SW_MINIMIZE);
ShowWindow(handle, SW_SHOWDEFAULT);
这似乎可以最小化窗口并将其重新打开,从而使其聚焦,但这不是一个解决方案,因为图像匹配过程应该根据用户的意愿持续多久。
感谢您的帮助!
当SetForeground不工作时,则需要"焦点窃取"。由于其他程序可能依赖于聚焦窗口,因此被淹没。基本上,只有当前的前台窗口才能将属于另一个程序的窗口设置为前台。我相信这是在Vista中引入的。
请小心使用。
bool ForceToForeground(HWND hWnd)
{
HWND hForeground = GetForegroundWindow();
int curThread = GetCurrentThreadId();
int remoteThread = GetWindowThreadProcessId(hForeground,0);
AttachThreadInput( curThread, remoteThread, TRUE);
SetForegroundWindow(hWnd);
AttachThreadInput( curThread, remoteThread, FALSE);
return GetForegroundWindow() == hWnd;
}
让您的应用程序通过RegisterHotKey注册一个(精心选择的)热键,然后通过SendInput 模拟密钥
在处理WM_HOTKEY消息时,您应该能够"窃取焦点"。
// Register the Ctrl+5 (numpad Hot Key)
BOOL BWin32Success = RegisterHotKey( hWnd, 4242, MOD_CONTROL, VK_NUMPAD5 );
[...]
// Later, Emulate the Hot Key
std::vector<INPUT> vInputs;
INPUT OneInput;
OneInput.type = INPUT_KEYBOARD;
OneInput.ki.time = 0;
OneInput.ki.dwExtraInfo = 0;
OneInput.ki.wScan = 0;
OneInput.ki.dwFlags = 0;
OneInput.ki.wVk = VK_CONTROL;
vInputs.push_back( OneInput );
OneInput.ki.wVk = VK_NUMPAD5;
vInputs.push_back( OneInput );
OneInput.ki.dwFlags |= KEYEVENTF_KEYUP;
vInputs.push_back( OneInput );
OneInput.ki.wVk = VK_CONTROL;
vInputs.push_back( OneInput );
// Update a global HWND variable with the target hWnd
UINT Sent = SendInput( static_cast<UINT>( vInputs.size() ), &vInputs[ 0 ] );
[...]
// WM_HOTKEY Handler (message is posted)
case WM_HOTKEY: {
if ( wParam == 4242 ) {
// HERE USE THE GLOBAL "TARGET" HWND WITH APIs
}
break;
}
我最终使用了这里显示的方法:http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 生成MRPT库时cmake配置失败
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- variadic模板中的模板参数推导失败