2014-05-17 68 views
5

首先,我知道這是一個有爭議的討論,但我希望我們可以保留這個技術。允許後臺應用程序設置不同過程的前景窗口

我有一個應用程序在後臺啓動,我不知何故希望它能夠激活/帶來在不同的過程中集中一個窗口。但是調用SetForegroundWindow總是失敗,即使我想要激活的窗口的進程調用了AllowSetForegroundWindow(ASFW_ANY)。

原因是(IMO)發起的應用程序是後臺進程,並且由於它沒有收到輸入,所以不允許設置前臺窗口。所以一切都出現在任務列表中,但沒有顯示。

所以我試着創建一個虛擬窗口來接收輸入,它是立即關閉的,然後之後能夠成功調用SetForegroundWindow。但即使是我顯示的虛擬窗口也顯示在背景中。

然而,如果我叫

AttachThreadInput(
    GetWindowThreadProcessId(GetForegroundWindow(), NULL), 
    GetCurrentThreadId(), TRUE); 

創建虛擬窗口前,在前景確實是創建的窗口,我可以後來在不同的進程,其作品調用SetForegroundWindow爲不同HWND。

但是:如果我不創建虛擬窗口,SetForegroundWindow仍然返回零,雖然我使用AttachThreadInput。

我不明白爲什麼AttachThreadInput攻擊是成功的,如果我創建一個自己的窗口(以後成功的其他窗口),但不成功,如果我不先創建自己的窗口。

我的後臺進程如何在不同的進程中調用SetForegroundWindow不同的窗口沒有創建一個虛擬窗口?

[*]後臺應用程序實際上是gpg-agent.exe,無論何時請求密碼,它都會調用pinentry.exe(我的應用程序)。 pinentry.exe(運行的後臺程序)必須從其他運行的應用程序要求的密碼,因此必須將其窗口前臺...

+0

可能的重複http://stackoverflow.com/questions/688337/how-do-i-force-my-app-to-come-to-the-front-and-take-focus –

+0

不,不在我的意見,因爲我不想創建一個自己的虛擬窗口。即使使用AttachThreadInput,SetForegroundWindow對於不同的窗口/進程也不起作用;當我創建自己的(虛擬)窗口時,它可以工作。 – divB

+0

你不能這樣做。如果你沒有*重點,你不能放棄。正如雷蒙德所說,「你不能放棄那些不屬於你的東西」。這是Windows中一個非常慎重的設計決定。 http://blogs.msdn.com/b/oldnewthing/archive/2009/02/20/9435239.aspx –

回答

0

documentationAttachThreadInput()爲您提供了一個線索:創建

的Windows在不同的線程中通常獨立處理輸入。也就是說,它們有自己的輸入狀態(焦點,活動,捕獲窗口,鍵狀態,隊列狀態等等),並且它們的輸入處理與其他線程的輸入處理不同步。通過使用AttachThreadInput函數,線程可以將其輸入處理機制附加到另一個線程。兩個線程接收到的鍵盤和鼠標事件都由idAttachTo參數指定的線程處理,直到通過再次調用AttachThreadInput併爲fAttach參數指定FALSE來分離線程爲止。 這也允許線程共享其輸入狀態,因此他們可以調用SetFocus函數來將鍵盤焦點設置爲不同線程的窗口。這也允許線程獲得密鑰狀態信息。

documentationSetForegroundWindow()告訴你什麼樣的標準調用進程的需要,以設置前臺窗口,以滿足:

系統限制哪些進程可以設置前臺窗口。只有滿足以下條件之一時,進程纔可以設置前景窗口:

該進程是前臺進程。
該過程由前臺進程啓動。
該進程收到最後一次輸入事件。
沒有前臺進程。
該進程正在調試。
前臺進程不是現代應用程序或開始屏幕。
前景未鎖定(請參閱LockSetForegroundWindow)。
前臺鎖定超時已過期(請參閱SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT)。
沒有菜單處於活動狀態。

簡單地創建一個虛擬窗口本身並不能保證你將成爲前臺進程。將窗口線程連接到當前前臺窗口的線程可以讓您共享其輸入狀態,如果前臺線程有權這樣做,則您可以更好地獲得設置前臺窗口的權限。

相關問題