<< Click to Display Table of Contents >>

Navigation:  »No topics above this level«

WinForms: How to center a MessageBox over its parent window C#

Return to chapter overview

Windows Forms is old, but it's still widely used. The MessageBox.Show() method puts the message box in the center of the screen instead of in front of its parent window. This is very annoying, especially on a large screen. Microsoft should have provided an option for this. Many people have struggled with this problem over the years. Here is a very simple solution.

The solutions on Internet which center the dialog box over the parent window usually use a derived MassageBoxEx class with a 'windows hook'. My method just intercepts the WM_ACTIVATE message that's sent to the parent window when the child window (the message box) is activated, so you don't need to use a non-standard MessageBox class.

The code below centers ALL the child windows, which is OK for many applications. You can easily easily limit it to certain types of window by examining the class name or title text, or even send the window a WM_USER message to ask if it should be centered or not, so you can disable this feature for your own windows.

 

center-dialog-1

 

		// >>>>>>>>>>>>>>>>>>
		// The easiest way to center a child window over its parent
		// is to center it when it gets activated by WM_ACTIVATE
		// put this code into your Form-derived main window class
		// and all child windows will be centered

		protected override void WndProc(ref Message m)
		{
			// WM_ACTIVATE
			// main window being deactivated
			// center the child window
			if (m.Msg == 6 && (int)m.WParam == 0) {
				CenterWindow(this.Handle, m.LParam);
			}
			base.WndProc(ref m);
		}

		private static void CenterWindow(IntPtr hParentWnd, IntPtr hChildWnd)
		{
			Rectangle rect = new Rectangle(0, 0, 0, 0);
			GetWindowRect(hChildWnd, ref rect);
			int width = rect.Width - rect.X;
			int height = rect.Height - rect.Y;

			GetWindowRect(hParentWnd, ref rect);
			int xCenter = rect.X + ((rect.Width - rect.X) / 2);
			int yCenter = rect.Y + ((rect.Height - rect.Y) / 2);

			int xWnd = xCenter - (width / 2);
			if (xWnd < 0)
				xWnd = 0;
			int yWnd = yCenter - (height / 2);
			if (yWnd < 0) 
				yWnd = 0;

			MoveWindow(hChildWnd, xWnd, yWnd, width, height, false);
		}

		[DllImport("user32.dll")]
		private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect);
		[DllImport("user32.dll")]
		private static extern int MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

		//we could use the window class or title to find which windows to center, else we center them all
		//[DllImport("User32.Dll")]
		//private static extern void GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
		//[DllImport("User32.dll")]
		//private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

		//<<<<<<<<<<<<<<<<<<<