如何在WinForm应用程序中获取最顶层表单的句柄?

我有一个WinForm应用程序,其他子窗体(不是mdi)。 如果用户按下“Esc”,即使没有焦点,也应关闭最上面的表格。

我可以使用键盘钩子来全局捕捉Escape,但我还需要关闭表单的句柄。

我想有一种方法可以使用Win32 API,但有一个使用托管代码的解决方案?

这是获取使用Win32的最顶层表单的一种方法(不是很优雅,但它可以工作):

public const int GW_HWNDNEXT = 2; // The next window is below the specified window public const int GW_HWNDPREV = 3; // The previous window is above [DllImport("user32.dll")] static extern IntPtr GetTopWindow(IntPtr hWnd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "GetWindow", SetLastError = true)] public static extern IntPtr GetNextWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.U4)] int wFlag); ///  /// Searches for the topmost visible form of your app in all the forms opened in the current Windows session. ///  /// Handle of the main form /// The Form that is currently TopMost, or null public static Form GetTopMostWindow(IntPtr hWnd_mainFrm) { Form frm = null; IntPtr hwnd = GetTopWindow((IntPtr)null); if (hwnd != IntPtr.Zero) { while ((!IsWindowVisible(hwnd) || frm == null) && hwnd != hWnd_mainFrm) { // Get next window under the current handler hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); try { frm = (Form)Form.FromHandle(hwnd); } catch { // Weird behaviour: In some cases, trying to cast to a Form a handle of an object // that isn't a form will just return null. In other cases, will throw an exception. } } } return frm; } 

使用Application.Openforms如何做到这一点

 Form GetTopMostForm() { return Application.OpenForms .Cast
() .First(x => x.Focused); }

我知道这是一个4岁的线程,但我有一个类似的问题,只是提出了一个替代解决方案,以防万一其他人偶然发现这个问题,并不想搞乱Win32调用。

我假设最顶层的forms将是最后一次激活的forms。 所以你可以保留一个单独的表单集合,类似于Application.OpenForms,除了这个集合将在最后一次激活时按顺序排序。 无论何时激活表单,都将其移动到集合的第一个项目。 每当您看到ESC键时,您将关闭集合[0]并将其删除。

Application对象使用FormCollection通过OpenForms属性列出应用程序中当前打开的表单

请参阅http://msdn.microsoft.com/en-us/library/system.windows.forms.application.openforms.aspx

然后你可以检查每个表单的TopMost()属性。 当你找到一个最顶层的表格时,你关闭它。

您可以在最顶层的表单中实现类似单例的模式,并提供一个静态属性,该属性返回自身的一个实例并简单地关闭它。

  public class MainForm : Form { private static MainForm mainForm; public static MainForm { get { return mainForm; } } public MainForm() { mainForm = this; } } // When the ESC key is pressed... MainForm.MainForm.Close();