枚举子窗口

发布于 2024-10-15 03:42:05 字数 2997 浏览 13 评论 0原文

几周前,这里有人帮助我编写了一个枚举所有主窗口的类。

今天我尝试修改该类以枚举特定父窗口的所有子窗口。

这是头文件:

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

我通过以下方式调用该函数:

 std::vector<Handles::child_data> windows = Handles().enum_windows().get_results(); //Enumerate all visible windows and store handle and caption in "windows"

问题是:

我不太确定如何将父窗口的句柄传递给标头中的回调函数。感觉我已经尝试了一切,但我总是会遇到这样的错误:变量 hwnd 没有在 ... 中声明

。问题是我不能 100% 理解这个类。我确实弄清楚的事情已发表评论。

感谢您的帮助!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

策马西风 2024-10-22 03:42:05

而不是调用 EnumWindows ,它枚举屏幕上的所有顶级窗口,您可以调用 EnumChildWindows 枚举给定父窗口的子窗口。为此,您可以将 enum_windows 重载添加到 Handles 类中:

Handles& enum_windows(HWND hParentWnd) 
{
    stuff.clear();                                  //clean up
    EnumChildWindows(hParentWnd, Handles_WndEnumProc, reinterpret_cast<LPARAM>(this));
    return *this;
}

EnumChildWindowsWNDENUMPROC 的错误名称。代码>.我建议将其重命名为更独特的名称,例如 Handles_WndEnumProc

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文