获取C++中所有打开窗口的列表并存储它们

获取C++中所有打开窗口的列表并存储它们,c++,windows,winapi,C++,Windows,Winapi,我目前正在尝试获取所有打开窗口的列表,并将它们存储在一个向量中。我一直在关注代码,所以解决方案可能非常简单,但如果没有我想要避免的全局变量,我似乎无法完成它 代码如下: #include "stdafx.h" #include "json.h" #include <algorithm> using namespace std; vector<string> vec; BOOL CALLBACK speichereFenster(HWND hwnd, LPARAM

我目前正在尝试获取所有打开窗口的列表,并将它们存储在一个向量中。我一直在关注代码,所以解决方案可能非常简单,但如果没有我想要避免的全局变量,我似乎无法完成它

代码如下:

#include "stdafx.h"
#include "json.h"
#include <algorithm>  

using namespace std;
vector<string> vec;


BOOL CALLBACK speichereFenster(HWND hwnd, LPARAM substring){
    const DWORD TITLE_SIZE = 1024;
    TCHAR windowTitle[TITLE_SIZE];

    GetWindowText(hwnd, windowTitle, TITLE_SIZE);
    int length = ::GetWindowTextLength(hwnd);

    wstring temp(&windowTitle[0]);
    string title(temp.begin(), temp.end());



    if (!IsWindowVisible(hwnd) || length == 0 || title == "Program Manager") {
        return TRUE;
    }

    vec.push_back(title);

    return TRUE;
}

int main() {
    EnumWindows(speichereFenster, NULL);
    cin.get();
    return 0;
}
我想在向量中存储所有标题,但我不知道如何存储,因为我无法将向量传递到函数中

谢谢

要记录的第二个参数lParam为:

要传递给回调函数的应用程序定义的值

只需将容器传递给API调用:

int main() {
    std::vector<std::wstring> titles;
    EnumWindows(speichereFenster, reinterpret_cast<LPARAM>(&titles));
    // At this point, titles if fully populated and could be displayed, e.g.:
    for ( const auto& title : titles )
        std::wcout << L"Title: " << title << std::endl;
    cin.get();
    return 0;
}
并在回调中使用它:

BOOL CALLBACK speichereFenster(HWND hwnd, LPARAM lParam){
    const DWORD TITLE_SIZE = 1024;
    WCHAR windowTitle[TITLE_SIZE];

    GetWindowTextW(hwnd, windowTitle, TITLE_SIZE);

    int length = ::GetWindowTextLength(hwnd);
    wstring title(&windowTitle[0]);
    if (!IsWindowVisible(hwnd) || length == 0 || title == L"Program Manager") {
        return TRUE;
    }

    // Retrieve the pointer passed into this callback, and re-'type' it.
    // The only way for a C API to pass arbitrary data is by means of a void*.
    std::vector<std::wstring>& titles =
                              *reinterpret_cast<std::vector<std::wstring>*>(lParam);
    titles.push_back(title);

    return TRUE;
}
注:

给出的代码使用std::wstring代替std::string。这是必要的,以便可以表示整个字符集。 正如所写的,代码是不正确的。存在不可见的代码路径,它们没有明确定义的含义。Windows API严格公开为C接口。因此,它不理解C++异常。特别是对于回调,从不让C++异常穿越未知的堆栈帧是至关重要的。要修复代码,请应用以下更改: [C++11 only]标记回调。 将整个回调封装在一个块中,并适当地处理任何异常。 (C++ 11)只有C++ 11,通过在调用站点上传递和调用,可以跨越未知堆栈帧传递C++异常。 要记录的第二个参数lParam为:

要传递给回调函数的应用程序定义的值

只需将容器传递给API调用:

int main() {
    std::vector<std::wstring> titles;
    EnumWindows(speichereFenster, reinterpret_cast<LPARAM>(&titles));
    // At this point, titles if fully populated and could be displayed, e.g.:
    for ( const auto& title : titles )
        std::wcout << L"Title: " << title << std::endl;
    cin.get();
    return 0;
}
并在回调中使用它:

BOOL CALLBACK speichereFenster(HWND hwnd, LPARAM lParam){
    const DWORD TITLE_SIZE = 1024;
    WCHAR windowTitle[TITLE_SIZE];

    GetWindowTextW(hwnd, windowTitle, TITLE_SIZE);

    int length = ::GetWindowTextLength(hwnd);
    wstring title(&windowTitle[0]);
    if (!IsWindowVisible(hwnd) || length == 0 || title == L"Program Manager") {
        return TRUE;
    }

    // Retrieve the pointer passed into this callback, and re-'type' it.
    // The only way for a C API to pass arbitrary data is by means of a void*.
    std::vector<std::wstring>& titles =
                              *reinterpret_cast<std::vector<std::wstring>*>(lParam);
    titles.push_back(title);

    return TRUE;
}
注:

