Winforms – 如何使MessageBox出现在MainForm中心?

Winforms – 如何使对话框出现在MainForm中心? 这是相反,基于正常的Windows默认呈现在屏幕的中心。

在我的情况下,我有一个小的主窗体,例如可以放置在一个angular落,消息框popup窗口显示什么似乎离开。

有些P / Invoke和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对话框。 MessageBox,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来使用这个,至less,如果你想要打开/保存对话框。

我试着查看NMHDR的通知代码和hwndFrom,然后确定它同样有效,而且更容易,而不是。 如果您真的想要非常具体,请告诉FindWindow查找您要查找的窗口的唯一标题(标题)。

在屏幕上绘制消息框之前触发,所以如果您设置一个全局标志来指示何时由您的代码执行操作,并查找唯一的标题,则确保您执行的操作只会发生一次(可能会有多个通知程序)。 我没有详细探讨这一点,但我pipe理得到CreateWindow把一个编辑框放在一个消息框对话框/它看起来像一个老鼠的耳朵嫁接到一个克隆猪的脊柱不合适,但它的作品。 以这种方式做事可能比自己做起来要容易得多。

乌鸦。

编辑:小的更正,以确保正确的窗口处理。 确保父母的手柄一致,这应该工作。 它对我来说,即使有两个相同的程序实例…

写你自己的消息框。 表单和标签应该这样做。 还是你还需要全球化呢?

certificate该类别适用于其他两种情况。 我有一个FolderBrowserDialog,我想要更大,我想它靠近父对话框的左上angular(靠近button,我点击打开它)。

我复制了CenterWinDialog类,并创build了两个新类。 一个类改变对话框的大小,另一个改变它的位置到父窗体的特定偏移量。 这是用法:

  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; } }