7

The Microsoft WinAPI documentation appears to suggest that user32.dll contains a function called GetNextWindow() which supposedly allows one to enumerate open windows in their Z order by calling this function repeatedly.

Pinvoke usually gives me the necessary DllImport statement to use WinAPI functions from C#. However, for GetNextWindow() it doesn't have an entry. So I tried to construct my own:

[DllImport("user32.dll")]
static extern IntPtr GetNextWindow(IntPtr hWnd, uint wCmd);

Unfortunately, when trying to call this, I get an EntryPointNotFoundException saying:

Unable to find an entry point named 'GetNextWindow' in DLL 'user32.dll'.

This seems to apply only to GetNextWindow(); other functions that are listed on Pinvoke are fine. I can call GetTopWindow() and GetWindowText() without throwing an exception.

Of course, if you can suggest a completely different way to enumerate windows in their current Z order, I'm happy to hear that too.

Jon B
  • 51,025
  • 31
  • 133
  • 161
Timwi
  • 65,159
  • 33
  • 165
  • 230

2 Answers2

26

GetNextWindow() is actually a macro for GetWindow(), rather than an actual API method. It's for backward compatibility with the Win16 API.

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

enum GetWindow_Cmd : uint {
    GW_HWNDFIRST = 0,
    GW_HWNDLAST = 1,
    GW_HWNDNEXT = 2,
    GW_HWNDPREV = 3,
    GW_OWNER = 4,
    GW_CHILD = 5,
    GW_ENABLEDPOPUP = 6
}

(From Pinvoke.net)

David Brown
  • 35,411
  • 11
  • 83
  • 132
  • 1
    Right. And this thread (http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/afa69b03-5425-4124-b9b4-f8c6cb9bcc9c) shows how to use it to get "next" – hometoast Apr 28 '09 at 14:37
  • What's the point of GetNextWindow() besides confusing poor pinvokers if it takes the same arguments as GetWindow() then? – ASA Feb 27 '14 at 12:51
  • 1
    It's included for backwards compatibility with old code. As for why they chose to implement it using a macro, I would guess that it's to eliminate an intermediate function call (back when compilers weren't as good at optimization), but I don't know for sure. That's probably a good question for [Raymond Chen](http://blogs.msdn.com/b/oldnewthing/). – David Brown Feb 27 '14 at 19:53
2

GetNextWindow is a c++ macro that calls GetWindow, so you cannot call it from .NET. Call GetWindow instead.

From MSDN:

Using this function is the same as calling the GetWindow function with the GW_HWNDNEXT or GW_HWNDPREV flag set

Richard Szalay
  • 83,269
  • 19
  • 178
  • 237