为什么子窗体不与父窗体出现在同一屏幕上?
Why doesn't the child form appear on the same screen as the parent form?
更新
我接受了 Rufus L 的回答并做了一些修改,相关代码如下
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));
}
}
原版Post
我的 VSTO Add-In
提供了一个功能区按钮,单击该按钮会调用 ObjButtonFoo_Click
,它又会显示 ClsFormFoo
表单(参见 代码 以下)。 ObjButtonFoo_Click
包含创建代表 Word 的 IWin32Window 所有者值以传递给 ShowDialog 的代码。
在多显示器设置中,我希望 objFormFoo
会出现在显示 Word 本身的同一台显示器上。但是,当我在辅助监视器上启动 Word 并导致执行 ObjButtonFoo_Click
时,objFormFoo
出现在主监视器上
如何使 objFormFoo
出现在与 Word 本身显示在同一台显示器上,无论它是否是主显示器?
注意:我已验证 winWordMain 已填充,即它不为空。请参阅下面的 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
我没有 VSTO 来测试这个,但在我看来你可以只获取你用作父级的 ActiveWindow
的位置,然后将其用作参考用于定位您的子表单:
private void allRootsWithChilds_CheckedChanged(object sender, EventArgs e)
{
var winWordMain = new NativeWindow();
var parent = Globals.ThisAddIn.Application.ActiveWindow;
winWordMain.AssignHandle(new IntPtr(parent.Hwnd));
using (var objFormFoo = new ClsFormFoo())
{
// Set the Left and Top properties so this form is centered over the parent
objFormFoo.Left = parent.Left + (parent.Width - objFormFoo.Width) / 2;
objFormFoo.Top = parent.Top + (parent.Height - objFormFoo.Height) / 2;
objFormFoo.ShowDialog(winWordMain);
}
winWordMain.ReleaseHandle();
}
我以前用C#做一个简单的屏保。我使用以下代码在所需屏幕或所有屏幕上打开屏幕保护程序。
您必须从所需的屏幕中获取 bounds
并将其传递给表单。
// Constructor
public NameForm(Rectangle bounds)
{
InitializeComponent();
this.Bounds = bounds;
}
// In my case, this is opening the screensaver on all screens
foreach (Screen screen in Screen.AllScreens)
{
NameForm form = new NameForm (screen.Bounds);
form.Show();
}
您只需将表单的 StartPosition
属性 设置为 FormStartPosition.CenterParent
值:
loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.ShowDialog(parentWindowdle);
更新
我接受了 Rufus L 的回答并做了一些修改,相关代码如下
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));
}
}
原版Post
我的 VSTO Add-In
提供了一个功能区按钮,单击该按钮会调用 ObjButtonFoo_Click
,它又会显示 ClsFormFoo
表单(参见 代码 以下)。 ObjButtonFoo_Click
包含创建代表 Word 的 IWin32Window 所有者值以传递给 ShowDialog 的代码。
在多显示器设置中,我希望 objFormFoo
会出现在显示 Word 本身的同一台显示器上。但是,当我在辅助监视器上启动 Word 并导致执行 ObjButtonFoo_Click
时,objFormFoo
出现在主监视器上
如何使 objFormFoo
出现在与 Word 本身显示在同一台显示器上,无论它是否是主显示器?
注意:我已验证 winWordMain 已填充,即它不为空。请参阅下面的 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
我没有 VSTO 来测试这个,但在我看来你可以只获取你用作父级的 ActiveWindow
的位置,然后将其用作参考用于定位您的子表单:
private void allRootsWithChilds_CheckedChanged(object sender, EventArgs e)
{
var winWordMain = new NativeWindow();
var parent = Globals.ThisAddIn.Application.ActiveWindow;
winWordMain.AssignHandle(new IntPtr(parent.Hwnd));
using (var objFormFoo = new ClsFormFoo())
{
// Set the Left and Top properties so this form is centered over the parent
objFormFoo.Left = parent.Left + (parent.Width - objFormFoo.Width) / 2;
objFormFoo.Top = parent.Top + (parent.Height - objFormFoo.Height) / 2;
objFormFoo.ShowDialog(winWordMain);
}
winWordMain.ReleaseHandle();
}
我以前用C#做一个简单的屏保。我使用以下代码在所需屏幕或所有屏幕上打开屏幕保护程序。
您必须从所需的屏幕中获取 bounds
并将其传递给表单。
// Constructor
public NameForm(Rectangle bounds)
{
InitializeComponent();
this.Bounds = bounds;
}
// In my case, this is opening the screensaver on all screens
foreach (Screen screen in Screen.AllScreens)
{
NameForm form = new NameForm (screen.Bounds);
form.Show();
}
您只需将表单的 StartPosition
属性 设置为 FormStartPosition.CenterParent
值:
loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.ShowDialog(parentWindowdle);