|
Hello, Is there any way to show MessageBox dialog in some particular place on the screen (except write your own MessageBox)? I saw some similar problems and solutions but with Visual Basic. I need it for C#. Thanks, Regards, Renat - Moved byTaylorMichaelLMVPTuesday, October 06, 2009 7:00 PMWinForms related (From:Visual C# General)
-
| | Renat.I Tuesday, October 06, 2009 5:07 PM | 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; } } Sample usage: private void button1_Click(object sender, EventArgs e) { using (new CenterWinDialog(this)) { MessageBox.Show("Nobugz waz here"); } } Note that this code works for any of the Windows dialogs. MessageBox, OpenFormDialog, FolderBrowserDialog, PrintDialog, ColorDialog, FontDialog, PageSetupDialog, SaveFileDialog.
Hans Passant.- Marked As Answer byRenat.I Wednesday, October 07, 2009 8:56 AM
-
| | nobugz Tuesday, October 06, 2009 6:32 PM | No. The only solution is to create your own. There's 21 overloads of the only method MessageBox exposes (the Show method), and none of them will allow you to pass in information regarding X/Y placement. Coding Light - Illuminated Ideas and Algorithms in SoftwareCoding Light Wiki � LinkedIn � ForumsBrowser | | David M Morton Tuesday, October 06, 2009 5:09 PM | You could use FindWindow() and MoveWindow()/SetWindowPos() Win32 API...
| | Matt Wise Tuesday, October 06, 2009 5:19 PM | 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; } } Sample usage: private void button1_Click(object sender, EventArgs e) { using (new CenterWinDialog(this)) { MessageBox.Show("Nobugz waz here"); } } Note that this code works for any of the Windows dialogs. MessageBox, OpenFormDialog, FolderBrowserDialog, PrintDialog, ColorDialog, FontDialog, PageSetupDialog, SaveFileDialog.
Hans Passant.- Marked As Answer byRenat.I Wednesday, October 07, 2009 8:56 AM
-
| | nobugz Tuesday, October 06, 2009 6:32 PM | Nobugz, thanks! It works and very simple to use (but not to understand for me although;) Regards, | | Renat.I Wednesday, October 07, 2009 8:56 AM |
|