枚举所有Windows所有窗口句柄并在Ctreelist控件显示

敢问题解决的时候相当棘手   记录以备后用

 

解决思路

 

EnumWindows  -->EnumWindowsProc -->EnumChildWindows -->EnumChildProc

在EnumWindowsProc 获得一个父(祖先)窗口后加入链表HwndList (元素由窗口句柄及其在Ctreelist中的位置组成)

 EnumChildProc 中查到一个窗口 首先去HwndList中查找其父窗口 找到后根据链表元素信息得到其父窗口在树控件中的位置

然后插入到其后

 

解决了如下问题

1:EnumWindows  -->可以获得一个父(祖先)窗口A

2:EnumChildWindows (A)  -->将获得A中的所有子窗口 而不仅仅是其下层 包括A的子窗口B1,B2...  及B1的子窗口C1,C2......

如图

 

  

 

代码演示如下

//为了贴代码方便就将这些变量一起放在cpp了 typedef HWND (WINAPI *pGETANCESTORFUN)(HWND hwnd, UINT gaFlags); HMODULE hUser32 =GetModuleHandle(_T("User32.dll")); pGETANCESTORFUN MyGetAncestor = (pGETANCESTORFUN)GetProcAddress(hUser32,_T("GetAncestor")); //treelist中窗口信息 typedef struct _TreeItem { HWND m_hWnd; //父窗口句柄 HTREEITEM m_hTreeItem; //父窗口在tree控件中的位置 //构造及重载见下 _TreeItem() { m_hWnd = NULL; m_hTreeItem = NULL; } _TreeItem::_TreeItem(HWND hwnd) { m_hWnd = hwnd; m_hTreeItem = NULL; } BOOL operator==(_TreeItem theObj) const //不能少const { return (m_hWnd == theObj.m_hWnd); } }TreeItem,*pTreeItem; CList HwndList; BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam) { //-->获得窗口信息 CEnumWindowDlg* pDlg = (CEnumWindowDlg*)lParam; char strBuffer[MAX_PATH] = {0}; GetWindowText(hwnd,strBuffer,MAX_PATH); CString csTxt; csTxt.Format("窗口句柄 = %08X, 窗口标题 = %s/r/n",hwnd,strBuffer); //查找该窗口的父窗口在链表中的位置-->在treelist中的位置 HWND hParentHwnd = GetParent(hwnd); //如果没有父窗 则用GetAncestor得其祖先窗口-->GetAncestor的使用类似openthread需要自己获得其指针 if (!hParentHwnd) { hParentHwnd = MyGetAncestor(hwnd,GA_PARENT); } TRACE0(csTxt); //在链表中找其父窗口信息 POSITION pos = HwndList.Find(TreeItem(hParentHwnd)); TreeItem hParentInfo = HwndList.GetAt(pos); //构造当前hwnd元素并加入链表 TreeItem hCurListItem; hCurListItem.m_hWnd = hwnd; hCurListItem.m_hTreeItem = pDlg->m_Tree.InsertItem(csTxt,hParentInfo.m_hTreeItem); HwndList.AddHead(hCurListItem); return TRUE; } BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { //-->获得窗口信息 CEnumWindowDlg* pDlg = (CEnumWindowDlg*)lParam; char strBuffer[MAX_PATH] = {0}; GetWindowText(hwnd,strBuffer,MAX_PATH); CString csTxt; csTxt.Format("窗口句柄 = %08X, 窗口标题 = %s/r/n",hwnd,strBuffer); if (strcmp("「开始」菜单",strBuffer) == 0) { //当前赋值 TreeItem hCurListItem; hCurListItem.m_hWnd = hwnd; hCurListItem.m_hTreeItem = pDlg->m_Tree.InsertItem(csTxt,TVI_ROOT); TRACE0(csTxt); //当前元素(窗口信息)加入链表 HwndList.AddHead(hCurListItem); //枚举该窗口子窗口 EnumChildWindows(hwnd,EnumChildProc,lParam); } return TRUE; } void CEnumWindowDlg::OnButton() { // TODO: Add your control notification handler code here EnumWindows(EnumWindowsProc,(LPARAM)this); }

 

效果图如下

你可能感兴趣的:(枚举所有Windows所有窗口句柄并在Ctreelist控件显示)