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;And here's some code that uses it:/// <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(); }
foreach(KeyValuePair<IntPtr, string> lWindow in OpenWindowGetter.GetOpenWindows()) { IntPtr lHandle = lWindow.Key; string lTitle = lWindow.Value; Console.WriteLine("{0}: {1}", lHandle, lTitle); }
Comments:
Post a Comment
Links to this post:
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(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)
{
...
}
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.
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.
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.
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
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.
foreach(KeyValuePair lWindow = OpenWindowGetter.GetOpenWindows())
be
foreach(KeyValuePair lWindow in OpenWindowGetter.GetOpenWindows())
??
That's what made it work for me anyway.
Rick O.
Links to this post:

