Search code examples
c++vectorrectanglesenumeratechildwindow

How to get a list of Window Rectangle from EnumChildWindow and store them?


I used EnumChildWindows and I can get the Handle, ClassName and WindowText of all the child windows. But I also want to get all the child windows' Rectangle. Is it possible?

This is my code:

#include <iostream>
#include <windows.h>
using namespace std;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    char class_name[100];
    char title[100];

    GetClassNameA(hwnd,class_name, sizeof(class_name));
    GetWindowTextA(hwnd,title,sizeof(title));

    cout <<"Window name : "<<title<<endl;
    cout <<"Class name  : "<<class_name<<endl;
    cout <<"hwnd        : "<<hwnd<<endl<<endl;
                                                   
    return TRUE;
}

int main()
{
    POINT pt;
    Sleep(3000);

    GetCursorPos(&pt);
    HWND hwnd = WindowFromPoint(pt);
    HWND hwndParent = GetParent(hwnd);

    EnumChildWindows(hwndParent,EnumWindowsProc,0);

    system("PAUSE");
    return 0;
}

Also, how can I stored all the data (handle,classname,windowtext,rectangle) of each child windows? Maybe in a vector list?


Solution

  • For your first question, you may have a look here.

    For your second question, you may define a structure with the fields you need, e.g.

    #include <iostream>
    #include <windows.h>
    #include <vector>
    
    struct MyWindow {
     HWND handle_;
     std::string name_;
     std::string text_;
     RECT rect_;
     MyWindow(HWND handle, const std::string& name, const std::string& text, RECT rect): handle_{handle}, name_{name}, text_{text}, rect_{rect}{}
    };
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
        char name[100];
        char text[100];
        RECT rect{0};
    
        GetClassNameA(hwnd,name, sizeof(name));
        GetWindowTextA(hwnd,text,sizeof(text));
        GetWindowRect(hwnd, &rect);
    
        std::vector<MyWindow>* myVec = reinterpret_cast<std::vector<MyWindow>*>(lParam);
    
        if (myVec) {
          myVec->emplace_back(MyWindow(hwnd, std::string(name), std::string(text), rect));
        } else {
          // Pointer to vector is NULL, handle accordingly
         return FALSE;
        }
    
        return TRUE;
    }
    
    int main()
    {
        POINT pt;
        Sleep(3000);
    
        std::vector<MyWindow> myChildWindows;
    
        GetCursorPos(&pt);
        HWND hwnd = WindowFromPoint(pt);
        HWND hwndParent = GetParent(hwnd);
    
        EnumChildWindows(hwndParent, EnumWindowsProc, reinterpret_cast<LPARAM>(&myChildWindows));
    
        for (const auto & childWindow: myChildWindows) {
                std::cout <<"Window name : "<< childWindow.name_ << std::endl;
                std::cout <<"Class name  : "<< childWindow.text_<< std::endl;
                std::cout <<"hwnd        : "<< childWindow.handle_<< std::endl;
                std::cout << "Rect: " << childWindow.rect_.left << "/" << childWindow.rect_.right << std::endl;
                std::cout << "---" << std::endl;
        }
    
        system("PAUSE");
        return 0;
    }
    

    EDIT

    I added a bit more code and explanation. This example should compile and run just fine.

    std::vector is a sequence container that encapsulates dynamic size arrays 1.

    When you declare myChildWindows in the main function, it is initialized to an empty vector, that can contain Objects of Type MyWindow. You can add and remove objects to that vector dynamically, i.e. you do not have to specify the size of the vector at compile time, like for example with an array. We then pass the pointer to this vector to your callback EnumWindowsProc. In this callback, we use this pointer to add Objects of type MyWindow to the vector. When EnumChildWindows returns, we can have a look at our vector by printing every object contained in the vector.