Find if window is displayed or not

Viewed 1196

Part of the project that I'm working on involves finding every window that is displayed. I use the EnumWindows() function to go through each window and filter out ones that do not return true on IsWindowVisible(). But even still, I get some weird results which include processes that don't have any visible windows. This is the code:

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

And this is the result:

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

All of the processes listed below those belonging to Visual Studio have no windows open, I have not even launched them since my computer's startup. I did some digging, and it turns out that these are considered background processes by the Task Manager (except for Program Manager, which I assume is a core process to the OS)

Is there a way to exclude these from my results?

2 Answers

I've had the same issue with enumerating windows on Windows 10 with EnumWindows: sometimes, Metro/Modern apps will be listed as running even if they aren't. Solution? Check if the window has the DWM cloaked attribute

Here's my EnumProc (the LPARAM is a 32-bit pointer to an opened file handle for writing titles to; adjust as necessary per your application's needs):

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

I think you are listing all windows in the system but maybe some of them are not in your current desktop. It was explained here: Filtering/Parsing list produced from EnumWindows in C++

Another case of non visible windows is when it is outside screen coordinate, you can intersect Window and Screen Rects.

Related