zoukankan      html  css  js  c++  java
  • 【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++也是使用了这种方式.

    演示代码

  • 相关阅读:
    JavaScript Array filter() 方法
    Object.assign方法的使用入门
    使用ES6新特性async await进行异步处理
    win10系统怎么设置软件开机启动
    【ES6学习笔记之】Object.assign()高级编程
    如何使用闭包形成计数器
    多次调用settimeout 如何使用单例模式
    在线表单设计器现在已经开源
    VisualStudio2017集成GitHub
    PHP使用curl替代file_get_contents
  • 原文地址:https://www.cnblogs.com/ztercel/p/2150016.html
Copyright © 2011-2022 走看看