Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Winforms-How can I make MessageBox appear centered on MainForm?

Winforms-How can I make dialog boxes appear centered on MainForm? That is as opposed to be based on Normal windows default which renders them in the centre of the screen.

In my case I have a small main form that may for example be positioned in a corner, the the MessageBox popup is displayed what seems a ways away.

like image 451
Greg Avatar asked Apr 04 '10 22:04

Greg


1 Answers

It is possible with some servings of P/Invoke and the magic provided by Control.BeginInvoke(). Add a new class to your project and paste this code:

using System; using System.Text; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices;  class CenterWinDialog : IDisposable {     private int mTries = 0;     private Form mOwner;      public CenterWinDialog(Form owner) {         mOwner = owner;         owner.BeginInvoke(new MethodInvoker(findDialog));     }      private void findDialog() {         // Enumerate windows to find the message box         if (mTries < 0) return;         EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);         if (EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero)) {             if (++mTries < 10) mOwner.BeginInvoke(new MethodInvoker(findDialog));         }     }     private bool checkWindow(IntPtr hWnd, IntPtr lp) {         // Checks if <hWnd> is a dialog         StringBuilder sb = new StringBuilder(260);         GetClassName(hWnd, sb, sb.Capacity);         if (sb.ToString() != "#32770") return true;         // Got it         Rectangle frmRect = new Rectangle(mOwner.Location, mOwner.Size);         RECT dlgRect;         GetWindowRect(hWnd, out dlgRect);         MoveWindow(hWnd,             frmRect.Left + (frmRect.Width - dlgRect.Right + dlgRect.Left) / 2,             frmRect.Top + (frmRect.Height - dlgRect.Bottom + dlgRect.Top) / 2,             dlgRect.Right - dlgRect.Left,             dlgRect.Bottom - dlgRect.Top, true);         return false;     }     public void Dispose() {         mTries = -1;     }      // P/Invoke declarations     private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);     [DllImport("user32.dll")]     private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);     [DllImport("kernel32.dll")]     private static extern int GetCurrentThreadId();     [DllImport("user32.dll")]     private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);     [DllImport("user32.dll")]     private static extern bool GetWindowRect(IntPtr hWnd, out RECT rc);     [DllImport("user32.dll")]     private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);     private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } } 

Sample usage:

    private void button1_Click(object sender, EventArgs e) {         using (new CenterWinDialog(this)) {             MessageBox.Show("Nobugz waz here");         }     } 

Note that this code works for any of the Windows dialogs. MessageBox, OpenFormDialog, FolderBrowserDialog, PrintDialog, ColorDialog, FontDialog, PageSetupDialog, SaveFileDialog.

like image 181
Hans Passant Avatar answered Oct 19 '22 12:10

Hans Passant