【问题标题】:How to get a list of Window Rectangle from EnumChildWindow and store them?如何从 EnumChildWindow 获取 Window Rectangle 列表并存储它们?
【发布时间】:2020-10-08 05:47:45
【问题描述】:

我使用了EnumChildWindows,我可以得到所有子窗口的HandleClassNameWindowText。但我也想得到所有子窗口的Rectangle。有可能吗?

这是我的代码:

#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;
}

另外,如何存储每个子窗口的所有数据(句柄、类名、窗口文本、矩形)?也许在向量列表中?

【问题讨论】:

    标签: c++ vector rectangles enumerate childwindow


    【解决方案1】:

    第一个问题,你可以看看here

    对于第二个问题,您可以定义一个包含所需字段的结构,例如

    #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;
    }
    

    编辑

    我添加了更多代码和解释。此示例应该可以正常编译和运行。

    std::vector是一个序列容器,封装了动态大小的数组1

    当你在 main 函数中声明 myChildWindows 时,它被初始化为一个空向量,可以包含 MyWindow 类型的对象。您可以动态地向该向量添加和删除对象,即您不必在编译时指定向量的大小,例如使用数组。然后我们将指向该向量的指针传递给您的回调EnumWindowsProc。在此回调中,我们使用此指针将 MyWindow 类型的对象添加到向量中。当EnumChildWindows 返回时,我们可以通过打印向量中包含的每个对象来查看我们的向量。

    【讨论】:

    • 您好,对于第一个问题,我可以使用GetWindowRect 获取我仅指向的窗口的Rect。我正在尝试将它们显示为与其他列表相似的列表(窗口名、类名、hwnd)。对于第二个问题,是否可以使其更详细?很抱歉,我是 std::vector 的新手,我不确定如何实施您的示例。谢谢
    • 您好,我编译失败,对于 MyWindow(HWND handle, const std::string&amp; name, const std::string&amp; text, RECT rect): handle_{handle}, name_{name}, text_{text}, rect_{rect}{} } 错误是语法错误:','unexpected token(s ) 前面的 '{';跳过明显的函数体 For RECT rect{0}; 错误是 'rect' : 局部函数定义是非法的 。还有其他错误更多...
    • 你是怎么编译的?
    • 我正在使用 VisualStudio Win32 Project 编译它
    • 你确定你的代码没有错别字吗?我使用 cygwin 和 Visual Studio Code 编译它,它两次都有效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 2012-12-17
    相关资源
    最近更新 更多