4

The code worked all along. Somehow I manage to get Visual C++ Express not hit the break point on the final return statement and it appeared to run for ever.

In the example code bellow EnumWindows enumerates infinitely. How can one make it stop after all windows has been enumerated.

#include <Windows.h>

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) {
    TCHAR buff[255];

    if (IsWindowVisible(hWnd)) {
        GetWindowText(hWnd, (LPWSTR) buff, 254);
        printf("%S\n", buff);
    }
    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[]) {
    EnumWindows(EnumWindowsProc, 0);
    return 0;
}
s5804
  • 995
  • 3
  • 12
  • 14
  • Is your project using UNICODE? Also, what platform/VS version are you using? Also why are you using '%S'? – dirkgently Apr 28 '09 at 13:53
  • Platform XP SP2. GetWindowText seems to return wide string. Used %S to print wide string. – s5804 Apr 28 '09 at 13:58
  • But what exactly gets printed??? –  Apr 28 '09 at 15:30
  • Since you are using TCHAR, you should use _tprintf_s, which expecto %s to be a unicode string. – Ismael Apr 28 '09 at 16:26
  • We had similar problem where EnumWindows() hangs, but it turned out to be because we use WaitForSingleObject(h, INFINITE), which block message pump in main thread, thus whenever EnumWindowsProc() run for own app, then it hangs. We solved it by implementing own message pump around WaitForSingleObject(h, 50) – Thomas3D Oct 12 '10 at 13:19

4 Answers4

8

Your code works for me, once I removed the wide-character stuff and added #include <stdio.h> to get the printf() declaration. What output does it produce on your system?

The code that works for me is:

#include <windows.h>
#include <stdio.h>

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) {
    char buff[255];

    if (IsWindowVisible(hWnd)) {
        GetWindowText(hWnd, (LPSTR) buff, 254);
        printf("%s\n", buff);
    }
    return TRUE;
}

int main() {
    EnumWindows(EnumWindowsProc, 0);
    return 0;
}
ColdCat
  • 1,192
  • 17
  • 29
  • 6
    Checking with IsWindowVisible works because some invisible windows can hang the call to GetWindowText. – pcunite Jun 04 '12 at 22:03
  • @pcunite A window's visibility does not affect `GetWindowText()`. And in fact, if a window belongs to another process, [`GetWindowText()` **cant** hang](https://blogs.msdn.microsoft.com/oldnewthing/20030821-00/?p=42833), by design. The only way it can hang is if the window belongs to your own process and the window's message queue is not being processed. That would be a bug in your own code. – Remy Lebeau Jan 20 '17 at 09:07
3

EnumWindowsProc should never run infinitely.

It should run until:

  • Your callback returns FALSE
  • There are no more top level windows to enumerate

So I suspect it appears to be running infinitely for you because of memory corruption or a memory access violation.

Your printf should be using %s not %S.

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) {
    TCHAR buff[255];

    if (IsWindowVisible(hWnd)) {
        GetWindowText(hWnd, (LPWSTR) buff, 254);
        printf("%s\n", buff);//<--- %s means use TCHAR* which is WCHAR* in your case
    }
    return TRUE;
}

Also you shouldn't need to be casting your buff as a LPWSTR. If your buff is somehow a CHAR buffer then you need to compile with the Unicode character set.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
2

From the documentation:

EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.

To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.

Community
  • 1
  • 1
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • It will stop when it reaches the last top-level window, no matter what value gets returned. –  Apr 28 '09 at 13:44
1

hmm, i don't get why it would. i ran it and it worked just fine. it displayed all of the windows i have and then stopped. enumWindows will stop when either the enumWindowsProc returns false (you have it coded to always return true) or when it runs out of top-level windows to enumerate. -don

Don Dickinson
  • 6,200
  • 3
  • 35
  • 30