WPF Office Add-In: Как установить позицию диалога, чтобы показывать в центре родительского окна - PullRequest
0 голосов
/ 05 ноября 2018

Это расширение вопроса здесь .

Я внес следующие незначительные изменения в код для работы в случае надстройки 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 (). Ширина кажется огромной по сравнению с другими значениями.

Мне не удалось получить хорошее решение от @chessweb для работы, поскольку вызывающие окна - это кнопка с ленты.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Что ж, после небольшого тестирования я получаю следующее решение, которое хорошо работает.

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.12 при работе с коэффициентом масштабирования 2)
  • При условии, что масштабные коэффициенты высоты и ширины равны, можно использовать только один и, таким образом, обратиться к первой точке

Любой комментарий / отзыв будет оценен.

0 голосов
/ 05 ноября 2018

Я могу придумать несколько способов, но вот как я, вероятно, подхожу к этому:

  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, но этот проверен и проверен.

Надеюсь, что поможет

...