枚举窗口

枚举窗口

  • 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
https://github.com/yangyang0312/cpp/tree/master/windows/EnumWindow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值