I want to have a tool that provide a Alt + Tab
like function, but instead of switch between all of opening windows, I want to narrow them down to 1 specific program only (e.g. firefox.exe).
All I could think of is using GetWindowText
to get a list of windows that contain "Mozilla Firefox" in their titles, and then ShowWindowAsync
to show them up, but it doesn't seem to work well if some other opening windows also have this phrase "Mozilla Firefox" in their titles.
Is there any better solution? Here is the code:
/// <summary>Contains functionality 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 shellWindow = GetShellWindow();
Dictionary<HWND, string> windows = new Dictionary<HWND, string>();
EnumWindows(delegate(HWND hWnd, int lParam)
{
if (hWnd == shellWindow) return true;
if (!IsWindowVisible(hWnd)) return true;
int length = GetWindowTextLength(hWnd);
if (length == 0) return true;
StringBuilder builder = new StringBuilder(length);
GetWindowText(hWnd, builder, length + 1);
windows[hWnd] = builder.ToString();
return true;
}, 0);
return windows;
}
private delegate bool EnumWindowsProc(HWND hWnd, int lParam);
[DllImport("USER32.DLL")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
[DllImport("USER32.DLL")]
private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("USER32.DLL")]
private static extern int GetWindowTextLength(HWND hWnd);
[DllImport("USER32.DLL")]
private static extern bool IsWindowVisible(HWND hWnd);
[DllImport("USER32.DLL")]
private static extern IntPtr GetShellWindow();
}
This is how I use it:
/// <summary>
/// Get a window handle by a title
/// </summary>
/// <param name="windowTitle"></param>
/// <param name="wildCard">match if window title contains input windowTitle</param>
/// <returns></returns>
public static int GetWindowHandle(string windowTitle, bool wildCard = false)
{
var processList = OpenWindowGetter.GetOpenWindows();
foreach (var process in processList)
{
if ((wildCard && process.Value.ToLower().Contains(windowTitle.ToLower())) //Find window by wildcard
|| !wildCard && process.Value.Equals(windowTitle)) //Find window with exact name
{
int a = (int)process.Key;
return a;
}
}
return 0;
}