此问题仅在Windows 10上发生。在其他版本(如Windows 7)上运行良好。
在用户操作上,我有以下代码来查找另一个打开的应用程序窗口:
void zcTarget::LocateSecondAppWindow( void ) { ghwndAppWindow = NULL; CString csQuickenTitleSearch = "MySecondApp"; ::EnumDesktopWindows( hDesktop, MyCallback, (LPARAM)(LPCTSTR)csTitleSearch ); }
callback函数如下:
BOOL CALLBACK MyCallback( HWND hwnd, LPARAM lParam) { if ( ::GetWindowTextLength( hwnd ) == 0 ) { return TRUE; } CString strText; GetWindowText( hwnd, strText.GetBuffer( 256 ), 256 ); strText.ReleaseBuffer(); if ( strText.Find( (LPCTSTR)lParam ) == 0 ) { // We found the desired app HWND, so save it off, and return FALSE to // tell EnumDesktopWindows to stopping iterating desktop HWNDs. ghwndAppWindow = hwnd; return FALSE; } return TRUE; } // This is the line after which call is not returned for about 30 mins
上面提到的这个callback函数被调用了大约7次,每次都返回True。 在这个阶段,它会find通过它调用EnumDesktopWindows的自己的应用程序窗口。
它如预期的那样返回True,但是约30分钟没有任何反应。 没有debugging点击。 原来的运行应用程序在这一点上是没有反应的。
如何解决这个问题?
找到另一条路。 而不是通过窗口名称,寻找过程的帮助。 使用进程名获取进程,提取进程ID并获取窗口句柄。
void zcTarget::LocateSecondAppWindow( void ) { PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (Process32First(snapshot, &entry) == TRUE) { while (Process32Next(snapshot, &entry) == TRUE) { if (_stricmp(entry.szExeFile, "myApp.exe") == 0) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); EnumData ed = { GetProcessId( hProcess ) }; if ( !EnumWindows( EnumProc, (LPARAM)&ed ) && ( GetLastError() == ERROR_SUCCESS ) ) { ghwndQuickenWindow = ed.hWnd; } CloseHandle(hProcess); break; } } } CloseHandle(snapshot); } BOOL CALLBACK EnumProc( HWND hWnd, LPARAM lParam ) { // Retrieve storage location for communication data zcmTaxLinkProTarget::EnumData& ed = *(zcmTaxLinkProTarget::EnumData*)lParam; DWORD dwProcessId = 0x0; // Query process ID for hWnd GetWindowThreadProcessId( hWnd, &dwProcessId ); // Apply filter - if you want to implement additional restrictions, // this is the place to do so. if ( ed.dwProcessId == dwProcessId ) { // Found a window matching the process ID ed.hWnd = hWnd; // Report success SetLastError( ERROR_SUCCESS ); // Stop enumeration return FALSE; } // Continue enumeration return TRUE; }