WPF Office加载项:如何设置对话框位置以显示在父窗口的中心

时间:2018-11-05 14:30:28

标签: c# wpf office-addins

这是问题here的扩展。

我对代码进行了以下较小调整,以使其在Office加载项下正常工作。

Microsoft.Office.Interop.Outlook.Application app = Globals.ThisAddIn.Application;
if (app.ActiveWindow() != null)
{
   this.Left = app.ActiveWindow().Left + (app.ActiveWindow().Width - this.Width) / 2;
   this.Top = app.ActiveWindow().Top + (app.ActiveWindow().Height - this.Height) / 2;
}

在正常条件下,但在HiDPI条件下(例如,在具有高分辨率的Mac上),此方法工作正常。弹出窗口显示在屏幕右下角。查看数字app.ActiveWindow()。Width与其他值相比似乎很大。

我无法从@chessweb获得好的solution来工作,因为调用窗口是功能区中的一个按钮。

有什么主意吗?

2 个答案:

答案 0 :(得分:0)

我可以考虑几种方法,但这是我可能会采用的方法:

  1. 从活动的Outlook窗口获取句柄。
  2. 在窗口上设置父项。

要获取句柄,请使用此:

using System.Runtime.InteropServices;

  //use pInvoke to find the window
  [DllImport("user32.dll", SetLastError = true)]
  static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  //now use it
  public static void Test(long handle)
  {
      Microsoft.Office.Interop.Outlook.Application app = Globals.ThisAddIn.Application;
      IntPtr hWnd = (IntPtr)FindWindow("rctrl_renwnd32\0", app.ActiveWindow().Caption);

      TestingWindowView win = new TestingWindowView(hWnd);
      win.ShowDialog();
  }

然后,在窗口的构造函数中,您可以使用WindowInteropHelper来分配所有者:

using System.Windows.Interop;

    public TestingWindowView(IntPtr handle)
    {
        InitializeComponent();
        new WindowInteropHelper(this).Owner = handle;
    }

在xaml中,您现在可以执行以下操作:

WindowStartupLocation="CenterOwner"

我确信还有其他方法可以获取Outlook的句柄,但是这一方法已经过测试和验证。

希望有帮助

答案 1 :(得分:0)

通过一些测试,我得出了下面的效果很好的解决方案。

Microsoft.Office.Interop.Outlook.Application app = Globals.ThisAddIn.Application;
if (app.ActiveWindow() != null) {
  double WidthRatio = (1 / SystemParameters.FullPrimaryScreenWidth) * 
  System.Windows.Forms.Screen.FromHandle(new 
  WindowInteropHelper(this).Handle).Bounds.Width;
  double HeightRatio = (1 / SystemParameters.FullPrimaryScreenHeight) * 
  System.Windows.Forms.Screen.FromHandle(new 
  WindowInteropHelper(this).Handle).Bounds.Height;
  this.Left = (app.ActiveWindow().Left + (app.ActiveWindow().Width - this.Width * WidthRatio) / 2) / WidthRatio;
  this.Top = (app.ActiveWindow().Top + (app.ActiveWindow().Height - this.Height * HeightRatio) / 2) / HeightRatio;
}

请注意:

  • 由于我无法解释身高比例不理想的原因( 如果没有缩放比例,则为1.12,而不是1;以2的缩放因子,则为2.12)
  • 在假设高度和宽度比例因子相等的情况下, 只能使用一个,从而解决了第一点

任何评论/反馈将不胜感激。