Windows Develop Bookmark and Share   
 index > Windows Forms General > MessageBox position
 

MessageBox position

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 Software
Coding 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

You can use google to search for other answers

Custom Search

More Threads

• Designer won't let me look at two forms
• Windows Forms Whidbey Chat Today
• How to enable Ctrl+C, Ctrl+V, Ctrl+X in a text box?
• Tool strip control is not aligned to left
• Newbie question: Controlling the styles of fonts etc. in an application
• Vertical Datagrid
• How to refresh ListBOx after Update
• MdiList-property in VS2005 ???
• Unable to change size property...
• RegionMaster C# to VB.NET References