One of the developers has sent me an email asking on how to get the same list of programs that's shown in the "Running Program List" applet on Pocket PC's. I forwarded her to the EnumerateTopWindows function I'd implemented before. But she replied to me that this function enumerates all windows, including Desktop, SIP button etc... So I've added a few checks into this function such as calls to the IsWindow and IsWindowVisible API's. I've also put in a few helper functions:
private static bool CheckForDialogs(ArrayList windowList, string value)
{
foreach(Window window in windowList)
{
if (window.Caption == value)
{
return true;
}
}
return false;
}
private static bool CheckExcludeList(string value)
{
foreach(string name in excludeList)
{
if (name == value)
{
return true;
}
}
return false;
}
The first one checks if the window that has the same caption already exists and the second loops through the exclude list of some known system programs:
static string[] excludeList = {"Desktop", "MS_SIPBUTTON", "Programs"};
So the new version of the EnumerateTopWindows looks like this:
public static Window[] EnumerateTopWindows()
{
ArrayList windowList = new ArrayList();
IntPtr hWnd = IntPtr.Zero;
Window window = null;
StringBuilder sb = null;
// Get first window
hWnd = GetActiveWindow();
hWnd = GetWindow(hWnd, GW_HWNDFIRST);
while(hWnd != IntPtr.Zero)
{
// Check if it is a windowm and it is visible
if(IsWindow(hWnd) && IsWindowVisible(hWnd))
{
IntPtr parentWin = GetParent(hWnd);
// Make sure that the window doesn't hav a parent
if ((parentWin == IntPtr.Zero))
{
int length = GetWindowTextLength(hWnd);
// Does it have the text caption
if (length > 0)
{
sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
string text = sb.ToString();
text = text.Substring(0, text.IndexOf('\0'));
// Exclude some known system programs
if(!CheckExcludeList(text) && !CheckForDialogs(windowList, text))
{
window = new Window();
window.Handle = hWnd;
window.Caption = text;
windowList.Add(window);
}
}
}
}
hWnd = GetWindow(hWnd, GW_HWNDNEXT);
}
return (Window[])windowList.ToArray(typeof(Window));
}
And the additional P/Invoke declarations:
[DllImport("coredll.dll")]
static extern bool IsWindow(IntPtr handle);
[DllImport("coredll.dll")]
static extern bool IsWindowVisible(IntPtr handle);
And as a bonus here's a way to close the program:
[DllImport("coredll.dll")]
private extern static int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private static int WM_CLOSE = 0x0010;
public static void CloseWindow(Window window)
{
SendMessage(window.Handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
Here's the updated project:
EnumerateWindowsProjNew.zip (6.51 KB)