您的位置:首页 > 其它

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

2010-05-20 20:55 1126 查看
敢问题解决的时候相当棘手 记录以备后用

解决思路

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<TreeItem ,TreeItem&> 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);
}


效果图如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