【问题标题】:Issue when enumerating windows枚举窗口时的问题
【发布时间】:2014-04-07 22:56:11
【问题描述】:

我在尝试运行以下代码时遇到问题:

#include "header.h"

int main()
{
    id = GetCurrentProcessId();
    EnumWindows(hEnumWindows, NULL);

    Sleep(5000);
    //MoveWindow(hThis, 450, 450, 100, 100, TRUE);

    system("pause");
    return 0;
}

//header.h

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>

using namespace std;

DWORD id = 0;
HWND hThis = NULL;

BOOL CALLBACK hEnumWindows(HWND hwnd, LPARAM lParam)
{
    DWORD pid = 0;
    pid = GetWindowThreadProcessId(hwnd, NULL);

    if (pid == id)
    {
        hThis = GetWindow(hwnd, GW_OWNER);
        if (!hThis)
        {
            cout << "Error getting window!" << endl;
        }
        else
        {
            char *buffer = nullptr;
            int size = GetWindowTextLength(hThis);
            buffer = (char*)malloc(size+1);
            if (buffer != nullptr)
            {
                GetWindowText(hThis, buffer, size);
                cout << pid << ":" << buffer << endl;
                free(buffer);
            }
        }
    }

    return TRUE;
}

当我运行这段代码时,几乎没有任何东西输出到屏幕上,就像没有附加程序一样。我尝试在 VS2013 的控制台和 Windows 子系统下运行它。

【问题讨论】:

  • @RobertHarvey 我看到了 C 风格的演员表,所以希望不是 C++ ;)
  • @Cyber​​:我看到像 cout &lt;&lt; pid &lt;&lt; 这样的东西让我相信它是 C++。
  • 这是在 VS2013 上使用 C++ 编译器编译的,我更喜欢 malloc 而不是 new,这就是使用它的原因。

标签: c++ windows winapi


【解决方案1】:

根据GetCurrentProcessId docs,API

检索调用进程的进程标识符。

另一方面,GetWindowThreadProcessId

检索创建指定窗口的线程的标识符,以及创建窗口的进程的标识符(可选)。

返回值是创建窗口的线程的标识符。

所以看看你的电话:

pid = GetWindowThreadProcessId(hwnd, NULL);

您实际上得到的是线程 ID,而不是进程 ID。因此,当您将pidid 进行比较时,您是在比较进程ID 和线程ID,而这是行不通的。试试这个:

GetWindowThreadProcessId(hwnd, &pid);

(注意:我实际上无法测试这是否有效,因为EnumWindows 需要一个顶级窗口来枚举,我将它作为控制台应用程序运行。如果这个答案对你不起作用,请告诉我我会删除它。)

(作为第二个注意事项,您不再需要使用 NULL,即使对于像 HWND 这样的 WinAPI 内容。nullptr 也可以正常工作。)

【讨论】:

  • 您可以在控制台应用程序中调用EnumWindows()。控制台应用程序可以调用 Win2 API 函数,EnumWindows() 枚举所有顶级窗口,无论调用它的应用程序类型如何。您不需要自己的顶级窗口即可调用EnumWindows()
  • @RemyLebeau 对,但是看看 op 的代码还在做什么——它正在检查顶级窗口的 pid 是否与该程序的 pid 匹配。由于我只是使用了一个又快又脏的控制台应用程序进行测试,因此我的应用程序中没有可用的顶级窗口,因此我无法正确执行 pid 检查。
【解决方案2】:

我假设您正在尝试从 ProcessID 中找到“主”窗口。在这种情况下,这可能会有所帮助:

#include "stdafx.h"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>

struct WindowHandleStructure
{
    unsigned long PID;
    HWND WindowHandle;
};

BOOL CALLBACK EnumWindowsProc(HWND WindowHandle, LPARAM lParam)
{
    unsigned long PID = 0;
    WindowHandleStructure* data = reinterpret_cast<WindowHandleStructure*>(lParam);

    GetWindowThreadProcessId(WindowHandle, &PID);
    if (data->PID != PID || (GetWindow(WindowHandle, GW_OWNER) && !IsWindowVisible(WindowHandle)))
    {
        return TRUE;
    }
    data->WindowHandle = WindowHandle;
    return FALSE;
}

HWND FindMainWindow(unsigned long PID)
{
    WindowHandleStructure data = { PID, nullptr };
    EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&data));
    return data.WindowHandle;
}

int main()
{
    HWND Window = FindMainWindow(GetCurrentProcessId());

    std::wstring Buffer(GetWindowTextLength(Window) + 1, L'\0');
    GetWindowText(Window, &Buffer[0], Buffer.size());

    std::wcout << Buffer.c_str() << L"\n";

    system("pause");
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多