Browse Source

注意EnumChildWindows关联的EnumChildWindowCallBack不要递归调用,否则会出现重复查找子窗口的问题。

Jeff Wang 3 years ago
parent
commit
d8d05d8cdf

+ 43 - 0
Source/InjectDLL/InjectDLL/Global.cpp

@@ -996,6 +996,49 @@ HWND GetProcessMainWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWndName)
     return hTagetProcessWnd;
 }
 
+BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam)  
+{  
+    DWORD dwPid = 0;  
+    LPWNDDATA lpWndData = (LPWNDDATA)lParam;
+    GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程  
+    if(dwPid == lpWndData->dwPid) // 判断是否是目标进程的窗口  
+    {  
+        TCHAR buf[MAX_PATH];
+        TCHAR szClassName[MAX_PATH] = {0};
+        SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)buf); 
+        GetClassName(hWnd, szClassName, MAX_PATH);
+        TRACE3("B-0x%08X, %s, %s\n", hWnd, szClassName, buf);  // 输出窗口信息  
+        // 此处如果再递归,会导致重复查找2次子窗口;
+        //EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam);    // 递归查找子窗口 
+        return TRUE;
+    }  
+
+    return FALSE;  
+}  
+
+BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam)  
+{  
+    DWORD dwPid = 0; 
+    LPWNDDATA lpWndData = (LPWNDDATA)lParam;
+    GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程  
+    if(dwPid == lpWndData->dwPid) // 判断是否是目标进程的窗口  
+    {  
+        TCHAR buf[MAX_PATH];  
+        TCHAR szClassName[MAX_PATH] = {0};
+        SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)buf);  
+        GetClassName(hWnd, szClassName, MAX_PATH);
+        TRACE3("A-0x%08X, %s, %s\n", hWnd, szClassName, buf);  // 输出窗口信息  
+        EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam);    // 继续查找子窗口  
+    }
+
+    return TRUE;  
+} 
+
+BOOL EnumProcessAllWnd(LPWNDDATA lpWndData)
+{
+    return EnumWindows(EnumWindowCallBack, (LPARAM)lpWndData);
+}
+
 BOOL GetWeChatPath()
 {
 	// 通过注册表获取微信安装目录;

+ 19 - 1
Source/InjectDLL/InjectDLL/Global.h

@@ -23,6 +23,24 @@ typedef struct __PROCINFO__
     TString strProFile;     // 进程路径;
 }ProInfo, *pProInfo;
 
+typedef struct __WNDINFO__
+{
+    HWND    hWnd;
+    TCHAR   szClassName[MAX_PATH];
+    TCHAR   szWndTitle[MAX_PATH];
+    __WNDINFO__()
+    {
+        memset(szClassName, 0, sizeof(TCHAR)*MAX_PATH);
+        memset(szWndTitle, 0, sizeof(TCHAR)*MAX_PATH);
+    }
+}WNDINFO, *LPWNDINFO;
+
+typedef struct __WNDDATA__
+{
+    DWORD   dwPid;
+    std::vector<WNDINFO> vtWndInfo;
+}WNDDATA,*LPWNDDATA;
+
 // 全局变量;
 extern TCHAR g_szModulePath[MAX_PATH];			// 软件目录;
 extern TCHAR g_szModuleFileName[MAX_PATH];		// 软件名称;
@@ -69,7 +87,7 @@ extern BOOL MySystemShutdown();
 HWND GetProcessMainWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWndName);
 // 获取指定进程名的进程主窗口;
 HWND GetProcessMainWnd(LPCTSTR lpProcessName, LPCTSTR lpTagetWndName);
-
+BOOL EnumProcessAllWnd(LPWNDDATA lpWndData);
 //////////////////////////////////////////////////////////////////////////
 extern BOOL GetWeChatPath();
 extern BOOL OpenWeChat();

+ 3 - 0
Source/InjectDLL/InjectDLL/InjectDLLDlg.cpp

@@ -268,6 +268,9 @@ void CInjectDLLDlg::OnBnClickedHideWnd()
     ProInfo *ptr = (ProInfo*)m_cbProcess.GetItemDataPtr(nCurSel);
     if ( ptr )
     {
+        WNDDATA wndData;
+        wndData.dwPid = ptr->dwProId;
+        EnumProcessAllWnd(&wndData);
         g_hCurrentProWnd = GetProcessMainWnd(ptr->dwProId, _T("Demo"));
         //g_hCurrentProWnd = GetProcessMainWnd(ptr->dwProId, NULL);
         if ( g_hCurrentProWnd )