程序更新后,SetForegroundWindow()失败

时间:2014-02-28 11:47:18

标签: c++ windows winapi windows-7

我写了一个匹配C ++工具的图像,这是一个通知区域工具(没有可见窗口)。它得到了另一个窗口的句柄并将其聚焦,然后进行了保存的图像匹配。现在这个工具正在完善,但程序的制作者(不是我写的)我专注于推动更新,这改变了他们的程序。

因此,我似乎无法再设置程序的重点(将其置于所有窗口的顶部)。我尝试以管理员身份运行而没有运气。我可以看到任务栏中的图标闪烁橙色表示它处于活动状态,但窗口不会出现在前台。

这是我工具的隐形hwnd:

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(失败)。我找不到有效的在线解决方案。

只有有效的东西(种类)是这样的:

ShowWindow(handle, SW_MINIMIZE);
ShowWindow(handle, SW_SHOWDEFAULT);

这似乎可以最小化窗口并将其重新启动,从而使其聚焦,但这不是解决方案,因为图像匹配过程应该在用户需要的时间内继续。

感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

让您的应用程序通过RegisterHotKey注册(精心挑选的)HotKey,然后通过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;
}

答案 2 :(得分:0)