如何在 C++ 中显示 window 并在 Windows 中作为参数给出的名称

How can I show a window with the a name given as parameter in Windows in C++

我想让我的软件可用于 Linux 和 Windows(Linux 已经可用)。现在我还需要一些功能,所以我也可以 运行 Windows 上的软件。

我目前正在尝试使用 EnumWindows() 函数获取 window 名称,然后在前台显示 window(与参数匹配)。

static BOOL CALLBACK setWindowFocus(HWND hWnd, LPARAM lparam) {
    int length = GetWindowTextLength(hWnd);
    char* buffer = new char[length + 1];
    GetWindowText(hWnd, buffer, length + 1);
    std::string windowTitle(buffer);

    // List visible windows with a non-empty title
    if (IsWindowVisible(hWnd) && length != 0) {
        // Check if it is the right Windowshandle
        if ( windowTitle.compare(programname) == 0 ) <-- programname is a static variable
        {
            // Set application to the foreground
            SetForegroundWindow(hWnd);
        }
    }
    return TRUE;
}

此外,我用它来创建变量:

std::string programname;

这样称呼它:

static void setWindowFocus(std::string programname)
{
    std::cout << "Setting focus to window." << std::endl;
    tempsavedProgramname=programname;
    EnumWindows(setWindowFocus, NULL);
}

只要在 main() 中,就可以正常工作。但是,我想把它放在一个额外的 class 和一些其他功能中(如果可能的话,我也想删除 static 变量)。

有什么方法可以将 EnumWindows() 函数与匿名函数一起使用吗?

我可以使用类似这样的方法将字符串传递给函数吗:

EnumWindows(setWindowFocus, reinterpret_cast<LPARAM>(stringvariable));

或者,我可以通过其他方式来实现我的目标吗?

包括我用于代码的内容:

Windows.h
winuser.h
string
iostream

希望我没有忘记一个。

是的,您可以使用 LPARAMstring 变量传递到您的回调中,例如:

static BOOL CALLBACK setWindowFocus(HWND hWnd, LPARAM lparam) {
    std::string &programname = *reinterpret_cast<std::string*>(lparam);

    int length = GetWindowTextLength(hWnd);
    char* buffer = new char[length + 1];
    GetWindowText(hWnd, buffer, length + 1);
    std::string windowTitle(buffer);
    delete[] buffer; // <-- ADD THIS!

    /* I would use this instead:
    int length = GetWindowTextLength(hWnd);
    std::string windowTitle(length+1, '[=10=]');
    windowTitle.resize(GetWindowText(hWnd, &windowTitle[0], length + 1));
    */

    // List visible windows with a non-empty title
    if (IsWindowVisible(hWnd) && (length != 0)) {
        // Check if it is the right Windowshandle
        if (windowTitle == programname)
        {
            // Set application to the foreground
            SetForegroundWindow(hWnd);
            return FALSE;
        }
    }
    return TRUE;
}
static void setWindowFocus(std::string programname)
{
    std::cout << "Setting focus to window." << std::endl;
    EnumWindows(setWindowFocus, reinterpret_cast<LPARAM>(&programname));
}

是的,您可以使用 C++11 lambda 进行回调,而不是 static class 方法,但是 如果您使用 非捕获 lambda,它可以隐式转换为函数指针(捕获 lambda 不能)。幸运的是,LPARAM 使这种可能性成为可能,例如:

static void setWindowFocus(std::string programname)
{
    std::cout << "Setting focus to window." << std::endl;
    EnumWindows(
        [](HWND hWnd, LPARAM lparam) -> BOOL {
            std::string &programname = *reinterpret_cast<std::string*>(lparam);
            // ...
        },
        reinterpret_cast<LPARAM>(&programname)
    );
}

现在,话虽这么说,但有一个更简单的解决方案 - 因为您已经知道要查找的确切 window 文本,所以您可以使用 FindWindow() 而不是 EnumWindows() ,例如:

static void setWindowFocus(std::string programname)
{
    std::cout << "Setting focus to window." << std::endl;
    HWND hWnd = FindWindowA(NULL, programname.c_str());
    if (hWnd != NULL) {
        // Set application to the foreground
        SetForegroundWindow(hWnd);
    }
}

这是包含在 class

中的回调
class enum_windows {
protected:
    virtual BOOL call_back(HWND hwnd)  {
        // Your code here
        return TRUE;
    }
public:
    void start() {
        EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
            enum_windows * obj = reinterpret_cast<enum_windows *>(lParam);
            return obj->call_back(hwnd);
        }, reinterpret_cast<LPARAM>(this));
    }
};

(您已经接受了答案 - 我打字慢)。无论如何我都会把它留在这里。