在XP x32/x64以及Vista x64的平台上測試,都可以正正確確的找到第一個程式的hWnd。但是在"某台特定"的Vista x32上卻發生第二個程式永遠抓到一組固定的hWnd,即使是第一個程式有重開過。
這個現象就非常的不合理,因為每次視窗重新產生的時候,都會有不同的hWnd,所以這邊的FindWindow抓到了誰,那就不得而知了。所以這邊在做PostMessgae的時候,想當然,資料就永遠傳不到第一個程式了。
後來在網路上搜尋了一下,發現還有EnumWindow(WNDENUMPROC EnumProc, LPARAM lParam)可以用來取得所有視窗的hWnd。這個API還須透過一個Callback function來使用,就是EnumWindowProc(HWND hWnd, LPARAM lParam)。第二個參數看個人需求可選擇自行傳遞,這邊是因為要取得第一個程式的hWnd,所以這邊是傳入第一個程式的PID。
由於這邊是使用PID來比對,所以還需要透過GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId)來取得目前所列舉的視窗的PID。
之後就可以利用取得之hWnd來進行PostMessage了。
Callback的範例如下
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD iPID = 0;
if ( GetWindowThreadProcessId(hwnd, &iPID) != NULL )
{
if ( iPID == (DWORD)lParam )
{
m_1sthWnd = hwnd;
return FALSE; //Find the PID and stop the callback function
}
}
return TRUE; //Continue the callback function
}
EnumWindow使用範例如下
::EnumWindows(&EnumWindowsProc, (LPARAM)m_1stPID);
2009/Sep/30-Add
不過這種方法在遇到會換hWnd的Dialog下就會出問題(目前我遇到的是切換combo會造成hWnd的變更),所以最保險的還是用FindWindow會比較好。
不過還是要找比較安全的作法才行。