2011-08-22 20 views
6

我有一個.NET應用程序需要能夠檢測特定窗口何時獲得並失去焦點。我感興趣的特定窗口屬於另一個我無法控制的應用程序,雖然我有窗口句柄。.NET/Win32 - 檢測屬於另一個應用程序的窗口何時獲得焦點的事件

我真的是最好的方法來解決這個問題。到目前爲止,我可以看到2種可能性:一個計時器使用Win32調用來監視狀態的任何變化

  1. 。不是很好,因爲它存在缺失狀態變化的風險,例如如果窗口變爲活動狀態,則在定時器間隔內處於非活動狀態
  2. 使用掛鉤(SetWindowsHookEx)截獲到窗口的消息。聽起來像它應該工作,但擔心a)全局級掛鉤不會從.NET代碼工作,所以需要本地和b)這可以被視爲病毒/鍵盤記錄類型的活動,所以被操作系統阻止?

我敢肯定,還有其他的選擇,如果是的話,我很樂意聽到他們!

回答

6

最簡單的方法很可能是使用SetWinEventHook,監聽EVENT_SYSTEM_FOREGROUND事件。您需要將它與WINEVENT_OUTOFCONTEXT標誌一起使用,以便在.net中使用它:當您使用此標誌時,Windows會將通知路由回您自己的進程,因此您不需要單獨的非託管DLL。但請注意,調用此方法的代碼必須運行一個消息循環。

有關如何與其他答案中提到的文章相關的快速說明:該文章重點介紹SetWindowsHook API。 SetWinEventHook是一個單獨的API,但是您使用相同的技術來設置P/Invoke調用,併爲回調設置代理 - 但請注意,兩個API在API調用本身和回調中都使用不同的參數。 SetWinEventHook已經覆蓋了SetWindowsHook的主要優點,就是對於某些類型的鉤子,SetWindowsHook 要求使用單獨的非託管DLL,這是你不能直接在.net中執行的。然而,SetWinEventHook允許使用任何一種回調方式,使用單獨的非託管DLL或通知原始進程而不需要DLL,所以更適合.net友好。

+2

完美 - 這幾乎正是我所期待的。似乎有一個角落的情況(有時)最大化以前最小化的窗口不會觸發該窗口的EVENT_SYSTEM_FOREGROUND - 因此偵聽EVENT_SYSTEM_MINIMIZEEND也會解決該問題。謝謝,真棒回答 –

+0

當我運行WPF應用程序時,消息循環約束對我來說不是問題。對於任何想要做同樣的事情,但是使用控制檯應用程序(默認情況下沒有消息循環)的人來說,這篇文章是很好的(搜索「在控制檯應用程序中處理消息」,如果鏈接被破壞,則爲「Stephen Toub」) - http:// msdn .microsoft.com/EN-US /雜誌/ cc163417.aspx –

0

下面是一篇關於在.NET中從MSDN雜誌實施windows掛鉤的精彩文章:Windows Hooks in the .NET Framework。至於你的第二個問題,我從來沒有聽說過將這些api調用作爲間諜軟件行爲的防病毒軟件。

希望它有幫助!

相關問題