c++ - 查找窗口是否显示

标签 c++ winapi

我正在处理的部分项目涉及查找显示的每个窗口。我使用 EnumWindows() 函数遍历每个窗口并过滤掉那些在 IsWindowVisible() 上不返回 true 的窗口。但即便如此,我还是得到了一些奇怪的结果,其中包括没有任何可见窗口的进程。这是代码:

int main()
{
    EnumWindows(callback, NULL);
    cin.get();
    return 0;
}

BOOL CALLBACK callback(HWND hWnd, LPARAM lParam)
{
    wchar_t windowTitle[256];
    GetWindowText(hWnd, windowTitle, sizeof(windowTitle));

    int length = ::GetWindowTextLength(hWnd);
    wstring title(&windowTitle[0]);
    if (!IsWindowVisible(hWnd) || length == 0) return TRUE;

    WINDOWPLACEMENT wp;
    GetWindowPlacement(hWnd, &wp);
    cout << string(title.begin(), title.end()) << endl;

    return TRUE;
}

这是结果:

C:\Users\qjohh\Documents\Visual Studio 2017\Projects\ConsoleApplication1\Debug\ConsoleApplication1.exe
ConsoleApplication1 (Running) - Microsoft Visual Studio
Settings
Settings
Movies & TV
Movies & TV
Calculator
Calculator
Microsoft Edge
Microsoft Edge
Netflix
Netflix
Microsoft Store
Microsoft Store
Program Manager

下面列出的所有属于 Visual Studio 的进程都没有打开窗口,自从我的计算机启动以来我什至没有启动它们。我做了一些挖掘,结果发现这些被任务管理器视为后台进程(Program Manager 除外,我认为它是操作系统的核心进程)

有没有办法从我的结果中排除这些?

最佳答案

我在使用 EnumWindows 枚举 Windows 10 上的窗口时遇到了同样的问题:有时,Metro/Modern 应用程序会被列为正在运行,即使它们没有运行。解决方案?检查窗口是否有DWM cloaked属性

这是我的 EnumProc(LPARAM 是一个 32 位指针,指向一个打开的文件句柄,用于写入标题;根据应用程序的需要进行必要的调整):

#include <Windows.h>
#include <strsafe.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")

#define MAX_TITLE_LEN 100

BOOL CALLBACK EnumProc(HWND hWnd, LPARAM lParam)
{
    LONG lStyle = GetWindowLongPtrW(hWnd, GWL_STYLE);

    if ((lStyle & WS_VISIBLE) && (lStyle & WS_SYSMENU))
    {
        CONST CHAR CRLF[2] = { '\r', '\n' };
        HANDLE hFile = *(HANDLE *)lParam;
        DWORD dwWritten;
        CHAR szTitle[MAX_TITLE_LEN];
        HRESULT hr;
        UINT uLen;
        INT nCloaked;

        // On Windows 10, ApplicationFrameWindow may run in the background and
        // WS_VISIBLE will be true even if the window isn't actually visible,
        // for various UWP apps. I don't know of any method for predicting when 
        // this will happen, and for which app(s).
        // 
        // The only way to test if a window is actually *visible* in this case
        // is to test for the DWM CLOAKED attribute.
        DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, &nCloaked, sizeof(INT));
        if (nCloaked)
            return TRUE;

        GetWindowTextA(hWnd, szTitle, MAX_TITLE_LEN);
        hr = StringCbLengthA(szTitle, MAX_TITLE_LEN, &uLen);
        if (SUCCEEDED(hr) && uLen > 0)
        {
            SetFilePointer(hFile, 0, NULL, FILE_END);
            WriteFile(hFile, szTitle, uLen, &dwWritten, NULL);
            WriteFile(hFile, CRLF, 2, &dwWritten, NULL);
        }
    }
    return TRUE;
}

关于c++ - 查找窗口是否显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53321963/

相关文章:

c++ - 你能在c中的同一个语句中的同一个变量上有一个递增器和一个递减器吗

c++ - 与模板参数解耦,无需动态多态性

c - 当 DPI 设置为 150% 时关闭 Aero (Windows 7),全屏窗口仅覆盖任务栏

c++ - CWnd::GetParent 导致异常

c++ - 我不明白我为这个程序得到的输出。

c++ - MEMORY_BASIC_INFORMATION.AllocationBase IMAGE_DOS_HEADER 有效性检查

c++ - CryptDecrypt() 无法解密某些 block C++

c++ - wglCreateContextAttribsARB 在 NVIDIA 硬件上失败

c++ - 打开转义文件时出现意外行为 :///URL in IE

c++ - O(1)内存中的随机序列迭代?