[英]How to close winform with TopMost=true, when another application opens on top of my app
[英]How to get the handle of the topmost form in a WinForm app?
我有一個 WinForm 應用程序,它有其他孩子 forms(不是 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);
/// <summary>
/// Searches for the topmost visible form of your app in all the forms opened in the current Windows session.
/// </summary>
/// <param name="hWnd_mainFrm">Handle of the main form</param>
/// <returns>The Form that is currently TopMost, or null</returns>
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<Form>()
.First(x => x.Focused);
}
我知道這是一個已有 4 年歷史的線程,但我遇到了類似的問題,只是想出了一個替代解決方案,以防其他人偶然發現這個問題並且不想亂用 Win32 調用。
我假設最頂層的表格將是最后激活的表格。 因此,您可以保留一個單獨的 forms 集合,類似於 Application.OpenForms,但該集合將按每個集合最后一次激活的時間排序。 每當激活一個表單時,將其移動到集合的第一項。 每當您看到 ESC 鍵時,您將關閉 collection[0] 並將其刪除。
FormCollection被Application object使用,通過OpenForms屬性列出一個應用程序中當前打開的forms
請參閱http://msdn.microsoft.com/en-us/library/system.windows.forms.application.openforms.aspx
然后你可以檢查每個表單的 TopMost() 屬性。 當您找到最頂層的表格時,您將其關閉。
您可以在最頂層的表單中實現類似單例的模式,並提供一個 static 屬性,該屬性返回其自身的一個實例並簡單地關閉它。
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.