2006-05-20

Getting a list of all the open windows

Here's some code you can use to get a list of all the open windows. Actually, you get a dictionary where each item is a KeyValuePair where the key is the handle (hWnd) of the window and the value is its title.
using HWND = IntPtr;
/// <summary>Contains a method to get all the open windows.</summary>
public static class OpenWindowGetter {
/// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary> /// <returns>A dictionary that contains the handle and title of all the open windows.</returns>
public static IDictionary<HWND, string> GetOpenWindows() { HWND lShellWindow = GetShellWindow(); Dictionary<HWND, string> lWindows = new Dictionary<HWND, string>(); EnumWindows(delegate(HWND hWnd, int lParam) { if (hWnd == lShellWindow) return true; if (!IsWindowVisible(hWnd)) return true; int lLength = GetWindowTextLength(hWnd); if (lLength == 0) return true; StringBuilder lBuilder = new StringBuilder(lLength); GetWindowText(hWnd, lBuilder, lLength + 1); lWindows[hWnd] = lBuilder.ToString(); return true; }, 0); return lWindows; } delegate bool EnumWindowsProc(HWND hWnd, int lParam); [DllImport("USER32.DLL")] static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); [DllImport("USER32.DLL")] static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount); [DllImport("USER32.DLL")] static extern int GetWindowTextLength(HWND hWnd); [DllImport("USER32.DLL")] static extern bool IsWindowVisible(HWND hWnd); [DllImport("USER32.DLL")] static extern IntPtr GetShellWindow(); }
And here's some code that uses it:
foreach(KeyValuePair<IntPtr, string> lWindow in OpenWindowGetter.GetOpenWindows())
{
    IntPtr lHandle = lWindow.Key;
    string lTitle = lWindow.Value;

    Console.WriteLine("{0}: {1}", lHandle, lTitle);
}
Comments:
What on earth does this do?


EnumWindows(delegate(HWND hWnd, int lParam)
{
if (hWnd == lShellWindow) return true;
if (!IsWindowVisible(hWnd)) return true;

int lLength = GetWindowTextLength(hWnd);
if (lLength == 0) return true;

StringBuilder lBuilder = new StringBuilder(lLength);
GetWindowText(hWnd, lBuilder, lLength + 1);

lWindows[hWnd] = lBuilder.ToString();
return true;

}, 0);


Thanks,
Curtis
 
EnumWindows is a Win32 function that has 2 arguments. The first is a pointer to a function that is called for each window that is open. The second is a parameter that is passed as data to the function.
What you see above is that I use an anonymous delegate instead of a function pointer. The block of code is called for each open window. You could consider EnumWindows to be like a foreach-loop:
foreach(HWND hWnd in OpenWindows)
{
...
}
 
I have not written any C++ in a while and I do not know the differences between c++ and C#. Can you tell me if this code will work with C++ or does it require C#.

Thank you.
 
Since it's just plain Win32, it will also work in C++.
You won't have to declare the static extern functions, imported from User32.dll, and instead of passing a delegate to EnumWindows, you will have to pass a function pointer. You will also have to replace the StringBuilder with a char array or a char pointer.
Here's the documentation for EnumWindows: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/enumwindows.asp.
And here is some sample code I just found via Google: http://simplesamples.info/Windows/EnumWindows.php.
 
How to get all the windows from multiple monitors?
 
I thought this would get the list of open windows across multiple monitors. I'll check later today at work where I have 2 monitors.
 
thanks for the code, It was hard to find, then I wanna give my contribution

here the code ready to use on C# 2008 (Net 3.5)

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

public static class OpenWindowGetter
{

public static IDictionary<IntPtr, String> GetOpenWindows()
{

IntPtr lShellWindow = GetShellWindow();
Dictionary<IntPtr, string> lWindows = new Dictionary<IntPtr, string>();

EnumWindows(delegate(IntPtr hWnd, int lParam)
{
if (hWnd == lShellWindow) return true;
if (!IsWindowVisible(hWnd)) return true;

int lLength = GetWindowTextLength(hWnd);
if (lLength == 0) return true;

StringBuilder lBuilder = new StringBuilder(lLength);
GetWindowText(hWnd, lBuilder, lLength + 1);

lWindows[hWnd] = lBuilder.ToString();
return true;

},0);

return lWindows;
}

delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);

[DllImport("USER32.DLL")]
static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

[DllImport("USER32.DLL")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("USER32.DLL")]
static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("USER32.DLL")]
static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("USER32.DLL")]
static extern IntPtr GetShellWindow();
}

--David C
 
What's the difference with the original code? The only thing I see that is different is that you use IntPtr directory instead of the alias HWND.
 
Thank you for this great example, but shouldn't

foreach(KeyValuePair lWindow = OpenWindowGetter.GetOpenWindows())

be

foreach(KeyValuePair lWindow in OpenWindowGetter.GetOpenWindows())

??
That's what made it work for me anyway.

Rick O.
 
Rick, thank you for the correction. You are absolutely correct. I'll fix it as soon as possible.
 
Post a Comment

Links to this post:

Create a Link