so I have a form with a ComboBox
that I populate with a list of open processes (In this case, I limit it to processes with titles that have 13 characters.) When I select an Item
in the ComboBox
I want to find that Form
by Title and BringToFront
However when I do so, it throws a System.NullReferenceException
.
Here's the code I use to populate the box.
using HWND = IntPtr;
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();
}
public void populateIncidents()
{
foreach (KeyValuePair<IntPtr, string> window in OpenWindowGetter.GetOpenWindows())
{
IntPtr handle = window.Key;
string title = window.Value;
if (title.Length == 13)
{
chooseIncidentBox.Items.Add(title);
}
}
}
And here's the code I'm using to try to show the Form.
private void chooseIncidentBox_SelectedIndexChanged(object sender, EventArgs e)
{
sSelectedIncident = chooseIncidentBox.Text;
Application.OpenForms[sSelectedIncident].BringToFront(); //Exception thrown here.
}
I'm not quite sure why it's throwing the exception, I know the Form exists as it wouldn't populate the ComboBox
otherwise. Any help would be greatly appreciated.
The code you have gives all the active windows. Now, Application.OpenForms
works only on the forms which are opened in your application. For example, if you have ParentForm
and ChildForm
in your application and both are open, OpenForms
collection will contain these two.
What you are looking for is to bring any process window in front. You can make use of SetForegroundWindow
in User32.dll
to do so. This SO question looks fairly similar to what you need. Take a look at the accepted solution.