Do you have a messagebox in a WPF application? Are you having a problem with the centering of the the messagebox in .net? I was as well. For some reason when ever i called a messagebox it would center the messagebox on what ever screen my mouse was on. Centering a messagebox on screen number two when the application is on screen number one is totally unacceptable. First let me start with credit where credit is due. I found the main part of this code here Centering a Message box on the Active window in C#. That code was for windows forms. I have changed it slightly to work with WPF.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WPFSetup.Util
{
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
internal static class MessageBoxHelper
{
internal static void PrepToCenterMessageBoxOnForm(Window form)
{
MessageBoxCenterHelper helper = new MessageBoxCenterHelper();
helper.Prep(form);
}
private class MessageBoxCenterHelper
{
private int messageHook;
private IntPtr parentFormHandle;
public void Prep(Window form)
{
NativeMethods.CenterMessageCallBackDelegate callBackDelegate = new NativeMethods.CenterMessageCallBackDelegate(CenterMessageCallBack);
GCHandle.Alloc(callBackDelegate);
parentFormHandle = new WindowInteropHelper(form).Handle;
messageHook = NativeMethods.SetWindowsHookEx(5, callBackDelegate, new IntPtr(NativeMethods.GetWindowLong(parentFormHandle, -6)), NativeMethods.GetCurrentThreadId()).ToInt32();
}
private int CenterMessageCallBack(int message, int wParam, int lParam)
{
NativeMethods.RECT formRect;
NativeMethods.RECT messageBoxRect;
int xPos;
int yPos;
if (message == 5)
{
NativeMethods.GetWindowRect(parentFormHandle, out formRect);
NativeMethods.GetWindowRect(new IntPtr(wParam), out messageBoxRect);
xPos = (int)((formRect.Left + (formRect.Right - formRect.Left) / 2) - ((messageBoxRect.Right - messageBoxRect.Left) / 2));
yPos = (int)((formRect.Top + (formRect.Bottom - formRect.Top) / 2) - ((messageBoxRect.Bottom - messageBoxRect.Top) / 2));
NativeMethods.SetWindowPos(wParam, 0, xPos, yPos, 0, 0, 0x1 | 0x4 | 0x10);
NativeMethods.UnhookWindowsHookEx(messageHook);
}
return 0;
}
}
private static class NativeMethods
{
internal struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
internal delegate int CenterMessageCallBackDelegate(int message, int wParam, int lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool UnhookWindowsHookEx(int hhk);
[DllImport("user32.dll", SetLastError = true)]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("kernel32.dll")]
internal static extern int GetCurrentThreadId();
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr SetWindowsHookEx(int hook, CenterMessageCallBackDelegate callback, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
}
}
}
I wont claim to understand all of what that code is doing but it does work. For more explanation on what its doing i suggest you check the main authors website.
Calling it
MessageBoxHelper.PrepToCenterMessageBoxOnForm(this);
MessageBox.Show("Hello!", "Hello!", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
Hello Linda,
Just wanted to say thank you for this great post, which helped me save a lot of time. 🙂
I love people like you who want to share their experiences.
Thanks again,
Bryan
Thank You