How to center a WPF Window in a Excel VSTO addin
.net, vsto, wpf
Solution
I was able to solve this by get getting the Rect of the Main Excel Window using `user32.dll`
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
It appears that Globals.ExcelAddin.Application.ActiveWindow was not giving me back the dimension I expected. I think it was giving me the Ribbon Addin's dimensions and not Excel's Main Window.
Problem
The problem is that a WPF window only takes a system.form.window so I cannot set Excel to be the owner object in my VSTO application, because the VSTO addin only exposes Excel's hwnd, or its active window as a Native Window since it is COM. That means when WindowStartUpLoadation is set to be center owner it doesn't work. So I am forced to work around this. What I have come up with so far after reading this site is to try and manually center the window, but even with his simple example my window never appears centered. ``` private static void CenterWpfWindowInExcel(WpfParameterDialog wpfDialog) { WindowInteropHelper helper = new WindowInteropHelper(wpfDialog); helper.Owner = new IntPtr(Globals.ExcelAddin.Application.Hwnd); // Manually calculate Top/Left to appear centered double nonWpfOwnerLeft = Globals.ExcelAddin.Application.ActiveWindow.Left; // Get non-WPF owner’s Left double nonWpfOwnerWidth = Globals.ExcelAddin.Application.ActiveWindow.Width; // Get non-WPF owner’s Width double nonWpfOwnerTop = Globals.ExcelAddin.Application.ActiveWindow.Top; // Get non-WPF owner’s Top double nonWpfOwnerHeight = Globals.ExcelAddin.Application.ActiveWindow.Height; // Get non-WPF owner’s Height wpfDialog.WindowStartupLocation = WindowStartupLocation.Manual; wpfDialog.Left = nonWpfOwnerLeft + (nonWpfOwnerWidth - wpfDialog.Width)/2; wpfDialog.Top = nonWpfOwnerTop + (nonWpfOwnerHeight - wpfDialog.Height)/2; } ``` Any ideas?