user3183230
user3183230

Reputation: 11

Issue when enumerating windows

I'm having a problem when trying to run the following code:

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

When I run this code nothing is output to the screen almost as if the program is not attached. I tried running it under a console and windows subsystem in VS2013.

Upvotes: 1

Views: 279

Answers (2)

Brandon
Brandon

Reputation: 23515

I assume you're trying to find the "Main" window from the ProcessID.. In that case, this MAY help:

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

Upvotes: 0

cf-
cf-

Reputation: 8866

According to the GetCurrentProcessId docs, the API

Retrieves the process identifier of the calling process.

GetWindowThreadProcessId, on the other hand,

Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.

The return value is the identifier of the thread that created the window.

So looking at your call:

pid = GetWindowThreadProcessId(hwnd, NULL);

You're actually getting back a thread ID, not a process ID. So when you compare pid to id, you're comparing a process ID and a thread ID, and that's just not going to work. Try this instead:

GetWindowThreadProcessId(hwnd, &pid);

(Note: I can't actually test whether this works, since EnumWindows requires a top-level window to enumerate and I ran this as a console app. Let me know if this answer doesn't work for you and I'll delete it.)

(As a second note, you don't need to use NULL anymore, even for WinAPI stuff like HWND. nullptr will work perfectly fine.)

Upvotes: 3

Related Questions