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 = 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.
 
Post a Comment

Links to this post:

Create a Link