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
附:spyxx.exe的使用:http://blog.csdn.net/yangyang031213/article/details/61624372