Winforms-如何使 MessageBox 以 MainForm 为中心显示? [英] Winforms-How can I make MessageBox appear centered on MainForm?
问题描述
Winforms-如何使对话框以 MainForm 为中心显示?这与基于将它们呈现在屏幕中央的普通窗口默认值相反.
Winforms-How can I make dialog boxes appear centered on MainForm? That is as opposed to be based on Normal windows default which renders them in the centre of the screen.
在我的例子中,我有一个小的主窗体,例如,它可能被放置在一个角落里,MessageBox 弹出窗口显示在很远的地方.
In my case I have a small main form that may for example be positioned in a corner, the the MessageBox popup is displayed what seems a ways away.
推荐答案
使用 P/Invoke 的一些服务和 Control.BeginInvoke() 提供的魔法是可能的.向您的项目添加一个新类并粘贴以下代码:
It is possible with some servings of P/Invoke and the magic provided by Control.BeginInvoke(). Add a new class to your project and paste this code:
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.
Note that this code works for any of the Windows dialogs. MessageBox, OpenFormDialog, FolderBrowserDialog, PrintDialog, ColorDialog, FontDialog, PageSetupDialog, SaveFileDialog.
这篇关于Winforms-如何使 MessageBox 以 MainForm 为中心显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!