子表单为什么不与父表单出现在同一屏幕上?

时间:2019-07-24 16:34:51

标签: c# winforms vsto handle multiple-monitors

更新

我接受了Rufus L的几个mod的回答,相关代码如下

public partial class ClsOfficeRibbonFooTab
{

    private void FooTab_Load(object sender, RibbonUIEventArgs e)
    {
         .
         .
         .
    }

    private void CheckResolution()
    {
        // set the left position so that the expanded version of the form fits on the screen
        Screen screen = Screen.FromHandle(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd));

        if (screen.Bounds.Width < 1360 || screen.Bounds.Height < 768)
        {
            throw new FormatException(String.Format("The {0} is supported on screens with a resolution of 1360 by 768 or greater. Your screen is {1} by {2}", "Some caption text", screen.Bounds.Width, screen.Bounds.Height));
        }
    }

    private void ObjButtonFoo_Click(object sender, RibbonControlEventArgs e)
    {
        using (ClsFormFoo objFormFoo = new ClsFormFoo(parentWindow: Globals.ThisAddIn.Application.ActiveWindow))
        {
            CheckResolution();
            objFormFoo.ShowDialog();
        }
    }
}

public partial class ClsFormFoo : Form
{
    // This form is a fixed dialog with a flyout on the right side. 
    // expandedWidth is a const set to the max width of this fixed dialog (i.e., the dialog with the flyout extended)
    const int expandedWidth = 1345;

    public ClsFormFoo(Microsoft.Office.Interop.Word.Window parentWindow)
    {
        InitializeComponent();
        Top = parentWindow.Top;
    }

    private void ClsFormFoo_Load(object sender, EventArgs e)
    {
        Screen screen = Screen.FromHandle(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd));

        // set the left position so that the expanded version of the form fits on the screen for all legal resolutions
        int halfScreenWidth = (int)(screen.WorkingArea.Width / 2);
        // This form is a fixed dialog with a flyout on the right side. 
        // expandedWidth is a const set to the max width of this fixed dialog (i.e., the dialog with the flyout extended)
        int halfFormWidth = (int)(expandedWidth / 2);
        this.Left = screen.Bounds.Left + ((int)(halfScreenWidth - halfFormWidth));
    }
}

原始帖子

我的VSTO Add-In提供了一个功能区按钮,单击该按钮会调用ObjButtonFoo_Click,这反过来会显示ClsFormFoo形式(请参见下面的 Code )。 ObjButtonFoo_Click包含用于创建代表Word的IWin32Window所有者值并传递给ShowDialog的代码。

在多显示器设置中,我希望objFormFoo会出现在显示Word本身的同一显示器上。但是,当我在辅助监视器上启动Word并导致执行ObjButtonFoo_Click时,objFormFoo会出现在主监视器上

如何使objFormFoo出现在与Word本身显示在同一显示器上的显示器上,无论它是否是主要显示器?

注意:我已验证是否已填充winWordMain,即它不是null。请参见下面的 winWordMain

代码

private void ObjButtonFoo_Click(object sender, RibbonControlEventArgs e)
{
    NativeWindow winWordMain = new NativeWindow();
    winWordMain.AssignHandle(new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd));
    IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd);

    using (ClsFormFoo objFormFoo = new ClsFormFoo()
    {
        objFormFoo.ShowDialog(winWordMain);
    }

    winWordMain.ReleaseHandle();
}

winWordMain

enter image description here

1 个答案:

答案 0 :(得分:0)

您只需要将表单的StartPosition属性设置为FormStartPosition.CenterParent值:

loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.ShowDialog(parentWindowdle);