Winforms - 如何让MessageBox以MainForm为中心?

Gre*_*reg 48 messagebox winforms

Winforms - 如何使对话框显示在MainForm的中心?这与基于普通窗口默认值相反,后者将它们呈现在屏幕的中心.

在我的情况下,我有一个小的主要形式,例如可能位于角落,消息框弹出窗口显示似乎有一些方法.

Han*_*ant 64

可以使用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; }
}
Run Code Online (Sandbox Code Playgroud)

样品用法:

    private void button1_Click(object sender, EventArgs e) {
        using (new CenterWinDialog(this)) {
            MessageBox.Show("Nobugz waz here");
        }
    }
Run Code Online (Sandbox Code Playgroud)

请注意,此代码适用于任何Windows对话框.MessageBox,OpenFormDialog,FolderBrowserDialog,PrintDialog,ColorDialog,FontDialog,PageSetupDialog,SaveFileDialog.

  • 您需要对此进行一个小的修复...如果最小化主窗口,它将使消息框混乱。可以通过将“ if(owner.WindowState!= FormWindowState.Minimized)”放置在构造器中的“ owner.BeginInvoke”之前来避免这种情况,从而避免了这种情况。 (2认同)
  • 我们向师尊顶礼!\&lt;^_^&gt;/ 最优秀的先生,十二国感谢您。 (2认同)