I have a WinForm app that has other child forms (not mdi). If the user presses "Esc" the topmost form should be closed even if it doesn't have the focus.
I can use a keyboard hook to globally catch the Escape but I also need the handle of the form to be closed.
I guess there is a way to do that using Win32 API, but is there a solution using managed code?
To change the name of your form, select it in the solution explorer and press F2. Then type in the new name for that form (don't forget the '. cs'!) and when you press enter it'll ask you if you want Visual Studio to update all references to that form. Click Yes, and you're done.
Add the control by drawingSelect the control by clicking on it. In your form, drag-select a region. The control will be placed to fit the size of the region you selected.
Gets or sets a value that indicates whether a window appears in the topmost z-order. public: property bool Topmost { bool get(); void set(bool value); }; C# Copy.
1. We couldn't reach the apples on the topmost branches. 2. The topmost branches were full of birds.
Here is one way to get the topmost form that uses Win32 (not very elegant, but it works):
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;
}
How about this using Application.Openforms
Form GetTopMostForm()
{
return Application.OpenForms
.Cast<Form>()
.First(x => x.Focused);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With