Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Settting System Dialogs to the foreground in WinForms


:P
On this page:

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.

 

 


The Voices of Reason


 

Yggy
April 03, 2006

# re: Settting System Dialogs to the foreground in WinForms

Just what I was looking for! ... almost -- this technique has a fun bug, try popping up a message box in this way with a DOS shell (cmd.exe) as the active application. The message box doesn't appear, the DOS shell can't be moved by dragging the title bar, and you'll only get the message when you change focus to another app and then back to the shell. Thanks Microsoft!

dj
June 02, 2006

# re: Settting System Dialogs to the foreground in WinForms

I ran into a need for exactly this fix in an print monitoring Windows service application. The service is interactive (as print monitors often are) and my dialogs are raised when other applications have focus. But I needed to grab focus. Without the fix, my dialogues would not have focus despite appearing top and despite being told to be activated. The fix worked perfectly in my situation.
Thanks for your posting.

ajr
July 26, 2006

# re: Settting System Dialogs to the foreground in WinForms

This works. However, If you minimize any application that is behind your windows form, your windows form will close. Very strange.

David Adams
October 30, 2012

# re: Settting System Dialogs to the foreground in WinForms

Awesome work Rick. I had the exact same problem and found this solution.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024