2014-02-28 77 views
1

我寫了一個匹配C++工具的圖像,它是一個通知區域工具(不可見窗口)。它獲得了另一個窗口的句柄並將其聚焦,然後完成了它保存的圖像匹配。現在這個工具正在完善,但是這個程序的製作者(不是我寫的)我把重點放在了更新上,這個更新改變了他們的程序。程序更新後SetForgroundWindow()失敗

因此,我似乎無法設置程序的重點(把它帶到所有窗口的頂部)。我試圖以管理員身份運行,但沒有運氣。我可以看到任務欄中的圖標閃爍橙色表示其活動,但窗口不會到達前景。

這是我爲我的工具無形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); 

這似乎將窗口最小化,並把它帶回來了,導致其集中但這不是一個解決方案作爲圖像匹配過程中應只要用戶想要,就繼續下去。

任何幫助表示讚賞!

+0

什麼價值由歸國'GetLastError函數()''時失敗SetForegroundWindow'?你有沒有讀過http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539.aspx中的'Remarks'? – manuell

+0

我似乎無法從GetLastError()獲取任何內容,但SetForegroundWindow的返回肯定是0(失敗)。我已經看過評論,不知道我是否會失敗。 'Windows閃爍任務欄'是我所暗示的我不符合條件。我只是試圖在通知區域中雙擊我的圖標,而該工具嘗試在循環中設置前景窗口並且它工作,它設法設置它(因爲我發送了最後一個事件?)。有任何想法嗎? – Mohammad

+0

此頁面上的Alt-Tab方法似乎適用於我:http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo 什麼是使用這種'黑客'的含義。如果我找不到其他選擇,我很想使用它。 – Mohammad

回答

0

讓你的應用程序通過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; 
} 
+0

所以這個解決方案是發送一個控制+7消息(WM_HOTKEY),其中我的程序將被允許改變前景窗口?我會試着看看它是否有效,這比我發佈的其他方法有什麼好處。非常感謝:D – Mohammad

+0

Control + 7(Num Pad)確實是一個不錯的選擇。我認爲這可能會混淆標準的Ctrl + Home。你必須選擇其他的東西,也許Ctrl + 5(數字鍵盤)。好處是,*可能*:比玩假鼠標點擊更可靠。一定要處理'RegisterHotKey'失敗'(並用另一個組合重試) – manuell

0

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