title: MessageBox with custom font?
body: <p>Is there an easy way to display a custom font for a MessageBox?</p>
  
  <p>For "easy way" I mean using WinAPI or other techniques but not coding a entire messagebox from scratch.</p>
  
  <p>I've seen lots of custom messagebox but most are just forms which don't preserve default messagebox additional parametters, other custom messagebox just has their size/bounds wrong so the "ok" button is cutted or not right alligned, and other custom messagebox has their own problems/bugs.</p>
  
  <p>I hope if is possibly to add a generic parametter to instance this great custom messagebox setting the desired font:</p>
  
  <p>The original code is a C# custom messagebox class of <strong>@Hans Passant</strong> which I've taken a lot time ago from here <a href="https://stackoverflow.com/questions/2576156/winforms-how-can-i-make-messagebox-appear-centered-on-mainform">Winforms-How can I make MessageBox appear centered on MainForm?</a> and translated it using an online translator:</p>
  
  <pre><code>' [ Centered Messagebox ]
  '
  ' Examples :
  '
  ' Using New MessageBox_Centered(Me)
  '     MessageBox.Show("Test Text", "Test Title", MessageBoxButtons.OK)
  ' End Using
  
  #Region " Centered MessageBox Class"
  
  Imports System.Runtime.InteropServices
  Imports System.Text
  
  Class MessageBox_Centered
  Implements IDisposable
  
  ' P/Invoke
  Public Class NativeMethods
  
      Delegate Function EnumThreadWndProc(hWnd As IntPtr, lp As IntPtr) As Boolean
  
      &lt;DllImport("user32.dll")&gt; _
      Shared Function EnumThreadWindows(tid As Integer, callback As EnumThreadWndProc, lp As IntPtr) As Boolean
      End Function
  
      &lt;DllImport("kernel32.dll")&gt; _
      Shared Function GetCurrentThreadId() As Integer
      End Function
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)&gt; _
      Shared Function GetClassName(hWnd As IntPtr, buffer As StringBuilder, buflen As Integer) As Integer
      End Function
  
      &lt;DllImport("user32.dll")&gt; _
      Shared Function GetWindowRect(hWnd As IntPtr, ByRef rc As RECT) As Boolean
      End Function
  
      &lt;DllImport("user32.dll")&gt; _
      Shared Function MoveWindow(hWnd As IntPtr, x As Integer, y As Integer, w As Integer, h As Integer, repaint As Boolean) As Boolean
      End Function
  
      Structure RECT
          Public Left As Integer
          Public Top As Integer
          Public Right As Integer
          Public Bottom As Integer
      End Structure
  
  End Class
  
  Private mTries As Integer = 0
  Private mOwner As Form
  
  Public Sub New(owner As Form)
      mOwner = owner
      owner.BeginInvoke(New MethodInvoker(AddressOf findDialog))
  End Sub
  
  Private Sub findDialog()
  
      ' Enumerate windows to find the message box
      If mTries &lt; 0 Then Return
  
      Dim callback As New NativeMethods.EnumThreadWndProc(AddressOf checkWindow)
      If NativeMethods.EnumThreadWindows(NativeMethods.GetCurrentThreadId(), callback, IntPtr.Zero) Then
          If System.Threading.Interlocked.Increment(mTries) &lt; 10 Then
              mOwner.BeginInvoke(New MethodInvoker(AddressOf findDialog))
          End If
      End If
  
  End Sub
  
  Private Function checkWindow(hWnd As IntPtr, lp As IntPtr) As Boolean
  
      ' Checks if &lt;hWnd&gt; is a dialog
      Dim sb As New StringBuilder(260)
      NativeMethods.GetClassName(hWnd, sb, sb.Capacity)
      If sb.ToString() &lt;&gt; "#32770" Then Return True
  
      ' Got it
      Dim frmRect As New Rectangle(mOwner.Location, mOwner.Size)
      Dim dlgRect As NativeMethods.RECT
      NativeMethods.GetWindowRect(hWnd, dlgRect)
      NativeMethods.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
  
  End Function
  
  Public Sub Dispose() Implements IDisposable.Dispose
      mTries = -1
  End Sub
  
  End Class
  
  #End Region
  </code></pre>
  
  <blockquote>
    <p>UPDATE:</p>
  </blockquote>
  
  <p>Trying to adapt @Pete supposed solution just I can't do it.</p>
  
  <pre><code>Class MessageBox_Centered : Implements IDisposable
  
  Public Class NativeMethods
  
      Delegate Function EnumThreadWndProc(hWnd As IntPtr, lp As IntPtr) As Boolean
      Delegate Function EnumWindowsProc(hWnd As IntPtr, lp As IntPtr) As Boolean
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function EnumThreadWindows(tid As Integer, callback As EnumThreadWndProc, lp As IntPtr) As Boolean
      End Function
  
      &lt;DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function GetCurrentThreadId() As Integer
      End Function
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function GetClassName(hWnd As IntPtr, buffer As StringBuilder, buflen As Integer) As Integer
      End Function
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function GetWindowRect(hWnd As IntPtr, ByRef rc As RECT) As Boolean
      End Function
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function MoveWindow(hWnd As IntPtr, x As Integer, y As Integer, w As Integer, h As Integer, repaint As Boolean) As Boolean
      End Function
  
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
      End Function
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function EnumChildWindows(hwndParent As IntPtr, lpEnumFunc As EnumWindowsProc, lParam As IntPtr) As &lt;MarshalAs(UnmanagedType.Bool)&gt; Boolean
      End Function
  
      &lt;DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)&gt; _
      Shared Function SendMessage(hWnd As IntPtr, Msg As UInt32, wParam As IntPtr, lParam As IntPtr) As IntPtr
      End Function
  
      Structure RECT
          Public Left As Integer
          Public Top As Integer
          Public Right As Integer
          Public Bottom As Integer
      End Structure
  
  End Class
  
  Private mTries As Integer = 0
  Private mOwner As Form
  
  Public Sub New(owner As Form)
      mOwner = owner
      owner.BeginInvoke(New MethodInvoker(AddressOf findDialog))
  End Sub
  
  Private Sub findDialog()
  
      ' Enumerate windows to find the message box
      If mTries &lt; 0 Then Return
  
      Dim callback As New NativeMethods.EnumThreadWndProc(AddressOf checkWindow)
      If NativeMethods.EnumThreadWindows(NativeMethods.GetCurrentThreadId(), callback, IntPtr.Zero) Then
          If System.Threading.Interlocked.Increment(mTries) &lt; 10 Then
              mOwner.BeginInvoke(New MethodInvoker(AddressOf findDialog))
          End If
      End If
  
  End Sub
  
  Private Function checkWindow(hWnd As IntPtr, lp As IntPtr) As Boolean
  
      ' Checks if &lt;hWnd&gt; is a dialog
      Dim sb As New StringBuilder(260)
      NativeMethods.GetClassName(hWnd, sb, sb.Capacity)
      If sb.ToString() &lt;&gt; "#32770" Then
          Return True
      End If
  
  
      ' Got it
      Dim frmRect As New Rectangle(mOwner.Location, mOwner.Size)
      Dim dlgRect As NativeMethods.RECT
      NativeMethods.GetWindowRect(hWnd, dlgRect)
      NativeMethods.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)
  
      ' Dim wndText As New StringBuilder()
      ' NativeMethods.GetWindowText(hWnd2, wndText, 1000)
      ' SendMessage(hWnd2, WM_SETFONT, f.ToHfont(), new IntPtr(1))
  
      Return False
  
  End Function
  
  Public Sub Dispose() Implements IDisposable.Dispose
      mTries = -1
  End Sub
  
  End Class
  </code></pre>
  
  <blockquote>
    <p>UPDATE 2:</p>
  </blockquote>
  
  <p>This is an explanation of what I need to do.</p>
  
  <p>Taking the code snippet of @Hans Passant, the centered messagebox, I need to launch it (instance it) but with a custom font.</p>
  
  <p>An example could be creating a generic function <strong>into the Centered Messagebox</strong> maybe using the "new" block of the Class to pass the desired font as an argument then do the necessary things with that font to show the messagebox centered + with a custom font.</p>
  
  <p>So what I need is to extend the class by adding the possibility of using custom fonts.</p>