枚举窗口

来源:互联网 发布:java 通用excel导出 编辑:程序博客网 时间:2024/06/05 12:20

枚举窗口

  • FindWindow:
    windows中可以使用FindWindow查找指定窗口:
HWND WINAPI FindWindow(  _In_opt_ LPCTSTR lpClassName,//窗口类名  _In_opt_ LPCTSTR lpWindowName//窗口名,标题);

lpClassName为注册窗口时的类名,如果为NULL,则匹配标题,返回值为句柄。类名窗口名可以使用spyxx可以看得到(最后介绍)。
使用如下:

HWND handle = NULL;FindWindow(NULL, "任务管理器");RECT rect;int width, height;if (handle){    GetWindowRect(handle, &rect);    width = rect.right - rect.left, height = rect.bottom - rect.top;    cout << "宽: " << width << endl << "高: " << height << endl;    cout<<MoveWindow(handle, 100, 100, width, height, true)<<endl;}
  • FindWindowEx:
HWND WINAPI FindWindowEx(  _In_opt_ HWND    hwndParent,//父窗口句柄  _In_opt_ HWND    hwndChildAfter,//子窗口句柄  _In_opt_ LPCTSTR lpszClass,//类名  _In_opt_ LPCTSTR lpszWindow//窗口名);

当hwndParent为NULL时即枚举桌面子窗口。

  • EnumWindows:
BOOL WINAPI EnumWindows(  _In_ WNDENUMPROC lpEnumFunc,//回调函数  _In_ LPARAM      lParam//传递给回调函数的参数);

该枚举屏幕上的顶层窗口,并将窗口句柄传送给应用程序定义的回调函数,其中lParam是传递给lpEnumFunc的参数。回调函数返回FALSE将停止枚举,否则EnumWindows函数继续到所有顶层窗口枚举完为止。

  • EnumChildWindows:
 BOOL WINAPI EnumChildWindows(  _In_opt_ HWND        hWndParent,\\父窗口  _In_     WNDENUMPROC lpEnumFunc,\\回调函数  _In_     LPARAM      lParam\\传递给回调函数的参数);

该函数遍历指定窗口的所有子窗口,其他参数和EnumWindows类似。
有了这几个函数之后,就可以遍历窗口、遍历特定窗口子控件、对某个窗口发送消息等。
如下代码可以用于枚举窗口:

#include <windows.h>#include <cstdio>#include <string>#include <iostream>using namespace std;//子窗口回调函数BOOL CALLBACK EnumChildWindowsProc(HWND hwnd,LPARAM lParam){    char title[100] = { 0 };    GetWindowTextA(hwnd, title, 100);    if (strlen(title)>0)        cout <<hex<<"句柄:"<<hwnd<<"  标题:"<<title << endl;    return true;}BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam){    char title[100] = { 0 };    GetWindowTextA(hwnd, title, 100);    if (strlen(title) > 0)        cout << hex << "句柄:" << hwnd << "  标题:" << title << endl;    EnumChildWindows(hwnd, EnumChildWindowsProc, NULL);    return true;}BOOL myEnumWindow(HWND hwnd){    char title[100] = { 0 };    HWND after = NULL;    while (after = ::FindWindowEx(hwnd, after, NULL, NULL))    {        GetWindowTextA(after, title, 100);        if(strlen(title)>0)            cout <<"句柄:"<<hex<< after<<"  标题:" << title <<endl;        myEnumWindow(after);    }    return true;}int main(){    HWND handle = NULL;    FindWindow(NULL, "任务管理器");//查找特定窗口的窗口句柄    RECT rect;    int width, height;    if (handle)    {        GetWindowRect(handle, &rect);//获取窗口信息        width = rect.right - rect.left, height = rect.bottom - rect.top;        cout << "宽: " << width << endl << "高: " << height << endl;        cout << MoveWindow(handle, 100, 100, width, height, true) << endl;    }    //使用EnumWindows枚举窗口,获取所有顶层可见窗口及他们的子窗口    EnumWindows(EnumWindowsProc, NULL);    cout << endl << endl << "第二种方法:" << endl;    myEnumWindow(NULL);//使用FindWindowEx枚举窗口    getchar();    getchar();    return 0;}

枚举窗口,获取到窗口句柄之后,很多操作都可以进行啦。

  • 效果:
    这里写图片描述

  • 注:部分不可见窗口,可能使用使用上边的代码都无法查找到,可以尝试使用如下代码获取,myEnumWindow 为上述代码中的函数,只是调用参数为 HWND_MESSAGE:

myEnumWindow(HWND_MESSAGE);

改了个MFC的版本:
- 代码:

BEGIN_MESSAGE_MAP(CEnumWindowDlg, CDialogEx)    ON_WM_PAINT()    ON_WM_QUERYDRAGICON()    ON_BN_CLICKED(IDC_ENUM, &CEnumWindowDlg::OnBnClickedEnum)    ON_BN_CLICKED(IDC_FIND, &CEnumWindowDlg::OnBnClickedFind)    ON_BN_CLICKED(IDC_FIND_MSG, &CEnumWindowDlg::OnBnClickedFindMsg)    ON_BN_CLICKED(ID_EXIT, &CEnumWindowDlg::OnBnClickedExit)END_MESSAGE_MAP()BOOL CALLBACK EnumChildWindowsProc(HWND hwnd, LPARAM lParam){    CEnumWindowDlg * pParent = (CEnumWindowDlg*)lParam;    TCHAR title[MAX_PATH] = { 0 };    if (GetWindowText(hwnd, title, sizeof(title)) > 0)    {        CString s;        int pos = pParent->m_list.GetItemCount();        s.Format(_T("%d"), pos);        pParent->m_list.InsertItem(pos, s);        s.Format(_T("%p"), hwnd);        pParent->m_list.SetItemText(pos, 1, s);        pParent->m_list.SetItemText(pos, 2, CString(title));    }    return true;}BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam){    CEnumWindowDlg * pParent = (CEnumWindowDlg*)lParam;    TCHAR title[MAX_PATH] = { 0 };    if (GetWindowText(hwnd, title, sizeof(title)))    {        CString s;        int pos = pParent->m_list.GetItemCount();        s.Format(_T("%d"), pos);        pParent->m_list.InsertItem(pos, s);        s.Format(_T("%p"), hwnd);        pParent->m_list.SetItemText(pos, 1, s);        pParent->m_list.SetItemText(pos, 2, CString(title));    }    EnumChildWindows(hwnd, EnumChildWindowsProc, lParam);    return true;}BOOL CEnumWindowDlg::myEnumWindow(HWND hwnd){    TCHAR title[MAX_PATH] = { 0 };    HWND after = NULL;    while (after = ::FindWindowEx(hwnd, after, NULL, NULL))    {        if (::GetWindowText(after, title, sizeof(title)) > 0)        {            CString s;            int pos = m_list.GetItemCount();            s.Format(_T("%d"), pos);            m_list.InsertItem(pos, s);            s.Format(_T("%p"), after);            m_list.SetItemText(pos, 1, s);            m_list.SetItemText(pos, 2, CString(title));        }        myEnumWindow(after);    }    return true;}// CEnumWindowDlg 消息处理程序BOOL CEnumWindowDlg::OnInitDialog(){    CDialogEx::OnInitDialog();    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动    //  执行此操作    SetIcon(m_hIcon, TRUE);         // 设置大图标    SetIcon(m_hIcon, FALSE);        // 设置小图标    m_list.SetExtendedStyle(m_list.GetStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);    CRect rect;    GetWindowRect(&rect);    m_list.InsertColumn(0, _T("序号"), LVCFMT_LEFT, rect.Width() / 8, 0);    m_list.InsertColumn(1, _T("句柄"), LVCFMT_LEFT, rect.Width() / 4, 1);    m_list.InsertColumn(2, _T("窗口名"), LVCFMT_LEFT, 5 * rect.Width() / 8, 2);    ((CButton*)GetDlgItem(IDC_ENUM))->SetCheck(TRUE);    EnumWindows(EnumWindowsProc, (LPARAM)this);    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void CEnumWindowDlg::OnBnClickedEnum(){    m_list.DeleteAllItems();    EnumWindows(EnumWindowsProc, (LPARAM)this);}void CEnumWindowDlg::OnBnClickedFind(){    m_list.DeleteAllItems();    myEnumWindow(NULL);//使用FindWindowEx枚举窗口}void CEnumWindowDlg::OnBnClickedFindMsg(){    m_list.DeleteAllItems();    myEnumWindow(HWND_MESSAGE);//使用FindWindowEx枚举窗口}void CEnumWindowDlg::OnBnClickedExit(){    CDialogEx::OnOK();}
  • 效果:
    这里写图片描述
    这里写图片描述
    这里写图片描述

代码链接:
VS2015工程:http://download.csdn.net/detail/yangyang031213/9891558

  • 附:spyxx.exe的使用:http://blog.csdn.net/yangyang031213/article/details/61624372
0 0