【Demo 0032】遍历子窗体

在上节中我们学习如何遍历顶层窗体,本节中我们继续学习如何遍历子窗体,在例程中我们用使用了二种方法来遍历子窗体;

1.  使用EnumChildWindows 遍历

    BOOL EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc, LPARAM lParam );

     功能:  遍历指定窗体的子窗体,将遍历到的子窗体通知预设的回调函数,并以遍历完子窗体或回调函数返回FALSE结束,  最后一参数用于将信息传递给回调函数

     说明:  a.  与函数与EnumChildWindows函数用法与EnumWindows几乎一样, EnumWindows 仅能遍历顶层窗体; 此函数枚举的窗体为CreateWindowEx时风格设有WS_CHILD

                  且父窗体被指定为EnumChildWindows中第一个参数 

              b.  EnumChildWindows 不能枚举到遍历前己销毁和遍历期间己创建的窗体

   

2.  使用GetWindow 遍历

HWND GetWindow(HWND hWnd, UINT uCmd);

      功能:  获取与指定窗体相对关系(Z-ORDER,OWNER), 根据uCmd参数不同返回不同的窗体

               GW_CHILD                  返回hWnd窗体第一个子窗体

               GW_ENABLEDPOPUP

               GW_HWNDFIRST    返回与hWnd窗体具有相同z-oder的窗体

               GW_HWNDLAST     意思与GW_HWNDFIRST 相同, 仅表示返回的是最后一个

               GW_HWNDNEXT     通常与GW_HWNDFIRST配合使用返回下一个具有相同z-oder的窗体

               GW_HWNDPREV     通常与GW_HWNDLAST配合使用返回上一个具有相同z-oder的窗体

               GW_OWNER           获取指定窗体拥有者窗体或父窗体

      说明:  此方法遍历子窗体没有EnumChildWindows函数稳定, 但它可以枚举到遍历期间消毁的窗体.

 

我们例程功能主要演示了这两种遍历方法的使用, 演示过程中我们将遍历到的窗体分别显示到二个ListBox窗体中, 看看演示代码

  1.  调用方法

  1. case WM_COMMAND:
  2. {
  3.     switch (wParam)
  4.     {
  5.         case IDC_BTNDATAREAD:
  6.         {
  7.             HWND hListbox    = GetDlgItem(hWnd, IDC_LSTWNDLIST);
  8.             HWND hListbox1    = GetDlgItem(hWnd, IDC_LSTWNDLIST1);
  9.             SendMessage(hListbox, LB_RESETCONTENT, 0, 0);
  10.             SendMessage(hListbox1, LB_RESETCONTENT, 0, 0);
  11.  
  12.             HWND hParent = GetDesktopWindow();
  13.             _EnumChildWindows(hParent, hListbox);
  14.             EnumChildWindows(hParent, EnumChildWndProc, (LPARAM)hListbox1);
  15.  
  16.             SetWindowText(GetDlgItem(hWnd, IDC_BTNDATAREAD), _T("Refresh"));
  17.         }
  18.         break;
  19.     }
  20.     break;
  21. }

  2. _EnumChildWindows  - GetWindow方法遍历

  1.  
  2. //////////////////////////////////////////////////////////////////////////
  3. void _EnumChildWindows(HWND hParent, HWND hDisplay)
  4. {
  5.     HWND hWndChild    = GetWindow(hParent, GW_CHILD);
  6.     HWND hWndTemp    = GetWindow(hWndChild, GW_HWNDFIRST);
  7.     do {
  8.         TCHAR szWndInfo[512]    = {0};
  9.         TCHAR szWndTitle[256]    = {0};
  10.         TCHAR szClsName[64]        = {0};
  11.  
  12.         GetWindowText(hWndTemp, szWndTitle, 256);
  13.         GetClassName(hWndTemp, szClsName, 64);
  14.         _stprintf(szWndInfo,
  15.                     _T("´°¿Ú%08X ")
  16.                     _T("\"%s\"")
  17.                     _T("%s ")
  18.                     _T("%s"),
  19.                     hWndTemp,
  20.                     szWndTitle,
  21.                     szClsName,
  22.                     IsWindowVisible(hWndTemp) ? _T("Visible") : _T("Invisible"));
  23.         SendMessage(hDisplay, LB_ADDSTRING, 0, (LPARAM)szWndInfo);
  24.     } while (NULL != (hWndTemp = GetWindow(hWndTemp, GW_HWNDNEXT)));
  25. }

  3.  EnumChildWindows 方法

  1. //////////////////////////////////////////////////////////////////////////
  2. BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam)
  3. {
  4.     HWND hListbox = (HWND)lParam;
  5.     if (NULL == hWnd)    return FALSE;
  6.  
  7.     if (NULL != hListbox && IsWindow(hListbox))
  8.     {
  9.         TCHAR szWndInfo[512]    = {0};
  10.         TCHAR szWndTitle[256]    = {0};
  11.         TCHAR szClsName[64]        = {0};
  12.  
  13.         GetWindowText(hWnd, szWndTitle, 256);
  14.         GetClassName(hWnd, szClsName, 64);
  15.         _stprintf(szWndInfo,
  16.                   _T("´°¿Ú%08X ")
  17.                   _T("\"%s\" ")
  18.                   _T("%s ")
  19.                   _T("%s"),
  20.                   hWnd,
  21.                   szWndTitle,
  22.                   szClsName,
  23.                   IsWindowVisible(hWnd) ? _T("Visible") : _T("Invisible"));
  24.         SendMessage(hListbox, LB_ADDSTRING, 0, (LPARAM)szWndInfo);
  25.     }
  26.  
  27.     return TRUE;
  28. }

遍历结果图, 我也参考了SPY++ 的遍历方法

image

根据上图的结果我发现两个问题,  1.  使用GetWindow与EnumChildWindows枚举出来的窗体不一致;  2. SPY++ 遍历的结果与通过GetWindow的得到的结果是一样的,说明SPY++也是使用了这种方式.

演示代码

原文地址:https://www.cnblogs.com/ztercel/p/2150016.html