的WinForms,我怎么可以让对话框出现集中在MainForm的? 也就是说,而不是基于正常的Windows默认这使它们在屏幕的中央。
在我来说,我有一个例如可以放置在一个角落里一个小的主要形式,在MessageBox的弹出显示的内容似乎走的方式。
的WinForms,我怎么可以让对话框出现集中在MainForm的? 也就是说,而不是基于正常的Windows默认这使它们在屏幕的中央。
在我来说,我有一个例如可以放置在一个角落里一个小的主要形式,在MessageBox的弹出显示的内容似乎走的方式。
有可能用P /调用和()由Control.BeginInvoke提供的魔的一些份。 添加一个新类到您的项目并粘贴此代码:
using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class CenterWinDialog : IDisposable {
private int mTries = 0;
private Form mOwner;
public CenterWinDialog(Form owner) {
mOwner = owner;
owner.BeginInvoke(new MethodInvoker(findDialog));
}
private void findDialog() {
// Enumerate windows to find the message box
if (mTries < 0) return;
EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
if (EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero)) {
if (++mTries < 10) mOwner.BeginInvoke(new MethodInvoker(findDialog));
}
}
private bool checkWindow(IntPtr hWnd, IntPtr lp) {
// Checks if <hWnd> is a dialog
StringBuilder sb = new StringBuilder(260);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() != "#32770") return true;
// Got it
Rectangle frmRect = new Rectangle(mOwner.Location, mOwner.Size);
RECT dlgRect;
GetWindowRect(hWnd, out dlgRect);
MoveWindow(hWnd,
frmRect.Left + (frmRect.Width - dlgRect.Right + dlgRect.Left) / 2,
frmRect.Top + (frmRect.Height - dlgRect.Bottom + dlgRect.Top) / 2,
dlgRect.Right - dlgRect.Left,
dlgRect.Bottom - dlgRect.Top, true);
return false;
}
public void Dispose() {
mTries = -1;
}
// P/Invoke declarations
private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT rc);
[DllImport("user32.dll")]
private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);
private struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
}
用法示例:
private void button1_Click(object sender, EventArgs e) {
using (new CenterWinDialog(this)) {
MessageBox.Show("Nobugz waz here");
}
}
请注意,此代码适用于任何Windows的对话框。 消息框,OpenFormDialog,的FolderBrowserDialog,PrintDialog类,ColorDialog类,FontDialog类,PageSetupDialog类SaveFileDialog。
这是Win32 API中,C语言编写的翻译它,因为你需要...
case WM_NOTIFY:{
HWND X=FindWindow("#32770",NULL);
if(GetParent(X)==H_frame){int Px,Py,Sx,Sy; RECT R1,R2;
GetWindowRect(hwnd,&R1); GetWindowRect(X,&R2);
Sx=R2.right-R2.left,Px=R1.left+(R1.right-R1.left)/2-Sx/2;
Sy=R2.bottom-R2.top,Py=R1.top+(R1.bottom-R1.top)/2-Sy/2;
MoveWindow(X,Px,Py,Sx,Sy,1);
}
} break;
这增加了WndProc的代码。您可以设置位置,只要你喜欢,在这种情况下,它只是在中心主程序窗口。 它会做到这一点对任何消息框,或文件打开/保存对话框,并有可能其他一些本地控件。 我不知道,但我想你可能需要包括COMMCTRL或COMMDLG使用这个,至少,你会如果你想打开/保存对话框。
我尝试用看通知代码和NMHDR的中的hwndFrom,然后决定是一样有效,更容易,更不要。 如果你真的要非常具体,告诉FindWindow函数寻找一个独特的标题(标题)你给你想要找到的窗口。
在MessageBox之前该火灾是在屏幕上绘制的,所以如果你设置一个全局标志,以表明他的动作是由您的代码实现,并寻找一个独特的标题,你要确保你采取行动只会发生一次(有可能会多通知程序)。 我没有详细探讨过这个,但我设法得到CreateWindow的把一个编辑框在一个消息对话框/它看起来格格不入的老鼠的耳朵移植到克隆猪的脊柱,但它的作品。 这样做,让可能远远高于其推出自己更容易。
乌鸦。
编辑:小的修正,以确保正确的窗口进行处理。 确保母体整个手柄同意,这应该工作正常。 它确实对我来说,即使采用相同的程序的两个实例...
写自己的消息框。 表单和标签应该这样做。 或者,你也需要全球化呢?
类被证明是适用于其他两种情况。 我有一个的FolderBrowserDialog,我想大一点,而我希望它拿出父对话框的左上角附近(靠近按钮我点击打开它)。
我复制了CenterWinDialog类,并提出两个新类。 一类改变对话框的大小,和其它改变其位置到特定的从母体形式偏移。 这是用法:
using (new OffsetWinDialog(this) { PreferredOffset = new Point(75, 75 )})
using (new SizeWinDialog(this) { PreferredSize = new Size(400, 600)})
{
DialogResult result = dlgFolderBrowser.ShowDialog();
if (result == DialogResult.Cancel)
return;
}
而这些都是基于原来的两个班。
class OffsetWinDialog : IDisposable
{
private int mTries = 0;
private Form mOwner;
public OffsetWinDialog(Form owner)
{
mOwner = owner;
owner.BeginInvoke(new MethodInvoker(findDialog));
}
public Point PreferredOffset { get; set; }
private void findDialog()
{
// Enumerate windows to find the message box
if (mTries < 0)
return;
EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
if (EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero))
{
if (++mTries < 10)
mOwner.BeginInvoke(new MethodInvoker(findDialog));
}
}
private bool checkWindow(IntPtr hWnd, IntPtr lp)
{
// Checks if <hWnd> is a dialog
StringBuilder sb = new StringBuilder(260);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() != "#32770") return true;
// Got it
Rectangle frmRect = new Rectangle(mOwner.Location, mOwner.Size);
RECT dlgRect;
GetWindowRect(hWnd, out dlgRect);
MoveWindow(hWnd,
frmRect.Left + PreferredOffset.X,
frmRect.Top + PreferredOffset.Y,
dlgRect.Right - dlgRect.Left,
dlgRect.Bottom - dlgRect.Top,
true);
return false;
}
public void Dispose()
{
mTries = -1;
}
// P/Invoke declarations
private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT rc);
[DllImport("user32.dll")]
private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);
private struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
}
和
class SizeWinDialog : IDisposable
{
private int mTries = 0;
private Form mOwner;
public SizeWinDialog(Form owner)
{
mOwner = owner;
mOwner.BeginInvoke(new Action(findDialog));
}
public Size PreferredSize { get; set; }
private void findDialog()
{
// Enumerate windows to find the message box
if (mTries < 0)
return;
EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
if (EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero))
{
if (++mTries < 10)
mOwner.BeginInvoke(new MethodInvoker(findDialog));
}
}
private bool checkWindow(IntPtr hWnd, IntPtr lp)
{
// Checks if <hWnd> is a dialog
StringBuilder sb = new StringBuilder(260);
GetClassName(hWnd, sb, sb.Capacity);
if (sb.ToString() != "#32770")
return true;
// Got it
Rectangle frmRect = new Rectangle(mOwner.Location, mOwner.Size);
RECT dlgRect;
GetWindowRect(hWnd, out dlgRect);
SetWindowPos(new HandleRef(this, hWnd), new HandleRef(), dlgRect.Left, dlgRect.Top, PreferredSize.Width, PreferredSize.Height, 20 | 2);
return false;
}
public void Dispose()
{
mTries = -1;
}
// P/Invoke declarations
private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
[DllImport("user32.dll")]
private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT rc);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool SetWindowPos(HandleRef hWnd, HandleRef hWndInsertAfter, int x, int y, int cx, int cy,
int flags);
private struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
}