我打算從純CWin32的角度回答這個問題,因爲我不知道Delphi或其庫。將它轉換爲C#可以通過p/invoke來完成,但有些部分可能需要不受管理。
首先,沒有保證。如果目標應用程序正在執行無窗口控件(如果在每個屏幕控件下都沒有HWND
),那麼您的運行狀況非常糟糕。這是不是所有的罕見,所以是...
步驟1,註冊一個窗口鉤子監聽由目標進程*創建的新窗口:
//dllHMod is an HMODULE that refers to the DLL containing ShellHookProc
HHOOK hook = SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHMod, 0);
// error handling, stashing hook away for unregistering later, etc...
LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0) return CallNextHookEx(NULL, nCode, wParam, lParam);
if(nCode == HSHELL_WINDOWCREATED)
{
WindowCreate((HWND)wParam);
}
return 0;
}
WindowCreated(HWND)
應該藏匿HWND的路程,如果在正確的過程(通過GetWindowThreadProcessId
確定)擁有它。此時,您將能夠獲取目標進程擁有的每個頂級窗口。請注意,註冊全局鉤子會帶來顯着的性能損失,而不是它對您的情況非常重要,但您應該期待它。
現在的樂趣部分。沒有可靠的方法來告訴窗口何時完全構建,或者完成了渲染(有些方法可以告訴它什麼時候開始渲染,但這沒有什麼幫助)。我的建議,猜想。只要在這裏拋出一些隨意的等待,然後嘗試枚舉所有的子窗口。
枚舉子窗口(如果你足夠了解目標窗口,有更好的方法來做到這一點,但我假設的搜索是最容易):
//targetHWND is an HWND of one of the top-level windows you've found
EnumChildWindows(targetHWND, ChildWindowCallback, NULL);
//more code...
BOOL ChildWindowCallback(HWND window, LPARAM ignored)
{
if(IsTargetWindow(window)) { /* Do something */ }
return TRUE;
}
實施IsTargetWindow
是另一個棘手的部分。希望你會找到一些可靠的測試(例如檢查課程名稱,窗口名稱,樣式,看看GetWindowInfo
)。
一旦你有你想監視的窗口,你可以使用SetWindowLongPtr
和GWLP_WNDPROC
來收看它收到的所有消息。這將需要代碼注入(因此需要非託管代碼)並且級別非常低。我建議反對它,如果你可以避免它,但缺乏來源...
我認爲這個答案是一個體面的起點,但再次這將是非常痛苦的如果它甚至可能在所有。祝你好運。 *或者,如果您知道目標應用程序不在啓動時(或在可檢測/可預測的時間點)創建窗口,則可以使用EnumWindows
。
Whew。自從我上次在Delphi開發軟件已經有五年了,所以我沒有完全有資格回答,但是當你唯一擁有的是二進制文件時,這聽起來不太可能。我並不是說要高興或者成爲一個聰明人,但是像這樣的事情是開放源碼的論點 - 如果不向公衆開放,那麼至少對付費用戶開放。 – 2010-01-02 13:41:35
你在開發什麼語言? – 2010-01-02 14:11:46