Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for messagebox.cs

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

  1. using System;
  2. using System.Globalization;
  3. using System.Runtime.InteropServices;
  4. using System.Text.RegularExpressions;
  5. using System.Windows.Forms;
  6.  
  7.  
  8. namespace RobvanderWoude
  9. {
  10. 	class MessageBox
  11. 	{
  12. 		static readonly string progver = "1.34";
  13.  
  14. 		static bool timeoutelapsed = false;
  15. 		static string defaulttitle = String.Format( "MessageBox {0}", progver );
  16. 		static int timeout = 0;
  17. 		static bool rcbutton = false;
  18. 		static MessageBoxButtons buttons = MessageBoxButtons.OK;
  19.  
  20.  
  21. 		static int Main( string[] args )
  22. 		{
  23. 			#region Initialize Variables
  24.  
  25. 			string message = DefaultMessage( );
  26. 			string result;
  27. 			string title = defaulttitle;
  28. 			MessageBoxIcon icon = MessageBoxIcon.Information;
  29. 			MessageBoxDefaultButton defaultbutton = MessageBoxDefaultButton.Button1;
  30. 			MessageBoxOptions option = MessageBoxOptions.DefaultDesktopOnly;
  31. 			bool buttonsset = false;
  32. 			bool defaultset = false;
  33. 			bool escapemessage = true;
  34. 			bool iconset = false;
  35. 			bool optionsset = false;
  36. 			bool useswitches = false;
  37. 			int rc = 0;
  38.  
  39. 			#endregion Initialize Variables
  40.  
  41.  
  42. 			#region Command Line Parsing
  43.  
  44. 			foreach ( string arg in args )
  45.             {
  46.                 if ( arg == "/?" )
  47.                 {
  48.                     return DisplayHelp( );
  49.                 }
  50.             }
  51.  
  52. 			foreach ( string arg in args )
  53. 			{
  54. 				if ( arg[0] == '/' )
  55. 				{
  56. 					useswitches = true;
  57. 					if ( arg.Length > 3 && arg[2] == ':' )
  58. 					{
  59. 						string key = arg[1].ToString( ).ToUpper( );
  60. 						string val = arg.Substring( 3 ).ToUpper( );
  61. 						switch ( key )
  62. 						{
  63. 							case "B":
  64. 								switch ( val )
  65. 								{
  66. 									case "A":
  67. 									case "ABORTRETRYIGNORE":
  68. 										buttons = MessageBoxButtons.AbortRetryIgnore;
  69. 										break;
  70. 									case "C":
  71. 									case "OKCANCEL":
  72. 										buttons = MessageBoxButtons.OKCancel;
  73. 										break;
  74. 									case "N":
  75. 									case "YESNOCANCEL":
  76. 										buttons = MessageBoxButtons.YesNoCancel;
  77. 										break;
  78. 									case "O":
  79. 									case "OK":
  80. 										buttons = MessageBoxButtons.OK;
  81. 										break;
  82. 									case "R":
  83. 									case "RETRYCANCEL":
  84. 										buttons = MessageBoxButtons.RetryCancel;
  85. 										break;
  86. 									case "Y":
  87. 									case "YESNO":
  88. 										buttons = MessageBoxButtons.YesNo;
  89. 										break;
  90. 									default:
  91. 										rc = 1;
  92. 										break;
  93. 								}
  94. 								buttonsset = true;
  95. 								break;
  96. 							case "D":
  97. 								if ( !buttonsset )
  98. 								{
  99. 									rc = 1;
  100. 								}
  101. 								switch ( val )
  102. 								{
  103. 									case "1":
  104. 									case "BUTTON1":
  105. 									case "ABORT":
  106. 									case "OK":
  107. 									case "YES":
  108. 										defaultbutton = MessageBoxDefaultButton.Button1;
  109. 										break;
  110. 									case "2":
  111. 									case "BUTTON2":
  112. 									case "NO":
  113. 										defaultbutton = MessageBoxDefaultButton.Button2;
  114. 										break;
  115. 									case "3":
  116. 									case "BUTTON3":
  117. 									case "IGNORE":
  118. 										defaultbutton = MessageBoxDefaultButton.Button3;
  119. 										break;
  120. 									case "CANCEL":
  121. 										if ( buttons == MessageBoxButtons.YesNoCancel )
  122. 										{
  123. 											defaultbutton = MessageBoxDefaultButton.Button3;
  124. 										}
  125. 										else
  126. 										{
  127. 											defaultbutton = MessageBoxDefaultButton.Button2;
  128. 										}
  129. 										break;
  130. 									case "RETRY":
  131. 										if ( buttons == MessageBoxButtons.RetryCancel )
  132. 										{
  133. 											defaultbutton = MessageBoxDefaultButton.Button1;
  134. 										}
  135. 										else
  136. 										{
  137. 											defaultbutton = MessageBoxDefaultButton.Button2;
  138. 										}
  139. 										break;
  140. 									default:
  141. 										rc = 1;
  142. 										break;
  143. 								}
  144. 								defaultset = true;
  145. 								break;
  146. 							case "I":
  147. 								switch ( val )
  148. 								{
  149. 									case "A":
  150. 									case "ASTERISK":
  151. 										icon = MessageBoxIcon.Asterisk;
  152. 										break;
  153. 									case "E":
  154. 									case "ERROR":
  155. 										icon = MessageBoxIcon.Error;
  156. 										break;
  157. 									case "H":
  158. 									case "HAND":
  159. 										icon = MessageBoxIcon.Hand;
  160. 										break;
  161. 									case "I":
  162. 									case "INFORMATION":
  163. 										icon = MessageBoxIcon.Information;
  164. 										break;
  165. 									case "N":
  166. 									case "NONE":
  167. 										icon = MessageBoxIcon.None;
  168. 										break;
  169. 									case "Q":
  170. 									case "QUESTION":
  171. 										icon = MessageBoxIcon.Question;
  172. 										break;
  173. 									case "S":
  174. 									case "STOP":
  175. 										icon = MessageBoxIcon.Stop;
  176. 										break;
  177. 									case "W":
  178. 									case "WARNING":
  179. 										icon = MessageBoxIcon.Warning;
  180. 										break;
  181. 									case "X":
  182. 									case "EXCLAMATION":
  183. 										icon = MessageBoxIcon.Exclamation;
  184. 										break;
  185. 									default:
  186. 										rc = 1;
  187. 										break;
  188. 								}
  189. 								iconset = true;
  190. 								break;
  191. 							case "O":
  192. 								switch ( val )
  193. 								{
  194. 									case "H":
  195. 									case "HIDECONSOLE":
  196. 										HideConsoleWindow( );
  197. 										break;
  198. 									case "L":
  199. 									case "RTLREADING":
  200. 										option |= MessageBoxOptions.RtlReading;
  201. 										break;
  202. 									case "N":
  203. 									case "NOESCAPE":
  204. 										escapemessage = false;
  205. 										break;
  206. 									case "R":
  207. 									case "RIGHTALIGN":
  208. 										option |= MessageBoxOptions.RightAlign;
  209. 										break;
  210. 									default:
  211. 										rc = 1;
  212. 										break;
  213. 								}
  214. 								optionsset = true;
  215. 								break;
  216. 							case "T":
  217. 								rc = CheckTimeout( val );
  218. 								break;
  219. 							default:
  220. 								rc = 1;
  221. 								break;
  222. 						}
  223. 					}
  224. 					else if ( arg.ToUpper( ) == "/R" )
  225. 					{
  226. 						rcbutton = true;
  227. 					}
  228. 					else
  229. 					{
  230. 						rc = 1;
  231. 					}
  232. 				}
  233. 				else
  234. 				{
  235. 					if ( message == DefaultMessage( ) )
  236. 					{
  237. 						message = arg;
  238. 					}
  239. 					else if ( title == defaulttitle )
  240. 					{
  241. 						title = arg;
  242. 					}
  243. 					else if ( useswitches ) // If switches are used, only 2 "unnamed" arguments are allowed
  244. 					{
  245. 						rc = 1;
  246. 					}
  247. 					else if ( !buttonsset )
  248. 					{
  249. 						switch ( arg.ToLower( ) )
  250. 						{
  251. 							case "abortretryignore":
  252. 								buttons = MessageBoxButtons.AbortRetryIgnore;
  253. 								break;
  254. 							case "ok":
  255. 								buttons = MessageBoxButtons.OK;
  256. 								break;
  257. 							case "okcancel":
  258. 								buttons = MessageBoxButtons.OKCancel;
  259. 								break;
  260. 							case "retrycancel":
  261. 								buttons = MessageBoxButtons.RetryCancel;
  262. 								break;
  263. 							case "yesno":
  264. 								buttons = MessageBoxButtons.YesNo;
  265. 								break;
  266. 							case "yesnocancel":
  267. 								buttons = MessageBoxButtons.YesNoCancel;
  268. 								break;
  269. 							default:
  270. 								buttons = MessageBoxButtons.OK;
  271. 								rc = 1;
  272. 								break;
  273. 						}
  274. 						buttonsset = true;
  275. 					}
  276. 					else if ( !iconset )
  277. 					{
  278. 						switch ( arg.ToLower( ) )
  279. 						{
  280. 							case "asterisk":
  281. 								icon = MessageBoxIcon.Asterisk;
  282. 								break;
  283. 							case "error":
  284. 								icon = MessageBoxIcon.Error;
  285. 								break;
  286. 							case "exclamation":
  287. 								icon = MessageBoxIcon.Exclamation;
  288. 								break;
  289. 							case "hand":
  290. 								icon = MessageBoxIcon.Hand;
  291. 								break;
  292. 							case "information":
  293. 								icon = MessageBoxIcon.Information;
  294. 								break;
  295. 							case "none":
  296. 								icon = MessageBoxIcon.None;
  297. 								break;
  298. 							case "question":
  299. 								icon = MessageBoxIcon.Question;
  300. 								break;
  301. 							case "stop":
  302. 								icon = MessageBoxIcon.Stop;
  303. 								break;
  304. 							case "warning":
  305. 								icon = MessageBoxIcon.Warning;
  306. 								break;
  307. 							default:
  308. 								icon = MessageBoxIcon.Warning;
  309. 								rc = 1;
  310. 								break;
  311. 						}
  312. 						iconset = true;
  313. 					}
  314. 					else if ( !defaultset )
  315. 					{
  316. 						switch ( arg.ToLower( ) )
  317. 						{
  318. 							case "":
  319. 							case "abort":
  320. 							case "button1":
  321. 							case "ok":
  322. 							case "yes":
  323. 								defaultbutton = MessageBoxDefaultButton.Button1;
  324. 								break;
  325. 							case "button2":
  326. 							case "no":
  327. 								defaultbutton = MessageBoxDefaultButton.Button2;
  328. 								break;
  329. 							case "button3":
  330. 							case "ignore":
  331. 								defaultbutton = MessageBoxDefaultButton.Button3;
  332. 								break;
  333. 							case "cancel":
  334. 								if ( args[2].ToLower( ) == "okcancel" || args[2].ToLower( ) == "retrycancel" )
  335. 								{
  336. 									defaultbutton = MessageBoxDefaultButton.Button2;
  337. 								}
  338. 								else // yesnocancel
  339. 								{
  340. 									defaultbutton = MessageBoxDefaultButton.Button3;
  341. 								}
  342. 								break;
  343. 							case "retry":
  344. 								if ( args[2].ToLower( ) == "abortretryignore" )
  345. 								{
  346. 									defaultbutton = MessageBoxDefaultButton.Button2;
  347. 								}
  348. 								else // retrycancel
  349. 								{
  350. 									defaultbutton = MessageBoxDefaultButton.Button1;
  351. 								}
  352. 								break;
  353. 							default:
  354. 								defaultbutton = MessageBoxDefaultButton.Button1;
  355. 								rc = 1;
  356. 								break;
  357. 						}
  358. 						defaultset = true;
  359. 					}
  360. 					else if ( !optionsset )
  361. 					{
  362. 						switch ( arg.ToLower( ) )
  363. 						{
  364. 							case "":
  365. 							case "none":
  366. 								optionsset = true;
  367. 								break;
  368. 							case "hideconsole":
  369. 								HideConsoleWindow( );
  370. 								optionsset = true;
  371. 								break;
  372. 							case "noescape":
  373. 								escapemessage = false;
  374. 								optionsset = true;
  375. 								break;
  376. 							case "rightalign":
  377. 								option = MessageBoxOptions.RightAlign;
  378. 								optionsset = true;
  379. 								break;
  380. 							case "rtlreading":
  381. 								option = MessageBoxOptions.RtlReading;
  382. 								optionsset = true;
  383. 								break;
  384. 							default: // try if option is unspecified and argument is timeout
  385. 								rc = CheckTimeout( arg );
  386. 								break;
  387. 						}
  388. 					}
  389. 					else if ( timeout == 0 )
  390. 					{
  391. 						rc = CheckTimeout( arg );
  392. 					}
  393. 					else
  394. 					{
  395. 						rc = 1;
  396. 					}
  397. 				}
  398. 			}
  399.  
  400. 			if ( !escapemessage && message != DefaultMessage( ) )
  401. 			{
  402. 				message = UnEscapeString( message );
  403. 				title = UnEscapeString( title );
  404. 			}
  405.  
  406. 			// MessageBoxOptions.ServiceNotification allows interactive use by SYSTEM account (or any other account not currently logged in)
  407. 			option |= MessageBoxOptions.ServiceNotification;
  408.  
  409. 			#endregion Command Line Parsing
  410.  
  411.  
  412. 			if ( rc == 1 ) // command line error
  413. 			{
  414. 				ShowConsoleWindow( );
  415. 				return DisplayHelp( );
  416. 			}
  417.  
  418. 			if ( rc == 0 && timeout > 0 )
  419. 			{
  420. 				result = AutoClosingMessageBox.Show( message, title, timeout, buttons, icon, defaultbutton, option ).ToString( ).ToLower( );
  421. 				if ( timeoutelapsed )
  422. 				{
  423. 					result = "timeout";
  424. 					rc = 3;
  425. 				}
  426. 				else if ( result == "cancel" )
  427. 				{
  428. 					rc = 2;
  429. 				}
  430. 			}
  431. 			else
  432. 			{
  433. 				if ( message == DefaultMessage( ) )
  434. 				{
  435. 					message = DefaultMessage( ).Substring( 0, DefaultMessage( ).IndexOf( "\n\nNotes:" ) ) + "\n\nWritten by Rob van der Woude\nhttp://www.robvanderwoude.com";
  436. 					result = System.Windows.Forms.MessageBox.Show( message, title, buttons, icon, defaultbutton, option ).ToString( ).ToLower( );
  437. 					Console.WriteLine( result );
  438. 					if ( result == "cancel" )
  439. 					{
  440. 						return 2;
  441. 					}
  442. 					message = DefaultMessage( ).Substring( DefaultMessage( ).IndexOf( "Notes:" ) );
  443. 				}
  444. 				result = System.Windows.Forms.MessageBox.Show( message, title, buttons, icon, defaultbutton, option ).ToString( ).ToLower( );
  445. 				if ( result == "cancel" )
  446. 				{
  447. 					rc = 2;
  448. 				}
  449. 			}
  450. 			Console.WriteLine( result );
  451. 			// Change return code if /R switch was used
  452. 			if ( rcbutton )
  453. 			{
  454. 				if ( rc == 1 )
  455. 				{
  456. 					return -1; // error
  457. 				}
  458. 				switch ( result )
  459. 				{
  460. 					case "abort":
  461. 						return 1; // button 1 of AbortRetryIgnore
  462. 					case "cancel":
  463. 						switch ( buttons )
  464. 						{
  465. 							case MessageBoxButtons.OKCancel:
  466. 							case MessageBoxButtons.RetryCancel:
  467. 								return 2; // button 2 for OKCancel or RetryCancel
  468. 							case MessageBoxButtons.YesNoCancel:
  469. 								return 3; // button 3 for YesNoCancel
  470. 							default:
  471. 								return 0; // terminated without clicking a button
  472. 						}
  473. 					case "ignore":
  474. 						return 3; // button 3 for AbortRetryIgnore
  475. 					case "no":
  476. 						return 2; // button 2 for YesNo or YesNoCancel
  477. 					case "ok":
  478. 						return 1; // button 1 for OK or OKCancel
  479. 					case "retry":
  480. 						if ( buttons == MessageBoxButtons.AbortRetryIgnore )
  481. 						{
  482. 							return 2; // button 2 for AbortRetryIgnore
  483. 						}
  484. 						else
  485. 						{
  486. 							return 1; // button 1 for RetryCancel
  487. 						}
  488. 					case "timeout":
  489. 						return 4;
  490. 					case "yes":
  491. 						return 1; // button 1 for YesNo or YesNoCancel
  492. 					default:
  493. 						return -1; // error
  494. 				}
  495. 			}
  496. 			else
  497. 			{
  498. 				return rc;
  499. 			}
  500. 		}
  501.  
  502.  
  503. 		static int CheckTimeout( string val )
  504. 		{
  505. 			int rc = 0;
  506. 			try
  507. 			{
  508. 				timeout = Convert.ToInt32( val ) * 1000;
  509. 				if ( timeout < 1000 )
  510. 				{
  511. 					rc = 1;
  512. 				}
  513. 			}
  514. 			catch ( FormatException )
  515. 			{
  516. 				rc = 1;
  517. 			}
  518. 			return rc;
  519. 		}
  520.  
  521.  
  522. 		static string DefaultMessage( )
  523. 		{
  524. 			string message = "MessageBox.exe,  Version " + progver + "\n";
  525. 			message += "Batch tool to show a message in a MessageBox and return\nthe caption of the button that is clicked\n\n";
  526. 			message += "Usage:\nMessageBox \"message\" [ \"title\" ]  [ switches ]\n\n";
  527. 			message += "Or:\nMessageBox \"message\" \"title\" buttons icon default [option] timeout\n\n";
  528.             message += "Where:\n\tbuttons\t\"AbortRetryIgnore\", \"OK\", \"OKCancel\",\n";
  529.             message += "\t\t\"RetryCancel\", \"YesNo\" or \"YesNoCancel\"\n";
  530. 			message += "\ticon\t\"Asterisk\", \"Error\", \"Exclamation\", \"Hand\",\n";
  531. 			message += "\t\t\"Information\", \"None\", \"Question\", \"Stop\"\n";
  532. 			message += "\t\tor \"Warning\"\n";
  533. 			message += "\tdefault\t\"Button1\", \"Button2\" or \"Button3\" or the\n\t\tdefault button's (English) caption\n";
  534. 			message += "\toption\t\"HideConsole\", \"NoEscape\", \"RightAlign\",\n\t\t\"RtlReading\", \"None\" or \"\"\n";
  535. 			message += "\ttimeout\ttimeout interval in seconds\n\n";
  536.             message += "Switches:\n";
  537.             message += "            \t/B:buttons\tA = AbortRetryIgnore, O = OK,\n";
  538.             message += "        \t\t\tC = OKCancel, R = RetryCancel,\n";
  539. 			message += "        \t\t\tY = YesNo, N = YesNoCancel\n";
  540. 			message += "            \t/I:icon        \tA = Asterisk, E = Error,\n";
  541. 			message += "        \t\t\tX = Exclamation, H = Hand,\n";
  542. 			message += "        \t\t\tI = Information, N = None,\n";
  543. 			message += "        \t\t\tQ = Question, S = Stop\n";
  544. 			message += "        \t\t\tW = Warning\n";
  545. 			message += "            \t/D:default    \t1 = Button1, 2 = Button2,\n";
  546. 			message += "        \t\t\t3 = Button3 or use the default\n";
  547. 			message += "        \t\t\tbutton's (English) caption\n";
  548. 			message += "            \t/O:option     \tH = HideConsole, N = NoEscape,\n";
  549. 			message += "        \t\t\tR = RightAlign, L = RtlReading\n";
  550. 			message += "            \t/R\t\tReturn code tells which button\n";
  551. 			message += "            \t\t\twas clicked (see Notes)\n";
  552. 			message += "            \t/T:timeout\ttimeout interval in seconds\n\n";
  553. 			message += "Notes:\n\nUse switches if you want to skip arguments.\n\n";
  554. 			message += "Always specify buttons BEFORE specifying default.\n\n";
  555.             message += "Using the \"HideConsole\" option will hide the console window permanently, thereby disabling all console based user interaction (e.g. \"ECHO\" and \"PAUSE\").\n";
  556.             message += "It is intended to be used in scripts that run \"hidden\" themselves, e.g. VBScript with the WScript.exe interpreter.\n";
  557.             message += "Do not use this option in a batch file unless hiding the console window permanently is intended.\n\n";
  558. 			message += "Linefeeds (\\n\u00A0or\u00A0\\012 and/or \\r\u00A0or\u00A0\\015), tabs (\\t\u00A0or\u00A0\\007), singlequotes ('\u00A0or\u00A0\\047) and doublequotes (\\\"\u00A0or\u00A0\\042) are allowed in the message string.\n";
  559. 			message += "Unicode characters (e.g.\u00A0\"\\u5173\" for\u00A0\"\u5173\") are allowed in the message string and in the title.\n";
  560.             message += "By default, however, these linefeeds, tabs, quotes and Unicode characters will be escaped to allow correct display of paths.\n";
  561. 			message += "Use option \"NoEscape\" to disable all character escaping except doublequotes.\n\n";
  562. 			message += "The (English) caption of the button that was clicked is returned as text to Standard Output (in lower case), or \"timeout\" if the timeout interval expired.\n\n";
  563. 			message += "When using the timeout feature, A window with the current MessageBox's TITLE will be closed, not necessarily THE current MessageBox.\nTo prevent closing the wrong MessageBox, use unique titles.\n\n";
  564. 			message += "The timeout feature should not be combined with buttons Abort Retry Fail; if it is, the MessageBox will remain open even after the timeout expires, until a button is clicked, and then return the \"timeout\" result.\n\n";
  565. 			message += "Unless the /R switch is used, the return code of the program is 0 if a button was clicked, 1 in case of (command line) errors, 2 if cancelled (this does require a Cancel button), 3 if the timeout expired.\n";
  566. 			message += "When the /R switch is used, the return code of the program is 1 if button 1 was clicked, 2 if button 2 was clicked, 3 if button 3 was clicked, 4 if the timeout expired, -1 in case of (command line) errors, or 0 if the MessageBox is cancelled without a Cancel button being available.\n\n";
  567. 			message += "Credits:\n\n";
  568.             message += "Code to hide console by Anthony on:\nhttp://stackoverflow.com/a/15079092\n\n";
  569.             message += "MessageBox timeout based on code by DmitryG on:\nhttp://stackoverflow.com/a/14522952\n\n";
  570.             message += "Written by Rob van der Woude\nhttps://www.robvanderwoude.com\n";
  571. 			return message;
  572. 		}
  573.  
  574.  
  575. 		static int DisplayHelp( )
  576. 		{
  577. 			// Display the help text in 2 message boxes AND in the console
  578. 			DisplayHelpText( );
  579. 			if ( DisplayHelpWindow( 1 ) != DialogResult.Cancel )
  580. 			{
  581. 				DisplayHelpWindow( 2 );
  582. 			}
  583. 			if ( rcbutton )
  584. 			{
  585. 				return -1;
  586. 			}
  587. 			else
  588. 			{
  589. 				return 1;
  590. 			}
  591. 		}
  592.  
  593.  
  594. 		static void DisplayHelpText( )
  595. 		{
  596. 			string message = DefaultMessage( );
  597. 			message = message.Replace( "\n\n\t", "\n\t" );
  598. 			message = message.Replace( "Usage:\n", "Usage:\t" );
  599. 			message = message.Replace( "Or:\n", "   or:\t" );
  600.             string[] lines = message.Split( '\n' );
  601.             foreach ( string line in lines )
  602.             {
  603.                 if ( line.Length < Console.WindowWidth )
  604.                 {
  605.                     Console.Error.WriteLine( line );
  606.                 }
  607.                 else
  608.                 {
  609.                     bool done = false;
  610.                     string remainder = line;
  611.                     string pattern = "^.{1," + ( Console.WindowWidth - 1 ) + "}[ $]";
  612.                     Regex regex = new Regex( pattern );
  613.                     while ( !done )
  614.                     {
  615.                         if ( regex.IsMatch( remainder ) )
  616.                         {
  617.                             Match match = regex.Match( remainder );
  618.                             Console.Error.WriteLine( match.Value.TrimEnd( ) );
  619.                             remainder = remainder.Substring( match.Value.Length );
  620.                             if ( remainder.Length < Console.WindowWidth )
  621.                             {
  622.                                 Console.Error.WriteLine( remainder.TrimEnd( ) );
  623.                             }
  624.                             done = string.IsNullOrWhiteSpace( remainder ) || remainder.Length < Console.WindowWidth;
  625.                         }
  626.                         else
  627.                         {
  628.                             Console.Error.WriteLine( remainder );
  629.                             done = true;
  630.                         }
  631.                     }
  632.                 }
  633.             }
  634. 		}
  635.  
  636.  
  637. 		static DialogResult DisplayHelpWindow( int part )
  638. 		{
  639. 			// part is 1 or 2; 1 for first half of message, 2 for second half
  640. 			string message = DefaultMessage( );
  641. 			if ( part == 1 )
  642. 			{
  643. 				message = message.Substring( 0, message.IndexOf( "\n\nNotes:" ) ) + "\n\nWritten by Rob van der Woude\nhttp://www.robvanderwoude.com";
  644. 				return System.Windows.Forms.MessageBox.Show( message, defaulttitle, MessageBoxButtons.OKCancel, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification );
  645. 			}
  646. 			else
  647. 			{
  648. 				message = message.Substring( message.IndexOf( "Notes:" ) );
  649. 				return System.Windows.Forms.MessageBox.Show( message, defaulttitle, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification );
  650. 			}
  651. 		}
  652.  
  653.  
  654. 		static string UnEscapeString( string message )
  655. 		{
  656. 			// Unescaping tabs, linefeeds and quotes
  657. 			message = message.Replace( "\\n", "\n" );
  658. 			message = message.Replace( "\\r", "\r" );
  659. 			message = message.Replace( "\\t", "\t" );
  660. 			message = message.Replace( "\\007", "\t" );
  661. 			message = message.Replace( "\\012", "\n" );
  662. 			message = message.Replace( "\\015", "\r" );
  663. 			message = message.Replace( "\\042", "\"" );
  664. 			message = message.Replace( "\\047", "'" );
  665. 			// Unescaping Unicode, technique by "dtb" on StackOverflow.com: http://stackoverflow.com/a/8558748
  666. 			message = Regex.Replace( message, @"\\[Uu]([0-9A-Fa-f]{4})", m => char.ToString( (char) ushort.Parse( m.Groups[1].Value, NumberStyles.AllowHexSpecifier ) ) );
  667. 			return message;
  668. 		}
  669.  
  670.  
  671. 		#region Hide or Show Console
  672. 		// Source: http://stackoverflow.com/a/15079092
  673.  
  674. 		public static void ShowConsoleWindow( )
  675. 		{
  676. 			var handle = GetConsoleWindow( );
  677.  
  678. 			if ( handle == IntPtr.Zero )
  679. 			{
  680. 				AllocConsole( );
  681. 			}
  682. 			else
  683. 			{
  684. 				ShowWindow( handle, SW_SHOW );
  685. 			}
  686. 		}
  687.  
  688.  
  689. 		public static void HideConsoleWindow( )
  690. 		{
  691. 			var handle = GetConsoleWindow( );
  692.  
  693. 			ShowWindow( handle, SW_HIDE );
  694. 		}
  695.  
  696.  
  697. 		[DllImport( "kernel32.dll", SetLastError = true )]
  698. 		static extern bool AllocConsole( );
  699.  
  700.  
  701. 		[DllImport( "kernel32.dll" )]
  702. 		static extern IntPtr GetConsoleWindow( );
  703.  
  704.  
  705. 		[DllImport( "user32.dll" )]
  706. 		static extern bool ShowWindow( IntPtr hWnd, int nCmdShow );
  707.  
  708.  
  709. 		const int SW_HIDE = 0;
  710. 		const int SW_SHOW = 5;
  711.  
  712. 		#endregion Hide or Show Console
  713.  
  714.  
  715. 		#region Timed MessageBox
  716.  
  717. 		// Timed MessageBox based on code by DmitryG on StackOverflow.com
  718. 		// http://stackoverflow.com/a/14522952
  719. 		public class AutoClosingMessageBox
  720. 		{
  721. 			System.Threading.Timer _timeouttimer;
  722. 			string _caption;
  723. 			DialogResult _result;
  724.  
  725.  
  726. 			AutoClosingMessageBox( string message, string title, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defaultbutton = MessageBoxDefaultButton.Button1, MessageBoxOptions option = MessageBoxOptions.DefaultDesktopOnly )
  727. 			{
  728. 				_caption = title;
  729. 				_timeouttimer = new System.Threading.Timer( OnTimerElapsed, null, timeout, System.Threading.Timeout.Infinite );
  730.  
  731. 				using ( _timeouttimer )
  732. 				{
  733. 					_result = System.Windows.Forms.MessageBox.Show( message, title, buttons, icon, defaultbutton, option | MessageBoxOptions.ServiceNotification );
  734. 				}
  735. 			}
  736.  
  737.  
  738. 			public static DialogResult Show( string message, string title, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defaultbutton = MessageBoxDefaultButton.Button1, MessageBoxOptions option = MessageBoxOptions.DefaultDesktopOnly )
  739. 			{
  740. 				return new AutoClosingMessageBox( message, title, timeout, buttons, icon, defaultbutton, option | MessageBoxOptions.ServiceNotification )._result;
  741. 			}
  742.  
  743.  
  744. 			void OnTimerElapsed( object state )
  745. 			{
  746. 				IntPtr mbWnd = FindWindow( "#32770", _caption ); // lpClassName is #32770 for MessageBox
  747. 				if ( mbWnd != IntPtr.Zero )
  748. 				{
  749. 					SendMessage( mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero );
  750. 				}
  751. 				_timeouttimer.Dispose( );
  752. 				timeoutelapsed = true;
  753. 			}
  754.  
  755.  
  756. 			const int WM_CLOSE = 0x0010;
  757.  
  758.  
  759. 			[System.Runtime.InteropServices.DllImport( "user32.dll", SetLastError = true )]
  760. 			static extern IntPtr FindWindow( string lpClassName, string lpWindowName );
  761.  
  762.  
  763. 			[System.Runtime.InteropServices.DllImport( "user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto )]
  764. 			static extern IntPtr SendMessage( IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam );
  765. 		}
  766.  
  767. 		#endregion Timed MessageBox
  768. 	}
  769. }
  770.  

page last modified: 2024-04-16; loaded in 0.0361 seconds