按标题激活表单 System.NullReferenceException
Activating Form By Title Throws System.NullReferenceException
所以我有一个带有 ComboBox
的表单,其中填充了一个打开的进程列表(在这种情况下,我将其限制为标题为 13 个字符的进程。)当我 select ComboBox
中的 Item
我想按标题找到 Form
和 BringToFront
但是当我这样做时,它会抛出 System.NullReferenceException
.
这是我用来填充框的代码。
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);
}
}
}
这是我用来显示表单的代码。
private void chooseIncidentBox_SelectedIndexChanged(object sender, EventArgs e)
{
sSelectedIncident = chooseIncidentBox.Text;
Application.OpenForms[sSelectedIncident].BringToFront(); //Exception thrown here.
}
我不太确定它为什么抛出异常,我知道表单存在,否则它不会填充 ComboBox
。任何帮助将不胜感激。
您拥有的代码提供了所有活动 windows。现在,Application.OpenForms
仅适用于在您的应用程序中打开的表单。例如,如果您的应用程序中有 ParentForm
和 ChildForm
并且都已打开,则 OpenForms
集合将包含这两个。
你要找的是把任何进程window放在前面。您可以使用 User32.dll
中的 SetForegroundWindow
来做到这一点。 This SO 问题看起来与您需要的非常相似。看看公认的解决方案。
所以我有一个带有 ComboBox
的表单,其中填充了一个打开的进程列表(在这种情况下,我将其限制为标题为 13 个字符的进程。)当我 select ComboBox
中的 Item
我想按标题找到 Form
和 BringToFront
但是当我这样做时,它会抛出 System.NullReferenceException
.
这是我用来填充框的代码。
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);
}
}
}
这是我用来显示表单的代码。
private void chooseIncidentBox_SelectedIndexChanged(object sender, EventArgs e)
{
sSelectedIncident = chooseIncidentBox.Text;
Application.OpenForms[sSelectedIncident].BringToFront(); //Exception thrown here.
}
我不太确定它为什么抛出异常,我知道表单存在,否则它不会填充 ComboBox
。任何帮助将不胜感激。
您拥有的代码提供了所有活动 windows。现在,Application.OpenForms
仅适用于在您的应用程序中打开的表单。例如,如果您的应用程序中有 ParentForm
和 ChildForm
并且都已打开,则 OpenForms
集合将包含这两个。
你要找的是把任何进程window放在前面。您可以使用 User32.dll
中的 SetForegroundWindow
来做到这一点。 This SO 问题看起来与您需要的非常相似。看看公认的解决方案。