2009-07-14 19 views
6

因爲我找不到this問題的答案我研究了一點進入MSDN,我發現isChild()。它可能會給我另一個問題的答案。獲取HWND爲我自己的應用程序在C

現在,爲了使用isChild()我需要傳遞我想檢查的父應用程序的HWND,在這種情況下我自己的應用程序。 如何獲得我自己的應用程序的HWND?

我不知道標題,因爲它不斷變化,所以我不能使用FindWindow()。

感謝

編輯:

因爲它是不明確的,我會添加更多的信息: 我不會創建一個窗口。我無法訪問創建窗口。我的代碼是一段代碼,與其他程序員編寫的任何應用程序一起編譯,我無法訪問窗口的創建方式,標題或任何其他信息。 那麼,如何將HWND獲取到正在運行的應用程序的「窗口」?

回答

6

使用GetTopWindow()和GetNextWindow()來遍歷windows z順序。

不過,不要認爲這是必要的,但你可以使用GetCurrentProcessId()和 GetWindowThreadProcessId(),可能是類似以下將幫助您:

HWND FindMyTopMostWindow() 
{ 
    DWORD dwProcID = GetCurrentProcessId(); 
    HWND hWnd = GetTopWindow(GetDesktopWindow()); 
    while(hWnd) 
    { 
     DWORD dwWndProcID = 0; 
     GetWindowThreadProcessId(hWnd, &dwWndProcID); 
     if(dwWndProcID == dwProcID) 
      return hWnd;    
     hWnd = GetNextWindow(hWnd, GW_HWNDNEXT); 
    } 
    return NULL; 
} 
1

難道你不能堅持從CreateWindow返回的句柄嗎?如果不是,爲什麼不呢?

+0

因爲我不是創建一個窗口一個線程的DLL。我的模塊是用別人的代碼編譯的。因此,我無法訪問創建窗口。 現在,知道了,我如何獲得正在運行的應用程序窗口的HWND? – wonderer 2009-07-14 14:20:07

+0

因此,您甚至無法訪問我假設的窗口消息泵? 然後我唯一能想到的就是EnumWindows,然後使用GWL_HINSTANCE參數調用GetWindowLong並將返回的HINSTANCE與從GetModuleHandle返回的HINSTANCE進行比較。 – Goz 2009-07-14 14:45:30

+0

值得注意的是,你會得到與你的HINSTANCE相關的每個HWND ... – Goz 2009-07-14 14:51:40

0

這對我來說很舊,但是IIRC你應該在窗口過程中接收HWND作爲參數。你可以將它保存在一個全局變量的開頭。

+1

實際上,不是將其作爲全局存儲,而是將其傳遞給另一個結構或作爲最後一個參數的指針CreateWindowEX。 WM_CREATE消息期間,該指針將可用於Windows過程。 – 2009-07-14 14:12:58

9

您的應用程序沒有HWND。窗戶確實如此。應用程序可能沒有窗口,也可能有很多窗口,所以沒有「獲取應用程序的HWND」的通用功能。

顯而易見的解決方案就是在拿到手柄時抓住手柄。當您創建窗口時,返回一個HWND。保存。

+0

好的抱歉不正確。 – wonderer 2009-07-14 14:20:38

0

你的Windows類名是什麼? 窗口創建總是不同嗎? 如果不是,你仍然可以找到FindWindow()。

1

正如其他人已經指出

  • 通常,應用程序可以有零個或多個頂層窗口。
  • 如果您自己創建窗口,則可以在某處記住HWND。

但也許你的代碼是在一個DLL中,所以你實際上並沒有自己創建頂層窗口。那麼該怎麼辦?

我建議如下:

  • 使用EnumWindows枚舉所有頂級窗口。使用GetWindowLongPtr可獲得每個頂層窗口的HINSTANCE。將此與應用程序的HINSTANCE進行比較,您可以使用GetModuleHandle(NULL)。如果它們是相同的,那麼你已經找到了你的主窗口。

編輯:這是一些代碼。事實證明,你還必須使用IsWindowVisible,因爲似乎有不少隱形的「幫手」窗口。

HWND hwndMain; 

BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam) 
{ 
    HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL); 

    if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst && 
     IsWindowVisible(hwnd)) 
    { 
     hwndMain=hwnd; 
     return FALSE; 
    } 
    else 
     return TRUE; 
} 

然後在地方,你要查找的窗口:

hwndMain=NULL; 
EnumWindows(EnumWindowProc, 0); 

並在此之後,hwndMain應該包含窗口的句柄,或者NULL如果不存在。

使用EnumWindows有點麻煩,但建議在循環中調用GetWindow,因爲,正如MSDN所指出的那樣:「調用GetWindow執行此任務的應用程序有被陷入無限循環或引用窗口句柄的風險已經被摧毀。「

1

推測你的代碼被主應用程序代碼調用,否則有什麼用處呢?在這種情況下,我看不出爲什麼你的代碼的API不能包含某種方式告知你應用程序主窗口的句柄。

相關問題