A couple of weeks ago someone here helped me out 开发者_如何学编程with writing a class that enumerates all main windows.
Today I tried to modify that class in order to enumerate all child windows of a specific parent window.
Here is the header file:
#include "TChar.h"
#include "string.h"
#include "windows.h"
#include "Winuser.h"
#include <string>
#include <vector>
using namespace std;
typedef std::basic_string<TCHAR> tstring; //define basic_string<TCHAR> as a member of the std namespace
//and at the same time use typedef to define the synonym tstring for it
class Handles {
public:
struct child_data
{
tstring caption;
HWND handle;
};
private:
std::vector<child_data> stuff; //define a vector of objecttype "child_data" (the struct defined above) named stuff
BOOL add_window(HWND hwnd)
{
TCHAR String[200] = {0};
if (!hwnd)
return TRUE; // Not a window, return TRUE to Enumwindows in order to get the next handle
if (!::IsWindowVisible(hwnd))
return TRUE; // Not visible, return TRUE to Enumwindows in order to get the next handle
LRESULT result = SendMessageW(hwnd, WM_GETTEXT, sizeof(String), (LPARAM)String); //result stores the number of characters copied from the window
if (!result)
return TRUE; // No window title, return TRUE to Enumwindows in order to get the next handle
child_data data; // define an object of type child_data called data
data.handle = hwnd; //copy the handle to the data.handle member
for(int i = 0; i < result; i++) //copy each character to data.caption by using push_back
data.caption.push_back(String[i]);
stuff.push_back(data); //Put the whole data (with its members data.caption and data.handel) struct in the vector "stuff" using pushback
return TRUE;
}
static BOOL CALLBACK EnumChildWindows(HWND hwnd, LPARAM lParam)
{
Handles* ptr = reinterpret_cast<Handles*>(lParam);
return ptr->add_window(hwnd);
}
public:
Handles& enum_windows()
{
stuff.clear(); //clean up
if(!EnumWindows(EnumChildWindows, reinterpret_cast<LPARAM>(this)))
{
// Error! Call GetLastError();
}
return *this;
}
std::vector<child_data>& get_results()
{
return stuff;
}
};
I call the function by:
std::vector<Handles::child_data> windows = Handles().enum_windows().get_results(); //Enumerate all visible windows and store handle and caption in "windows"
The problem is:
I am not quite sure how to pass the handle of the parent window to the callback function in the header. It feels like I have tried everything, but I always end up with errors of the kind: the variable hwnd is not declared in ....
The problem is that I do not understand the class 100%. The things I did figure out are commented.
Thanks for any help!
Instead of calling EnumWindows
, which enumerates over all top-level windows on the screen, you can call EnumChildWindows
to enumerate child windows of a given parent window. To do this, you can add an overload of enum_windows
to your Handles
class:
Handles& enum_windows(HWND hParentWnd)
{
stuff.clear(); //clean up
EnumChildWindows(hParentWnd, Handles_WndEnumProc, reinterpret_cast<LPARAM>(this));
return *this;
}
EnumChildWindows
is a bad name for the WNDENUMPROC
. I suggest renaming it to something more unique, such as Handles_WndEnumProc
.
精彩评论