(view source code of richtextmessagebox.cs as plain text)
using System;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Timers;
using System.Windows.Forms;
namespace RobvanderWoude{ class RichTextMessageBox {static readonly string progver = "1.03";
#region Global Default Valuesstatic readonly int defaultbuttonheight = 25;
static readonly int defaultbuttonwidth = 100;
static readonly string defaultfontfamily = "Sans-Serif";
static readonly float defaultfontsize = 12;
static readonly FontStyle defaultfontstyle = FontStyle.Regular;
static readonly Color defaulttextcolor = Color.Black;
static readonly string defaulttitle = string.Format( "RichTextMessageBox, Version {0}", progver );
static readonly int defaultwindowheight = 480;
static readonly int defaultwindowwidth = 640;
static readonly int screenheight = Screen.PrimaryScreen.Bounds.Height;
static readonly int screenwidth = Screen.PrimaryScreen.Bounds.Width;
#endregion Global Default Values #region Global Variablesstatic Form rtmbform;
static RichTextBox rtmbox;
static string button1text = "OK";
static string button2text = string.Empty;
static string button3text = string.Empty;
static string buttonclickedtext = "Cancel";
static int buttonclickednumber = -1;
static int buttoncount = 1;
static int buttonheight = defaultbuttonheight;
static int buttonwidth = defaultbuttonwidth;
static int defaultbutton = -1;
static string message = string.Empty;
static string title = string.Empty;
static double timeout = 0;
static bool timeoutelapsed = false;
static System.Timers.Timer timer;
static int windowheight = defaultwindowheight;
static int windowwidth = defaultwindowwidth;
#endregion Global Variables[STAThread]
static int Main( string[] args )
{ #region Initial Valuesint windowx = -1;
int windowy = -1;
string fontfamily = defaultfontfamily;
float fontsize = defaultfontsize;
FontStyle fontstyle = defaultfontstyle;
bool literal = false;
bool showhelp = false;
bool showintaskbar = false;
Color textcolor = defaulttextcolor;
bool topmost = false;
#endregion Initial Values #region Parse Command Lineif ( args.Length == 0 || args.Contains( "/?" ) )
{showhelp = true;
}foreach ( string arg in args )
{if ( arg.Length > 2 && ( arg[0] == '/' || arg[0] == '-' ) )
{if ( arg.IndexOf( ':' ) > 1 )
{string key = arg.ToUpper( ).Substring( 1, arg.IndexOf( ':' ) - 1 );
string val = arg.Substring( arg.IndexOf( ':' ) + 1 );
switch ( key )
{case "B1": // /B1:"text for button 1"
button1text = val;
break;
case "B2": // /B2:"text for button 2"
button2text = val;
buttoncount = 2;
break;
case "B3": // /B3:"text for button 3"
button3text = val;
buttoncount = 3;
break;
case "BH": // /BH:button_height
if ( !int.TryParse( val, out buttonheight ) )
{showhelp = true;
}break;
case "BW": // /BW:button_width
if ( !int.TryParse( val, out buttonwidth ) )
{showhelp = true;
}break;
case "C": // /C"text_color"
try {textcolor = Color.FromName( val ); // if FromName does not recognize the value of val as color it will return black
}catch ( Exception )
{showhelp = true;
}break;
case "DB": // /DB:default_button (1 is always valid, 2 or 3 only if there are that many buttons)
if ( !int.TryParse( val, out defaultbutton ) )
{if ( val.ToUpper( ) == button1text.ToUpper( ) )
{defaultbutton = 1;
}else if ( val.ToUpper( ) == button2text.ToUpper( ) )
{defaultbutton = 2;
}else if ( val.ToUpper( ) == button3text.ToUpper( ) )
{defaultbutton = 3;
} else {showhelp = true;
} }break;
case "FONT":
fontfamily = val;
try {FontFamily testfont = new FontFamily( fontfamily );
} catch {showhelp = true;
}break;
case "FS": // /FS:font_size
if ( !float.TryParse( val, out fontsize ) )
{showhelp = true;
}break;
case "T": // /T:timeout_seconds
if ( !double.TryParse( val, out timeout ) )
{showhelp = true;
}timeout *= 1000; // specified in seconds, timer requires milliseconds
break;
case "WH": // /WH:window_height
if ( !int.TryParse( val, out windowheight ) )
{showhelp = true;
}break;
case "WW": // /WW:window_width
if ( !int.TryParse( val, out windowwidth ) )
{showhelp = true;
}break;
case "X": // /X:X_coordinate of upper left window corner
if ( !int.TryParse( val, out windowx ) )
{showhelp = true;
}break;
case "Y": // /Y:Y_coordinate of upper left window corner
if ( !int.TryParse( val, out windowy ) )
{showhelp = true;
}break;
} } else {switch ( arg.ToUpper( ).Substring( 1 ) )
{case "ALWAYSONTOP":
case "MODAL":
case "TOPMOST":
topmost = true;
break;
case "BOLD":
fontstyle |= FontStyle.Bold;
break;
case "ITALIC":
case "ITALICS":
fontstyle |= FontStyle.Italic;
break;
case "LITERAL":
literal = true;
break;
case "SHOWINTASKBAR":
case "TASKBAR":
showintaskbar = true;
break;
case "STRIKE":
case "STRIKEOUT":
fontstyle |= FontStyle.Strikeout;
break;
case "UNDERLINE":
case "UNDERLINED":
fontstyle |= FontStyle.Underline;
break;
default:
showhelp = true;
break;
} } } else {if ( string.IsNullOrWhiteSpace( message ) )
{message = arg; // the message to be displayed in the dialog
}else if ( string.IsNullOrWhiteSpace( title ) )
{title = arg; // the title of the dialog window
} else {showhelp = true;
} } } #endregion Parse Command Line #region Validate Command Line Settingsif ( !literal && !string.IsNullOrWhiteSpace( message ) )
{message = UnEscapeString( message );
} // Check mandatory button text, and if default button number is validif ( string.IsNullOrWhiteSpace( message ) )
{showhelp = true;
}if ( string.IsNullOrWhiteSpace( title ) )
{title = defaulttitle;
}if ( string.IsNullOrWhiteSpace( button1text ) )
{showhelp = true;
}if ( string.IsNullOrWhiteSpace( button2text ) && defaultbutton > 1 )
{showhelp = true;
}if ( string.IsNullOrWhiteSpace( button3text ) && defaultbutton > 2 )
{showhelp = true;
}if ( showhelp )
{ShowHelp( );
// Restore defaults before showing help in GUIbutton1text = "OK";
button2text = string.Empty;
button3text = string.Empty;
buttonheight = defaultbuttonheight;
buttonwidth = defaultbuttonwidth;
fontfamily = "Courier New";
fontsize = 10; // slightly smaller font to fit in the help text
fontstyle = defaultfontstyle;
textcolor = defaulttextcolor;
title = defaulttitle;
windowheight = defaultwindowheight;
windowwidth = defaultwindowwidth;
windowx = Convert.ToInt32( ( screenwidth - defaultwindowwidth ) / 2 );
windowy = Convert.ToInt32( ( screenheight - defaultwindowheight ) / 2 );
} else {windowheight = Math.Min( windowheight, screenheight );
windowwidth = Math.Min( windowwidth, screenwidth );
if ( windowx == -1 )
{windowx = Convert.ToInt32( ( screenwidth - windowwidth ) / 2 );
}if ( windowy == -1 )
{windowy = Convert.ToInt32( ( screenheight - windowheight ) / 2 );
}windowx = Math.Min( windowx, screenwidth - windowwidth );
windowy = Math.Min( windowy, screenheight - windowheight );
} #endregion Validate Command Line Settings #region Prepare Dialog Form // The dialog form itselfrtmbform = new Form
{ Text = title,ClientSize = new Size( windowwidth, windowheight ),
Location = new Point( windowx, windowy ),
MaximizeBox = false,
SizeGripStyle = SizeGripStyle.Hide,
ShowInTaskbar = showintaskbar,StartPosition = FormStartPosition.Manual,
TopMost = topmost,WindowState = FormWindowState.Normal
};
rtmbform.BringToFront( );
// The rich text boxrtmbox = new RichTextBox
{ Text = message,Height = ( windowheight - buttonheight - 30 ),
Width = ( windowwidth - 20 ),
Font = new Font( fontfamily, fontsize, fontstyle ),
ForeColor = textcolor,Location = new Point( 10, 10 ),
ReadOnly = true
};
rtmbform.Controls.Add( rtmbox );
// Button 1Button button1 = new Button
{ Text = button1text, Height = buttonheight, Width = buttonwidth,Location = ButtonLocation( 1 )
};
button1.Click += Button1_Click;
rtmbform.Controls.Add( button1 );
if ( defaultbutton == 1 )
{rtmbform.AcceptButton = button1;
button1.Focus( );
} // Optional button 2if ( !string.IsNullOrWhiteSpace( button2text ) )
{Button button2 = new Button
{ Text = button2text, Height = buttonheight, Width = buttonwidth,Location = ButtonLocation( 2 )
};
button2.Click += Button2_Click;
rtmbform.Controls.Add( button2 );
if ( defaultbutton == 2 )
{rtmbform.AcceptButton = button2;
button2.Focus( );
} // Optional button 3, only if button 2 is also specifiedif ( !string.IsNullOrWhiteSpace( button3text ) )
{Button button3 = new Button
{ Text = button3text, Height = buttonheight, Width = buttonwidth,Location = ButtonLocation( 3 )
};
button3.Click += Button3_Click;
rtmbform.Controls.Add( button3 );
if ( defaultbutton == 3 )
{rtmbform.AcceptButton = button3;
button3.Focus( );
} } } #endregion Prepare Dialog Form // Optional timer for timeout featureif ( timeout > 0 )
{timer = new System.Timers.Timer( );
timer.Elapsed += new ElapsedEventHandler( Timer_Elapsed );
timer.Interval = timeout;
timer.Start( );
} // Show dialog windowrtmbform.ShowDialog( );
// Interpret the result to be returnedif ( timeoutelapsed )
{buttonclickednumber = defaultbutton;
switch ( defaultbutton )
{case 1:
buttonclickedtext = button1text;
break;
case 2:
buttonclickedtext = button2text;
break;
case 3:
buttonclickedtext = button3text;
break;
default:
buttonclickedtext = "Timeout";
buttonclickednumber = 4;
break;
} }if ( showhelp )
{return -1;
} else {Console.WriteLine( buttonclickedtext );
return buttonclickednumber;
} }private static void Button1_Click( object sender, EventArgs e )
{buttonclickedtext = button1text;
buttonclickednumber = 1;
rtmbform.Close( );
}private static void Button2_Click( object sender, EventArgs e )
{buttonclickedtext = button2text;
buttonclickednumber = 2;
rtmbform.Close( );
}private static void Button3_Click( object sender, EventArgs e )
{buttonclickedtext = button3text;
buttonclickednumber = 3;
rtmbform.Close( );
}public static void Timer_Elapsed( object sender, System.EventArgs e )
{timeoutelapsed = true;
FormClose( );
}private static void FormClose()
{if ( rtmbform.InvokeRequired )
{FormCloseCallback fccb = new FormCloseCallback( FormClose );
rtmbform.Invoke( fccb );
} else {rtmbform.Close( );
} }delegate void FormCloseCallback( );
private static Point ButtonLocation( int button )
{Point location = new Point( );
switch ( buttoncount )
{case 1:
location.X = ( windowwidth - buttonwidth ) / 2; // center
break;
case 2:
if ( button == 1 )
{location.X = windowwidth / 2 - buttonwidth - 10; // left
} else {location.X = windowwidth / 2 + buttonwidth + 10; // right
}break;
case 3:
if ( button == 1 )
{location.X = ( windowwidth - buttonwidth ) / 2 - buttonwidth - 10; // left
}else if ( button == 2 )
{location.X = ( windowwidth - buttonwidth ) / 2; // center
} else {location.X = ( windowwidth - buttonwidth ) / 2 + buttonwidth + 10; // right
}break;
}location.Y = windowheight - buttonheight - 10;
return location;
}static string UnEscapeString( string message )
{ // Unescaping tabs, linefeeds and quotesmessage = message.Replace( "\\n", "\n" );
message = message.Replace( "\\r", "\r" );
message = message.Replace( "\\t", "\t" );
message = message.Replace( "\\007", "\t" );
message = message.Replace( "\\012", "\n" );
message = message.Replace( "\\015", "\r" );
message = message.Replace( "\\042", "\"" );
message = message.Replace( "\\047", "'" );
// Unescaping Unicode, technique by "dtb" on StackOverflow.com: http://stackoverflow.com/a/8558748message = Regex.Replace( message, @"\\[Uu]([0-9A-Fa-f]{4})", m => char.ToString( (char) ushort.Parse( m.Groups[1].Value, NumberStyles.AllowHexSpecifier ) ) );
return message;
}static void ShowHelp( )
{ /* RichTextMessageBox, Version 1.00 Show a fully customizable message dialog and return which button is clicked Usage: RichTextMessageBox.exe message [ title ] [ options ] message is the text to be displayed in the dialog title is the dialog's window title (default: program name and version) Options: /AlwaysOnTop Modal window, always on top /B1:"caption" Caption for button 1 (default: OK) /B2:"caption" Caption for button 2 (default: empty) /B3:"caption" Caption for button 3 (default: empty) /BH:height Button height (default: 25) /Bold Bold text for message /BW:width Button width (default: 100) /C:color Text color for dialog (default: Black) /DB:default Default button (default: 1; values 2 or 3 are valid only if there are that many buttons) /Font:name Font family name (default: Sans-Serif) /FS:fontsize Font size (default: 12) /Italic Italic text for message /Literal Treat message as literal, do not interpret special characters \n, \012, \t, \007 or unicode \u**** (default: interpret special characters and unicode) /Strike Strikeout text /T:seconds Timeout in seconds (default: no timeout) /Taskbar Show in taskbar /Underline Underline text /WH:height Window height (default: 480) /WW:width Window width (default: 640) /X:x X-coordinate of upper left window corner /Y:y Y-coordinate of upper left window corner (default: center window on screen) Notes: The caption of the button that is clicked will be sent to the console, the number of the button is returned as "errorlevel". In case of errors, the "errorlevel" will be -1, if a timeout elapsed and no default button was specified, the "errorlevel" will be 4, and the text "Timeout" is sent to the console. If an invalid text color is specified, it will be ignored. Written by Rob van der Woude https://www.robvanderwoude.com/ */message = string.Format( "RichTextMessageBox, Version {0}\n", progver );
message += "Show a fully customizable message dialog and return which button is clicked\n\n";
message += "Usage: RichTextMessageBox.exe message [ title ] [ options ]\n\n";
message += " message is the text to be displayed in the dialog\n";
message += " title is the dialog's window title\n";
message += " (default: program name and version)\n\n";
message += "Options: /AlwaysOnTop Modal window, always on top\n";
message += " /B1:\"caption\" Caption for button 1 (default: OK)\n";
message += " /B2:\"caption\" Caption for button 2 (default: empty)\n";
message += " /B3:\"caption\" Caption for button 3 (default: empty)\n";
message += string.Format( " /BH:height Button height (default: {0})\n", defaultbuttonheight );
message += " /Bold Bold text for message\n";
message += string.Format( " /BW:width Button width (default: {0})\n", defaultbuttonwidth );
message += " /C:color Text color for dialog (default: Black)\n";
message += " /DB:default Default button (default: 1; values 2 or 3 are\n";
message += " valid only if there are that many buttons)\n";
message += string.Format( " /Font:name Font family name (default: {0})\n", defaultfontfamily );
message += string.Format( " /FS:fontsize Font size (default: {0})\n", defaultfontsize );
message += " /Italic Italic text for message\n";
message += " /Literal Treat message as literal, do not interpret special\n";
message += " characters \\n, \\012, \\t, \\007 or unicode \\u****\n";
message += " (default: interpret special chars and unicode)\n";
message += " /Strike Strikeout text\n";
message += " /T:seconds Timeout in seconds (default: no timeout)\n";
message += " /Taskbar Show in taskbar\n";
message += " /Underline Underline text\n";
message += string.Format( " /WH:height Window height (default: {0})\n", defaultwindowheight );
message += string.Format( " /WW:width Window width (default: {0})\n", defaultwindowwidth );
message += " /X:x X-coordinate of upper left window corner\n";
message += " /Y:y Y-coordinate of upper left window corner\n";
message += " (default: center window on screen)\n\n";
message += "Notes: The caption of the button that is clicked will be sent to the\n";
message += " console, the number of the button is returned as \"errorlevel\".\n";
message += " In case of errors, the \"errorlevel\" will be -1, if a timeout\n";
message += " elapsed and no default button was specified, the \"errorlevel\"\n";
message += " will be 4, and the text \"Timeout\" is sent to the console.\n";
message += " If an invalid text color is specified, it will be ignored.\n\n";
message += "Written by Rob van der Woude\n";
message += "https://www.robvanderwoude.com/";
Console.Error.WriteLine( message );
} }}page last modified: 2025-10-11; loaded in 0.0119 seconds