Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for richtextmessagebox.cs

(view source code of richtextmessagebox.cs as plain text)

  1. using System;
  2. using System.Drawing;
  3. using System.Linq;
  4. using System.Timers;
  5. using System.Windows.Forms;
  6.  
  7.  
  8. namespace RobvanderWoude
  9. {
  10. 	class RichTextMessageBox
  11. 	{
  12. 		static readonly string progver = "1.02";
  13.  
  14.  
  15. 		#region Global Default Values
  16.  
  17. 		static readonly int defaultbuttonheight = 25;
  18. 		static readonly int defaultbuttonwidth = 100;
  19. 		static readonly string defaultfontfamily = "Sans-Serif";
  20. 		static readonly float defaultfontsize = 12;
  21. 		static readonly FontStyle defaultfontstyle = FontStyle.Regular;
  22. 		static readonly Color defaulttextcolor = Color.Black;
  23. 		static readonly string defaulttitle = string.Format( "RichTextMessageBox,  Version {0}", progver );
  24. 		static readonly int defaultwindowheight = 480;
  25. 		static readonly int defaultwindowwidth = 640;
  26. 		static readonly int screenheight = Screen.PrimaryScreen.Bounds.Height;
  27. 		static readonly int screenwidth = Screen.PrimaryScreen.Bounds.Width;
  28.  
  29. 		#endregion Global Default Values
  30.  
  31.  
  32. 		#region Global Variables
  33.  
  34. 		static Form rtmbform;
  35. 		static RichTextBox rtmbox;
  36. 		static string button1text = "OK";
  37. 		static string button2text = string.Empty;
  38. 		static string button3text = string.Empty;
  39. 		static string buttonclickedtext = "Cancel";
  40. 		static int buttonclickednumber = -1;
  41. 		static int buttoncount = 1;
  42. 		static int buttonheight = defaultbuttonheight;
  43. 		static int buttonwidth = defaultbuttonwidth;
  44. 		static int defaultbutton = -1;
  45. 		static string message = string.Empty;
  46. 		static string title = string.Empty;
  47. 		static double timeout = 0;
  48. 		static bool timeoutelapsed = false;
  49. 		static System.Timers.Timer timer;
  50. 		static int windowheight = defaultwindowheight;
  51. 		static int windowwidth = defaultwindowwidth;
  52.  
  53. 		#endregion Global Variables
  54.  
  55.  
  56. 		[STAThread]
  57. 		static int Main( string[] args )
  58. 		{
  59. 			#region Initial Values
  60.  
  61. 			int windowx = -1;
  62. 			int windowy = -1;
  63. 			string fontfamily = defaultfontfamily;
  64. 			float fontsize = defaultfontsize;
  65. 			FontStyle fontstyle = defaultfontstyle;
  66. 			bool showhelp = false;
  67. 			bool showintaskbar = false;
  68. 			Color textcolor = defaulttextcolor;
  69. 			bool topmost = false;
  70.  
  71. 			#endregion Initial Values
  72.  
  73.  
  74. 			#region Parse Command Line
  75.  
  76. 			if ( args.Length == 0 || args.Contains( "/?" ) )
  77. 			{
  78. 				showhelp = true;
  79. 			}
  80.  
  81. 			foreach ( string arg in args )
  82. 			{
  83. 				if ( arg.Length > 2 && ( arg[0] == '/' || arg[0] == '-' ) )
  84. 				{
  85. 					if ( arg.IndexOf( ':' ) > 1 )
  86. 					{
  87. 						string key = arg.ToUpper( ).Substring( 1, arg.IndexOf( ':' ) - 1 );
  88. 						string val = arg.Substring( arg.IndexOf( ':' ) + 1 );
  89. 						switch ( key )
  90. 						{
  91. 							case "B1": // /B1:"text for button 1"
  92. 								button1text = val;
  93. 								break;
  94. 							case "B2": // /B2:"text for button 2"
  95. 								button2text = val;
  96. 								buttoncount = 2;
  97. 								break;
  98. 							case "B3": // /B3:"text for button 3"
  99. 								button3text = val;
  100. 								buttoncount = 3;
  101. 								break;
  102. 							case "BH": // /BH:button_height
  103. 								if ( !int.TryParse( val, out buttonheight ) )
  104. 								{
  105. 									showhelp = true;
  106. 								}
  107. 								break;
  108. 							case "BW": // /BW:button_width
  109. 								if ( !int.TryParse( val, out buttonwidth ) )
  110. 								{
  111. 									showhelp = true;
  112. 								}
  113. 								break;
  114. 							case "C": // /C"text_color"
  115. 								try
  116. 								{
  117. 									textcolor = Color.FromName( val ); // if FromName does not recognize the value of val as color it will return black
  118. 								}
  119. 								catch ( Exception )
  120. 								{
  121. 									showhelp = true;
  122. 								}
  123. 								break;
  124. 							case "DB": // /DB:default_button (1 is always valid, 2 or 3 only if there are that many buttons)
  125. 								if ( !int.TryParse( val, out defaultbutton ) )
  126. 								{
  127. 									if ( val.ToUpper( ) == button1text.ToUpper( ) )
  128. 									{
  129. 										defaultbutton = 1;
  130. 									}
  131. 									else if ( val.ToUpper( ) == button2text.ToUpper( ) )
  132. 									{
  133. 										defaultbutton = 2;
  134. 									}
  135. 									else if ( val.ToUpper( ) == button3text.ToUpper( ) )
  136. 									{
  137. 										defaultbutton = 3;
  138. 									}
  139. 									else
  140. 									{
  141. 										showhelp = true;
  142. 									}
  143. 								}
  144. 								break;
  145. 							case "FONT":
  146. 								fontfamily = val;
  147. 								try
  148. 								{
  149. 									FontFamily testfont = new FontFamily( fontfamily );
  150. 								}
  151. 								catch
  152. 								{
  153. 									showhelp = true;
  154. 								}
  155. 								break;
  156. 							case "FS": // /FS:font_size
  157. 								if ( !float.TryParse( val, out fontsize ) )
  158. 								{
  159. 									showhelp = true;
  160. 								}
  161. 								break;
  162. 							case "T": // /T:timeout_seconds
  163. 								if ( !double.TryParse( val, out timeout ) )
  164. 								{
  165. 									showhelp = true;
  166. 								}
  167. 								timeout *= 1000; // specified in seconds, timer requires milliseconds
  168. 								break;
  169. 							case "WH": // /WH:window_height
  170. 								if ( !int.TryParse( val, out windowheight ) )
  171. 								{
  172. 									showhelp = true;
  173. 								}
  174. 								break;
  175. 							case "WW": // /WW:window_width
  176. 								if ( !int.TryParse( val, out windowwidth ) )
  177. 								{
  178. 									showhelp = true;
  179. 								}
  180. 								break;
  181. 							case "X": // /X:X_coordinate of upper left window corner
  182. 								if ( !int.TryParse( val, out windowx ) )
  183. 								{
  184. 									showhelp = true;
  185. 								}
  186. 								break;
  187. 							case "Y": // /Y:Y_coordinate of upper left window corner
  188. 								if ( !int.TryParse( val, out windowy ) )
  189. 								{
  190. 									showhelp = true;
  191. 								}
  192. 								break;
  193. 						}
  194. 					}
  195. 					else
  196. 					{
  197. 						switch ( arg.ToUpper( ).Substring( 1 ) )
  198. 						{
  199. 							case "ALWAYSONTOP":
  200. 							case "MODAL":
  201. 							case "TOPMOST":
  202. 								topmost = true;
  203. 								break;
  204. 							case "BOLD":
  205. 								fontstyle |= FontStyle.Bold;
  206. 								break;
  207. 							case "ITALIC":
  208. 							case "ITALICS":
  209. 								fontstyle |= FontStyle.Italic;
  210. 								break;
  211. 							case "SHOWINTASKBAR":
  212. 							case "TASKBAR":
  213. 								showintaskbar = true;
  214. 								break;
  215. 							case "STRIKE":
  216. 							case "STRIKEOUT":
  217. 								fontstyle |= FontStyle.Strikeout;
  218. 								break;
  219. 							case "UNDERLINE":
  220. 							case "UNDERLINED":
  221. 								fontstyle |= FontStyle.Underline;
  222. 								break;
  223. 							default:
  224. 								showhelp = true;
  225. 								break;
  226. 						}
  227. 					}
  228. 				}
  229. 				else
  230. 				{
  231. 					if ( string.IsNullOrWhiteSpace( message ) )
  232. 					{
  233. 						message = arg; // the message to be displayed in the dialog
  234. 					}
  235. 					else if ( string.IsNullOrWhiteSpace( title ) )
  236. 					{
  237. 						title = arg; // the title of the dialog window
  238. 					}
  239. 					else
  240. 					{
  241. 						showhelp = true;
  242. 					}
  243. 				}
  244. 			}
  245.  
  246. 			#endregion Parse Command Line
  247.  
  248.  
  249. 			#region Validate Command Line Settings
  250.  
  251. 			// Check mandatory button text, and if default button number is valid
  252. 			if ( string.IsNullOrWhiteSpace( message ) )
  253. 			{
  254. 				showhelp = true;
  255. 			}
  256.  
  257. 			if ( string.IsNullOrWhiteSpace( title ) )
  258. 			{
  259. 				title = defaulttitle;
  260. 			}
  261.  
  262. 			if ( string.IsNullOrWhiteSpace( button1text ) )
  263. 			{
  264. 				showhelp = true;
  265. 			}
  266.  
  267. 			if ( string.IsNullOrWhiteSpace( button2text ) && defaultbutton > 1 )
  268. 			{
  269. 				showhelp = true;
  270. 			}
  271.  
  272. 			if ( string.IsNullOrWhiteSpace( button3text ) && defaultbutton > 2 )
  273. 			{
  274. 				showhelp = true;
  275. 			}
  276.  
  277. 			if ( showhelp )
  278. 			{
  279. 				ShowHelp( );
  280. 				// Restore defaults before showing help in GUI
  281. 				button1text = "OK";
  282. 				button2text = string.Empty;
  283. 				button3text = string.Empty;
  284. 				buttonheight = defaultbuttonheight;
  285. 				buttonwidth = defaultbuttonwidth;
  286. 				fontfamily = "Courier New";
  287. 				fontsize = 10; // slightly smaller font to fit in the help text
  288. 				fontstyle = defaultfontstyle;
  289. 				textcolor = defaulttextcolor;
  290. 				title = defaulttitle;
  291. 				windowheight = defaultwindowheight;
  292. 				windowwidth = defaultwindowwidth;
  293. 				windowx = Convert.ToInt32( ( screenwidth - defaultwindowwidth ) / 2 );
  294. 				windowy = Convert.ToInt32( ( screenheight - defaultwindowheight ) / 2 );
  295. 			}
  296. 			else
  297. 			{
  298. 				windowheight = Math.Min( windowheight, screenheight );
  299. 				windowwidth = Math.Min( windowwidth, screenwidth );
  300. 				if ( windowx == -1 )
  301. 				{
  302. 					windowx = Convert.ToInt32( ( screenwidth - windowwidth ) / 2 );
  303. 				}
  304. 				if ( windowy == -1 )
  305. 				{
  306. 					windowy = Convert.ToInt32( ( screenheight - windowheight ) / 2 );
  307. 				}
  308. 				windowx = Math.Min( windowx, screenwidth - windowwidth );
  309. 				windowy = Math.Min( windowy, screenheight - windowheight );
  310. 			}
  311.  
  312. 			#endregion Validate Command Line Settings
  313.  
  314.  
  315. 			#region Prepare Dialog Form
  316.  
  317. 			// The dialog form itself
  318. 			rtmbform = new Form
  319. 			{
  320. 				Text = title,
  321. 				ClientSize = new Size( windowwidth, windowheight ),
  322. 				Location = new Point( windowx, windowy ),
  323. 				MaximizeBox = false,
  324. 				SizeGripStyle = SizeGripStyle.Hide,
  325. 				ShowInTaskbar = showintaskbar,
  326. 				StartPosition = FormStartPosition.Manual,
  327. 				TopMost = topmost,
  328. 				WindowState = FormWindowState.Normal
  329. 			};
  330. 			rtmbform.BringToFront( );
  331.  
  332. 			// The rich text box
  333. 			rtmbox = new RichTextBox
  334. 			{
  335. 				Text = message,
  336. 				Height = ( windowheight - buttonheight - 30 ),
  337. 				Width = ( windowwidth - 20 ),
  338. 				Font = new Font( fontfamily, fontsize, fontstyle ),
  339. 				ForeColor = textcolor,
  340. 				Location = new Point( 10, 10 ),
  341. 				ReadOnly = true
  342. 			};
  343. 			rtmbform.Controls.Add( rtmbox );
  344.  
  345. 			// Button 1
  346. 			Button button1 = new Button
  347. 			{
  348. 				Text = button1text,
  349. 				Height = buttonheight,
  350. 				Width = buttonwidth,
  351. 				Location = ButtonLocation( 1 )
  352. 			};
  353. 			button1.Click += Button1_Click;
  354. 			rtmbform.Controls.Add( button1 );
  355. 			if ( defaultbutton == 1 )
  356. 			{
  357. 				rtmbform.AcceptButton = button1;
  358. 				button1.Focus( );
  359. 			}
  360.  
  361. 			// Optional button 2
  362. 			if ( !string.IsNullOrWhiteSpace( button2text ) )
  363. 			{
  364. 				Button button2 = new Button
  365. 				{
  366. 					Text = button2text,
  367. 					Height = buttonheight,
  368. 					Width = buttonwidth,
  369. 					Location = ButtonLocation( 2 )
  370. 				};
  371. 				button2.Click += Button2_Click;
  372. 				rtmbform.Controls.Add( button2 );
  373. 				if ( defaultbutton == 2 )
  374. 				{
  375. 					rtmbform.AcceptButton = button2;
  376. 					button2.Focus( );
  377. 				}
  378.  
  379. 				// Optional button 3, only if button 2 is also specified
  380. 				if ( !string.IsNullOrWhiteSpace( button3text ) )
  381. 				{
  382. 					Button button3 = new Button
  383. 					{
  384. 						Text = button3text,
  385. 						Height = buttonheight,
  386. 						Width = buttonwidth,
  387. 						Location = ButtonLocation( 3 )
  388. 					};
  389. 					button3.Click += Button3_Click;
  390. 					rtmbform.Controls.Add( button3 );
  391. 					if ( defaultbutton == 3 )
  392. 					{
  393. 						rtmbform.AcceptButton = button3;
  394. 						button3.Focus( );
  395. 					}
  396. 				}
  397. 			}
  398.  
  399. 			#endregion Prepare Dialog Form
  400.  
  401.  
  402. 			// Optional timer for timeout feature
  403. 			if ( timeout > 0 )
  404. 			{
  405. 				timer = new System.Timers.Timer( );
  406. 				timer.Elapsed += new ElapsedEventHandler( Timer_Elapsed );
  407. 				timer.Interval = timeout;
  408. 				timer.Start( );
  409. 			}
  410.  
  411. 			// Show dialog window
  412. 			rtmbform.ShowDialog( );
  413.  
  414. 			// Interpret the result to be returned
  415. 			if ( timeoutelapsed )
  416. 			{
  417. 				buttonclickednumber = defaultbutton;
  418. 				switch ( defaultbutton )
  419. 				{
  420. 					case 1:
  421. 						buttonclickedtext = button1text;
  422. 						break;
  423. 					case 2:
  424. 						buttonclickedtext = button2text;
  425. 						break;
  426. 					case 3:
  427. 						buttonclickedtext = button3text;
  428. 						break;
  429. 					default:
  430. 						buttonclickedtext = "Timeout";
  431. 						buttonclickednumber = 4;
  432. 						break;
  433. 				}
  434. 			}
  435.  
  436. 			if ( showhelp )
  437. 			{
  438. 				return -1;
  439. 			}
  440. 			else
  441. 			{
  442. 				Console.WriteLine( buttonclickedtext );
  443. 				return buttonclickednumber;
  444. 			}
  445. 		}
  446.  
  447.  
  448. 		private static void Button1_Click( object sender, EventArgs e )
  449. 		{
  450. 			buttonclickedtext = button1text;
  451. 			buttonclickednumber = 1;
  452. 			rtmbform.Close( );
  453. 		}
  454.  
  455.  
  456. 		private static void Button2_Click( object sender, EventArgs e )
  457. 		{
  458. 			buttonclickedtext = button2text;
  459. 			buttonclickednumber = 2;
  460. 			rtmbform.Close( );
  461. 		}
  462.  
  463.  
  464. 		private static void Button3_Click( object sender, EventArgs e )
  465. 		{
  466. 			buttonclickedtext = button3text;
  467. 			buttonclickednumber = 3;
  468. 			rtmbform.Close( );
  469. 		}
  470.  
  471. 		public static void Timer_Elapsed( object sender, System.EventArgs e )
  472. 		{
  473. 			timeoutelapsed = true;
  474. 			FormClose( );
  475. 		}
  476.  
  477.  
  478. 		private static void FormClose()
  479. 		{
  480. 			if ( rtmbform.InvokeRequired )
  481. 			{
  482. 				FormCloseCallback fccb = new FormCloseCallback( FormClose );
  483. 				rtmbform.Invoke( fccb );
  484. 			}
  485. 			else
  486. 			{
  487. 				rtmbform.Close( );
  488. 			}
  489. 		}
  490.  
  491.  
  492. 		delegate void FormCloseCallback( );
  493.  
  494.  
  495. 		private static Point ButtonLocation( int button )
  496. 		{
  497. 			Point location = new Point( );
  498. 			switch ( buttoncount )
  499. 			{
  500. 				case 1:
  501. 					location.X = ( windowwidth - buttonwidth ) / 2; // center
  502. 					break;
  503. 				case 2:
  504. 					if ( button == 1 )
  505. 					{
  506. 						location.X = windowwidth / 2 - buttonwidth - 10; // left
  507. 					}
  508. 					else
  509. 					{
  510. 						location.X = windowwidth / 2 + buttonwidth + 10; // right
  511. 					}
  512. 					break;
  513. 				case 3:
  514. 					if ( button == 1 )
  515. 					{
  516. 						location.X = ( windowwidth - buttonwidth ) / 2 - buttonwidth - 10; // left
  517. 					}
  518. 					else if ( button == 2 )
  519. 					{
  520. 						location.X = ( windowwidth - buttonwidth ) / 2; // center
  521. 					}
  522. 					else
  523. 					{
  524. 						location.X = ( windowwidth - buttonwidth ) / 2 + buttonwidth + 10; // right
  525. 					}
  526. 					break;
  527. 			}
  528. 			location.Y = windowheight - buttonheight - 10;
  529. 			return location;
  530. 		}
  531.  
  532.  
  533. 		static void ShowHelp( )
  534. 		{
  535. 			/*
  536. 			RichTextMessageBox,  Version 1.00
  537. 			Show a fully customizable message dialog and return which button is clicked
  538.  
  539. 			Usage:    RichTextMessageBox.exe  message  [ title ]  [ options ]
  540.  
  541. 			          message       is the text to be displayed in the dialog
  542. 			          title         is the dialog's window title
  543. 									(default: program name and version)
  544.  
  545. 			Options:  /AlwaysOnTop  Modal window, always on top
  546. 			          /B1:"caption" Caption for button 1 (default: OK)
  547. 			          /B2:"caption" Caption for button 2 (default: empty)
  548. 			          /B3:"caption" Caption for button 3 (default: empty)
  549. 			          /BH:height    Button height (default: 25)
  550. 			          /Bold         Bold text for message
  551. 			          /BW:width     Button width (default: 100)
  552. 			          /C:color      Text color for dialog (default: Black)
  553. 			          /DB:default   Default button (default: 1; values 2 or 3 are
  554. 			                        valid only if there are that many buttons)
  555. 			          /Font:name    Font family name (default: Sans-Serif)
  556. 			          /FS:fontsize  Font size (default: 12)
  557. 			          /Italic       Italic text for message
  558. 			          /Strike       Strikeout text
  559. 			          /T:seconds    Timeout in seconds (default: no timeout)
  560. 			          /Taskbar      Show in taskbar
  561. 			          /Underline    Underline text
  562. 			          /WH:height    Window height (default: 480)
  563. 			          /WW:width     Window width (default: 640)
  564. 			          /X:x          X-coordinate of upper left window corner
  565. 			          /Y:y          Y-coordinate of upper left window corner
  566. 			                        (default: center window on screen)
  567.  
  568. 			Notes:    The caption of the button that is clicked will be sent to the
  569. 			          console, the number of the button is returned as "errorlevel".
  570. 			          In case of errors, the "errorlevel" will be -1, if a timeout
  571. 			          elapsed and no default button was specified, the "errorlevel"
  572. 			          will be 4, and the text "Timeout" is sent to the console.
  573. 			          If an invalid text color is specified, it will be ignored.
  574.  
  575. 			Written by Rob van der Woude
  576. 			https://www.robvanderwoude.com/
  577. 			*/
  578.  
  579. 			message = string.Format( "RichTextMessageBox,  Version {0}\n", progver );
  580. 			message += "Show a fully customizable message dialog and return which button is clicked\n\n";
  581. 			message += "Usage:    RichTextMessageBox.exe  message  [ title ]  [ options ]\n\n";
  582. 			message += "          message       is the text to be displayed in the dialog\n";
  583. 			message += "          title         is the dialog's window title\n";
  584. 			message += "                        (default: program name and version)\n\n";
  585. 			message += "Options:  /AlwaysOnTop  Modal window, always on top\n";
  586. 			message += "          /B1:\"caption\" Caption for button 1 (default: OK)\n";
  587. 			message += "          /B2:\"caption\" Caption for button 2 (default: empty)\n";
  588. 			message += "          /B3:\"caption\" Caption for button 3 (default: empty)\n";
  589. 			message += string.Format( "          /BH:height    Button height (default: {0})\n", defaultbuttonheight );
  590. 			message += "          /Bold         Bold text for message\n";
  591. 			message += string.Format( "          /BW:width     Button width (default: {0})\n", defaultbuttonwidth );
  592. 			message += "          /C:color      Text color for dialog (default: Black)\n";
  593. 			message += "          /DB:default   Default button (default: 1; values 2 or 3 are\n";
  594. 			message += "                        valid only if there are that many buttons)\n";
  595. 			message += string.Format( "          /Font:name    Font family name (default: {0})\n", defaultfontfamily );
  596. 			message += string.Format( "          /FS:fontsize  Font size (default: {0})\n", defaultfontsize );
  597. 			message += "          /Italic       Italic text for message\n";
  598. 			message += "          /Strike       Strikeout text\n";
  599. 			message += "          /T:seconds    Timeout in seconds (default: no timeout)\n";
  600. 			message += "          /Taskbar      Show in taskbar\n";
  601. 			message += "          /Underline    Underline text\n";
  602. 			message += string.Format( "          /WH:height    Window height (default: {0})\n", defaultwindowheight );
  603. 			message += string.Format( "          /WW:width     Window width (default: {0})\n", defaultwindowwidth );
  604. 			message += "          /X:x          X-coordinate of upper left window corner\n";
  605. 			message += "          /Y:y          Y-coordinate of upper left window corner\n";
  606. 			message += "                        (default: center window on screen)\n\n";
  607. 			message += "Notes:    The caption of the button that is clicked will be sent to the\n";
  608. 			message += "          console, the number of the button is returned as \"errorlevel\".\n";
  609. 			message += "          In case of errors, the \"errorlevel\" will be -1, if a timeout\n";
  610. 			message += "          elapsed and no default button was specified, the \"errorlevel\"\n";
  611. 			message += "          will be 4, and the text \"Timeout\" is sent to the console.\n";
  612. 			message += "          If an invalid text color is specified, it will be ignored.\n\n";
  613. 			message += "Written by Rob van der Woude\n";
  614. 			message += "https://www.robvanderwoude.com/";
  615.  
  616. 			Console.Error.WriteLine( message );
  617. 		}
  618. 	}
  619. }
  620.  

page last uploaded: 2019-01-21, 22:48