给出的代码使用std::wstring代替std::string。这是必要的,以便可以表示整个字符集。 正如所写的,代码是不正确的。存在不可见的代码路径,它们没有明确定义的含义。Windows API严格公开为C接口。因此,它不理解C++异常。特别是对于回调,从不让C++异常穿越未知的堆栈帧是至关重要的。要修复代码,请应用以下更改: [C++11 only]标记回调。 将整个回调封装在一个块中,并适当地处理任何异常。 (C++ 11)只有C++ 11,通过在调用站点上传递和调用,可以跨越未知堆栈帧传递C++异常。
获取所有具有非空标题的可见窗口的简单代码

对于HWND,HWND=GetTopWindowNULL;hwnd!=无效的hwnd=GetNextWindowhwnd,GW\u HWNDNEXT { 如果!IsWindowVisiblehwnd 持续 int length=GetWindowTextLengthWnd; 如果长度==0 持续 字符*标题=新字符[长度+1]; GetWindowTexthwnd,标题,长度+1; 如果title==程序管理器 持续
std::cout获取所有非空标题可见窗口的简单代码

对于HWND HWND=GetTopWindowNULL;HWND!=NULL;HWND=GetNextWindowhwnd,GW_hwndnnext { 如果!IsWindowVisiblehwnd 持续 int length=GetWindowTextLengthWnd; 如果长度==0 持续 字符*标题=新字符[长度+1]; GetWindowTexthwnd,标题,长度+1; 如果title==程序管理器 持续
std::无法通过lParam第2个参数传递向量的地址,并将其强制转换回回调中。您需要使用reinterpret_强制转换锤在EnumWindowswstring temp&windowTitle[0]的第二个参数中传递指向数据的指针尽管您假设,这不是字符编码转换。它是一个数据删除设备。而且不需要。在Windows应用程序中只使用宽字符串。相关:我不同意用C++中的C样式方法是一个罪恶。许多人错误地声称重新解释。在C++的C++规范下,C编程风格是很好的定义,最好的做法是使用更少的输入方法。C++中的ASCII不是一个罪恶,事实上,我利用仿生仿生的计算机模拟技术,以便更容易理解下一个基因。定量系统。我的Unicode处理是通过其他更快的机制完成的。通过lParam第2个参数传递向量的地址,并将其强制转换回回调中。您需要使用reinterpret_强制转换锤在EnumWindowswstring temp&windowTitle[0]的第二个参数中传递指向数据的指针尽管您假设,这不是字符编码转换。它是一个数据删除设备。而且不需要。在Windows应用程序中只使用宽字符串。相关:我不同意用C++中的C样式方法是一个罪恶。许多人错误地声称重新解释。在C++中,C++是正确的编程方法,在C++规范和最佳实践中,C编程风格被很好地定义了。
tice将使用打字较少的方法。C++中的ASCII不是一个罪恶,事实上,我利用仿生仿生技术模仿计算机技术,以便创造更容易理解的下一代系统。我的Unicode处理是通过其他更快的机制完成的。可以通过动态分配windowTitle而不是将其限制为1023个字符来改进它。@zett42:有无数种方法可以改进此代码。我集中精力回答这个问题:如何将数据传递给回调并返回?@MarcoVogt:从wchar\u t到char的“转换”不是转换。这是一个破坏性的操作,不会保留初始数据。四分之一的代码单元不受影响,另四分之一的代码单元以不希望的方式被重新解释,剩下的一半被抛出。如果您使用的是Windows API,请在UTF-16的所有位置使用宽字符串。如果您需要与外部世界的文件、网络套接字、服务网页进行交互,请将其转换为适当的字符编码,例如UTF-8。@zett42您将如何动态分配windowTitle?@kay:我相信这条评论背后的动机是,正如所写的,代码通常会过度分配内存。不过,这是一种权衡。在堆栈上分配2048字节是便宜的,通常甚至是免费的,而堆分配是我们通常执行的最昂贵的操作之一。另一方面,虽然通常有大量的堆内存可用,但在使用VisualStudio时,默认情况下堆栈内存限制为1MB。也就是说,有一个重要的改进需要做,那就是使代码正确。可以通过动态分配windowTitle来改进,而不是将其限制为1023个字符。@zett42:有无数种方法可以改进此代码。我集中精力回答这个问题:如何将数据传递给回调并返回?@MarcoVogt:从wchar\u t到char的“转换”不是转换。这是一个破坏性的操作,不会保留初始数据。四分之一的代码单元不受影响,另四分之一的代码单元以不希望的方式被重新解释,剩下的一半被抛出。如果您使用的是Windows API,请在UTF-16的所有位置使用宽字符串。如果您需要与外部世界的文件、网络套接字、服务网页进行交互,请将其转换为适当的字符编码,例如UTF-8。@zett42您将如何动态分配windowTitle?@kay:我相信这条评论背后的动机是,正如所写的,代码通常会过度分配内存。不过,这是一种权衡。在堆栈上分配2048字节是便宜的,通常甚至是免费的,而堆分配是我们通常执行的最昂贵的操作之一。另一方面,虽然通常有大量的堆内存可用,但在使用VisualStudio时,默认情况下堆栈内存限制为1MB。这就是说,有一个重要的改进需要做,使代码正确。