Windows Forms have the annoying habit of popping up windows underneath other windows. Something is royally screwed up in the way the Windows form engine parents dialog boxes like messageboxes which always seem to pop behind any active windows.
For example, in one of my apps I have a warning dialog that pops up before a form is active that lets the user know that the database connections have not been set up. The following C# code demonstrates:
private void LoadForm()
{
Lookups = WebStoreFactory.GetbusLookups();
int Result = Lookups.GetCountryList();
// *** Check for data failure at startup
if (Result < 0)
{
// *** Splash gets in the way so let's make it
// *** gets released.
Splash.Instance.Close();
MessageBox.Show("Can't load data files.\r\n" +
Lookups.ErrorMessage + "\r\n\r\n"+
"Please make sure the Connection String to a local West Wind Web Store\r\n" +
"SQL Server database is set up. To create an offline database\r\n" +
"you can use the Web based wizard on the West Wind Web Store Admin page.\r\n\r\n",
App.WWSTORE_APPNAME,MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
WebStoreConfigForm Form = new WebStoreConfigForm();
Form.TopMost = true;
Form.ShowDialog();
return;
}
}
When I run this code the MessageBox pops up behind the currently active Window stack which is uh, far from optimal. Apparently MessageBox automatically tries to attach to the currently running form – alas the form isn’t visible yet so it usually pops up at the bottom of the window stack.
Most dialog function support the ability to use an IWin32Window handle. Seems easy enough until you try to do something useful with it and realize you have to implement a class. Worse in order to get a window to the top of the stack you really need to use Interop:
public class DesktopWindow : IWin32Window
{
// *** Instance to return
private static DesktopWindow m_DesktopWindow = new DesktopWindow();
// *** Don't allow instantiation
private DesktopWindow() {}
public static IWin32Window Instance
{
get { return m_DesktopWindow; }
}
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
/// <summary>
/// This method returns the actual window handle
/// This is one convoluted way to do a simple thing
/// </summary>
IntPtr IWin32Window.Handle
{
get
{
return GetForegroundWindow();
}
}
}
That’s one hell of a funky way to expose a simple IntPtr reference. Now you can do:
MessageBox.Show(DesktopWindow.Instance,"Can't load data files.\r\n",…);
and the window will pop up on the top of the window stack.
You'll need this same kind of logic if you are activating windows from a notify icon, basically anywhere where you call MessageBox where the current form is either not yet active or hidden away.
Other Posts you might also like