Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for dropdownbox.cs

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Windows.Forms;
  9.  
  10.  
  11. namespace RobvanderWoude
  12. {
  13. 	class DropDownBox
  14. 	{
  15. 		public static string progver = "1.11";
  16. 		public static bool returnindex = false;
  17.  
  18. 		[STAThread]
  19. 		static int Main( string[] args )
  20. 		{
  21. 			try
  22. 			{
  23. 				#region Initialize Variables
  24.  
  25. 				char delimiter = ';';
  26. 				List<string> namedargs = new List<string>( );
  27. 				List<string> unnamedargs = new List<string>( );
  28. 				string file = String.Empty;
  29. 				string list = String.Empty;
  30. 				string cancelcaption = "&Cancel";
  31. 				string okcaption = "&OK";
  32. 				string localizationstring = String.Empty;
  33. 				string prompt = String.Empty;
  34. 				string selectedText = String.Empty;
  35. 				string title = String.Format( "DropDownBox,  Version {0}", progver );
  36. 				int defaultwidth = 200;
  37. 				int defaultheight = 90;
  38. 				int icon = 23;
  39. 				int selectedindex = 0;
  40. 				int tablength = 4;
  41. 				int width = defaultwidth;
  42. 				int height = defaultheight;
  43. 				bool widthset = false;
  44. 				bool heightset = false;
  45. 				bool delimiterset = false;
  46. 				bool iconset = false;
  47. 				bool indexset = false;
  48. 				bool listset = false;
  49. 				bool localizedcaptionset = false;
  50. 				bool monospaced = false;
  51. 				bool tablengthset = false;
  52. 				bool topmost = true;
  53.  
  54. 				#endregion Initialize Variables
  55.  
  56.  
  57. 				#region Command Line Parsing
  58.  
  59. 				if ( args.Length == 0 )
  60. 				{
  61. 					return ShowHelp( );
  62. 				}
  63. 				if ( args.Length > 11 )
  64. 				{
  65. 					return ShowHelp( "Too many command line arguments" );
  66. 				}
  67. 				// Split up named and unnamed arguments
  68. 				foreach ( string arg in args )
  69. 				{
  70. 					if ( arg == "/?" )
  71. 					{
  72. 						return ShowHelp( );
  73. 					}
  74. 					if ( arg[0] == '/' )
  75. 					{
  76. 						namedargs.Add( arg );
  77. 					}
  78. 					else
  79. 					{
  80. 						unnamedargs.Add( arg );
  81. 					}
  82. 				}
  83.  
  84.  
  85. 				// First, validate the named arguments
  86. 				#region Named Arguments
  87.  
  88. 				foreach ( string arg in namedargs )
  89. 				{
  90. 					if ( arg.Length < 3 && arg.ToUpper( ) != "/L" )
  91. 					{
  92. 						return ShowHelp( "Invalid command line switch {0} or missing value", arg );
  93. 					}
  94. 					if ( arg.ToUpper( ) == "/L" )
  95. 					{
  96. 						if ( localizedcaptionset )
  97. 						{
  98. 							return ShowHelp( "Duplicate command line switch /L" );
  99. 						}
  100. 						localizedcaptionset = true;
  101. 					}
  102. 					else
  103. 					{
  104. 						switch ( arg.Substring( 0, 3 ).ToUpper( ) )
  105. 						{
  106. 							case "/C:":
  107. 								if ( iconset )
  108. 								{
  109. 									return ShowHelp( "Duplicate command line switch /D" );
  110. 								}
  111. 								try
  112. 								{
  113. 									icon = Convert.ToInt32( arg.Substring( 3 ) );
  114. 								}
  115. 								catch ( Exception )
  116. 								{
  117. 									return ShowHelp( "Invalid icon index: {0}", arg.Substring( 3 ) );
  118. 								}
  119. 								iconset = true;
  120. 								break;
  121. 							case "/D:":
  122. 								if ( delimiterset )
  123. 								{
  124. 									return ShowHelp( "Duplicate command line switch /D" );
  125. 								}
  126. 								string test = arg.Substring( 3 );
  127. 								if ( test.Length == 1 )
  128. 								{
  129. 									delimiter = test[0];
  130. 								}
  131. 								else if ( test.Length == 3 && ( ( test[0] == '"' && test[2] == '"' ) || ( test[0] == '\'' && test[2] == '\'' ) ) )
  132. 								{
  133. 									delimiter = test[1];
  134. 								}
  135. 								else
  136. 								{
  137. 									return ShowHelp( String.Format( "Invalid delimiter specified \"{0}\"", arg ) );
  138. 								}
  139. 								break;
  140. 							case "/F:":
  141. 								if ( listset )
  142. 								{
  143. 									return ShowHelp( "Duplicate command line switch /F" );
  144. 								}
  145. 								file = arg.Substring( 3 );
  146. 								if ( String.IsNullOrEmpty( file ) || !File.Exists( file ) )
  147. 								{
  148. 									return ShowHelp( "List file not found: \"{0}\"", file );
  149. 								}
  150. 								else
  151. 								{
  152. 									try
  153. 									{
  154. 										string delim = delimiter.ToString( );
  155. 										list = String.Join( delim, File.ReadLines( file ) );
  156. 										string pattern = delim + "{2,}";
  157. 										// Remove empty list items
  158. 										Regex.Replace( list, pattern, delim );
  159. 									}
  160. 									catch ( Exception e )
  161. 									{
  162. 										return ShowHelp( e.Message );
  163. 									}
  164. 								}
  165. 								listset = true;
  166. 								break;
  167. 							case "/H:":
  168. 								if ( heightset )
  169. 								{
  170. 									return ShowHelp( "Duplicate command line switch /H" );
  171. 								}
  172. 								try
  173. 								{
  174. 									height = Convert.ToInt32( arg.Substring( 3 ) );
  175. 									if ( height < defaultheight || height > Screen.PrimaryScreen.Bounds.Height )
  176. 									{
  177. 										return ShowHelp( String.Format( "Height {0} outside allowed range of {1}..{2}", arg.Substring( 3 ), defaultheight, Screen.PrimaryScreen.Bounds.Height ) );
  178. 									}
  179. 								}
  180. 								catch ( Exception e )
  181. 								{
  182. 									return ShowHelp( String.Format( "Invalid height \"{0}\": {1}", arg.Substring( 3 ), e.Message ) );
  183. 								}
  184. 								heightset = true;
  185. 								break;
  186. 							case "/I:":
  187. 								if ( indexset )
  188. 								{
  189. 									return ShowHelp( "Duplicate command line switch /I" );
  190. 								}
  191. 								try
  192. 								{
  193. 									selectedindex = Convert.ToInt32( arg.Substring( 3 ) );
  194. 								}
  195. 								catch ( Exception e )
  196. 								{
  197. 									return ShowHelp( String.Format( "Invalid index value \"{0}\": {1}", arg, e.Message ) );
  198. 								}
  199. 								break;
  200. 							case "/L:":
  201. 								if ( localizedcaptionset )
  202. 								{
  203. 									return ShowHelp( "Duplicate command line switch /L" );
  204. 								}
  205. 								localizedcaptionset = true;
  206. 								localizationstring = arg.Substring( 3 );
  207. 								string localizationpattern = "(;|^)(OK|Cancel)=[^\\\"';]+(;|$)";
  208. 								foreach ( string substring in localizationstring.Split( ";".ToCharArray( ), StringSplitOptions.RemoveEmptyEntries ) )
  209. 								{
  210. 									if ( !Regex.IsMatch( substring, localizationpattern, RegexOptions.IgnoreCase ) )
  211. 									{
  212. 										return ShowHelp( "Invalid value for /L switch: \"{1}\"", localizationstring );
  213. 									}
  214. 								}
  215. 								break;
  216. 							case "/MF":
  217. 								if ( monospaced )
  218. 								{
  219. 									return ShowHelp( "Duplicate command line switch /MF" );
  220. 								}
  221. 								monospaced = true;
  222. 								break;
  223. 							case "/NM":
  224. 								if ( !topmost )
  225. 								{
  226. 									return ShowHelp( "Duplicate command line switch /NM" );
  227. 								}
  228. 								topmost = false;
  229. 								break;
  230. 							case "/RI":
  231. 								if ( returnindex )
  232. 								{
  233. 									return ShowHelp( "Duplicate command line switch /RI" );
  234. 								}
  235. 								returnindex = true;
  236. 								break;
  237. 							case "/T:":
  238. 								if ( tablengthset )
  239. 								{
  240. 									return ShowHelp( "Duplicate command line switch /T" );
  241. 								}
  242. 								try
  243. 								{
  244. 									tablength = Convert.ToInt32( arg.Substring( 3 ) );
  245. 									if ( tablength < 4 || tablength > 16 )
  246. 									{
  247. 										return ShowHelp( String.Format( "Tab length {0} outside allowed range of {1}..{2}", arg.Substring( 3 ), 4, 16 ) );
  248. 									}
  249. 								}
  250. 								catch ( Exception e )
  251. 								{
  252. 									return ShowHelp( String.Format( "Invalid tab length \"{0}\": {1}", arg.Substring( 3 ), e.Message ) );
  253. 								}
  254. 								tablengthset = true;
  255. 								break;
  256. 							case "/W:":
  257. 								if ( widthset )
  258. 								{
  259. 									return ShowHelp( "Duplicate command line switch /W" );
  260. 								}
  261. 								try
  262. 								{
  263. 									width = Convert.ToInt32( arg.Substring( 3 ) );
  264. 									if ( width < defaultwidth || width > Screen.PrimaryScreen.Bounds.Width )
  265. 									{
  266. 										return ShowHelp( String.Format( "Width {0} outside allowed range of {1}..{2}", arg.Substring( 3 ), defaultwidth, Screen.PrimaryScreen.Bounds.Width ) );
  267. 									}
  268. 								}
  269. 								catch ( Exception e )
  270. 								{
  271. 									return ShowHelp( String.Format( "Invalid width \"{0}\": {1}", arg.Substring( 3 ), e.Message ) );
  272. 								}
  273. 								widthset = true;
  274. 								break;
  275. 							default:
  276. 								return ShowHelp( String.Format( "Invalid command line switch \"{0}\"", arg ) );
  277. 						}
  278. 					}
  279. 				}
  280.  
  281. 				#endregion Named Arguments
  282.  
  283.  
  284. 				// Next, validate unnamed arguments
  285. 				#region Unnamed Arguments
  286.  
  287. 				if ( listset ) // This check is the reason why named arguments had to be validated before unnamed ones: /F switch changes the meaning of unnamed arguments
  288. 				{
  289. 					switch ( unnamedargs.Count )
  290. 					{
  291. 						case 0:
  292. 							break;
  293. 						case 1:
  294. 							prompt = unnamedargs[0];
  295. 							break;
  296. 						case 2:
  297. 							prompt = unnamedargs[0];
  298. 							title = unnamedargs[1];
  299. 							break;
  300. 						case 3:
  301. 							return ShowHelp( "Invalid command line argument: {0}", unnamedargs[2] );
  302. 						default:
  303. 							unnamedargs.RemoveRange( 0, 2 );
  304. 							return ShowHelp( "Invalid command line arguments: {0}", String.Join( ", ", unnamedargs ) );
  305. 					}
  306. 				}
  307. 				else
  308. 				{
  309. 					switch ( unnamedargs.Count )
  310. 					{
  311. 						case 0:
  312. 							break;
  313. 						case 1:
  314. 							list = unnamedargs[0];
  315. 							listset = true;
  316. 							break;
  317. 						case 2:
  318. 							list = unnamedargs[0];
  319. 							prompt = unnamedargs[1];
  320. 							listset = true;
  321. 							break;
  322. 						case 3:
  323. 							list = unnamedargs[0];
  324. 							prompt = unnamedargs[1];
  325. 							title = unnamedargs[2];
  326. 							listset = true;
  327. 							break;
  328. 						case 4:
  329. 							return ShowHelp( "Invalid command line argument: {0}", unnamedargs[3] );
  330. 						default:
  331. 							unnamedargs.RemoveRange( 0, 3 );
  332. 							return ShowHelp( "Invalid command line arguments: {0}", String.Join( ", ", unnamedargs ) );
  333. 					}
  334. 				}
  335.  
  336. 				#endregion Unnamed Arguments
  337.  
  338.  
  339. 				// List is mandatory
  340. 				if ( !listset )
  341. 				{
  342. 					return ShowHelp( "No list specified" );
  343. 				}
  344.  
  345. 				// Validate selected index
  346. 				int listrange = list.Split( delimiter ).Length - 1;
  347. 				if ( selectedindex < 0 || selectedindex > listrange )
  348. 				{
  349. 					return ShowHelp( String.Format( "Selected index ({0}) outside list range (0..{0})", selectedindex, listrange ) );
  350. 				}
  351.  
  352. 				#endregion Command Line Parsing
  353.  
  354.  
  355. 				#region Set Localized Captions
  356.  
  357. 				if ( localizedcaptionset )
  358. 				{
  359. 					cancelcaption = Load( "user32.dll", 801, cancelcaption );
  360. 					okcaption = Load( "user32.dll", 800, okcaption );
  361.  
  362. 					if ( !String.IsNullOrWhiteSpace( localizationstring ) )
  363. 					{
  364. 						string[] locstrings = localizationstring.Split( ";".ToCharArray( ) );
  365. 						foreach ( string locstring in locstrings )
  366. 						{
  367. 							string key = locstring.Substring( 0, locstring.IndexOf( '=' ) );
  368. 							string val = locstring.Substring( Math.Min( locstring.IndexOf( '=' ) + 1, locstring.Length - 1 ) );
  369. 							if ( !String.IsNullOrWhiteSpace( val ) )
  370. 							{
  371. 								switch ( key.ToUpper( ) )
  372. 								{
  373. 									case "OK":
  374. 										okcaption = val;
  375. 										break;
  376. 									case "CANCEL":
  377. 										cancelcaption = val;
  378. 										break;
  379. 									default:
  380. 										return ShowHelp( "Invalid localization key \"{0}\"", key );
  381. 								}
  382. 							}
  383. 						}
  384. 					}
  385. 				}
  386.  
  387. 				#endregion Set Localized Captions
  388.  
  389.  
  390. 				#region Build Form
  391.  
  392. 				// Inspired by code by Gorkem Gencay on StackOverflow.com:
  393. 				// http://stackoverflow.com/questions/97097/what-is-the-c-sharp-version-of-vb-nets-inputdialog#17546909
  394.  
  395. 				Form dropdownForm = new Form( );
  396. 				Size size = new Size( width, height );
  397. 				dropdownForm.FormBorderStyle = FormBorderStyle.FixedDialog;
  398. 				dropdownForm.MaximizeBox = false;
  399. 				dropdownForm.MinimizeBox = false;
  400. 				dropdownForm.StartPosition = FormStartPosition.CenterParent;
  401. 				dropdownForm.ClientSize = size;
  402. 				dropdownForm.Text = title;
  403. 				dropdownForm.Icon = IconExtractor.Extract( "shell32.dll", icon, true );
  404.  
  405. 				if ( !String.IsNullOrWhiteSpace( prompt ) )
  406. 				{
  407. 					Label labelPrompt = new Label( );
  408. 					labelPrompt.Size = new Size( size.Width - 20, 20 );
  409. 					labelPrompt.Location = new Point( 10, 10 );
  410. 					// Replace tabs with spaces
  411. 					if ( prompt.IndexOf( "\\t", StringComparison.Ordinal ) > -1 )
  412. 					{
  413. 						string tab = new String( ' ', tablength );
  414. 						// First split the prompt on newlines
  415. 						string[] prompt2 = prompt.Split( new string[] { "\\n" }, StringSplitOptions.None );
  416. 						for ( int i = 0; i < prompt2.Length; i++ )
  417. 						{
  418. 							if ( prompt2[i].IndexOf( "\\t", StringComparison.Ordinal ) > -1 )
  419. 							{
  420. 								// Slit each "sub-line" of the prompt on tabs
  421. 								string[] prompt3 = prompt2[i].Split( new string[] { "\\t" }, StringSplitOptions.None );
  422. 								// Each substring before a tab gets n spaces attached, and then is cut off at the highest possible length which is a multiple of n
  423. 								for ( int j = 0; j < prompt3.Length - 1; j++ )
  424. 								{
  425. 									prompt3[j] += tab;
  426. 									int length = prompt3[j].Length;
  427. 									length /= tablength;
  428. 									length *= tablength;
  429. 									prompt3[j] = prompt3[j].Substring( 0, length );
  430. 								}
  431. 								prompt2[i] = String.Join( "", prompt3 );
  432. 							}
  433. 						}
  434. 						prompt = String.Join( "\n", prompt2 );
  435. 					}
  436. 					labelPrompt.Text = prompt.Replace( "\\n", "\n" ).Replace( "\\r", "\r" );
  437. 					if ( !heightset )
  438. 					{
  439. 						// Add 20 to window height to allow space for prompt
  440. 						size = new Size( size.Width, size.Height + 20 );
  441. 						dropdownForm.ClientSize = size;
  442. 					}
  443. 					labelPrompt.Size = new Size( size.Width - 20, size.Height - 90 );
  444. 					if ( monospaced )
  445. 					{
  446. 						labelPrompt.Font = new Font( FontFamily.GenericMonospace, labelPrompt.Font.Size );
  447. 					}
  448. 					dropdownForm.Controls.Add( labelPrompt );
  449. 				}
  450.  
  451. 				ComboBox combobox;
  452. 				combobox = new ComboBox( );
  453. 				combobox.Size = new Size( size.Width - 20, 25 );
  454. 				combobox.Location = new Point( 10, size.Height - 70 );
  455. 				combobox.AutoCompleteMode = AutoCompleteMode.Append;
  456. 				combobox.AutoCompleteSource = AutoCompleteSource.ListItems;
  457. 				combobox.DropDownStyle = ComboBoxStyle.DropDownList;
  458. 				dropdownForm.Controls.Add( combobox );
  459.  
  460. 				Button okButton = new Button( );
  461. 				okButton.DialogResult = DialogResult.OK;
  462. 				okButton.Name = "okButton";
  463. 				okButton.Size = new Size( 80, 25 );
  464. 				okButton.Text = okcaption;
  465. 				okButton.Location = new Point( size.Width / 2 - 10 - 80, size.Height - 35 );
  466. 				dropdownForm.Controls.Add( okButton );
  467.  
  468. 				Button cancelButton = new Button( );
  469. 				cancelButton.DialogResult = DialogResult.Cancel;
  470. 				cancelButton.Name = "cancelButton";
  471. 				cancelButton.Size = new Size( 80, 25 );
  472. 				cancelButton.Text = cancelcaption;
  473. 				cancelButton.Location = new Point( size.Width / 2 + 10, size.Height - 35 );
  474. 				dropdownForm.Controls.Add( cancelButton );
  475.  
  476. 				dropdownForm.AcceptButton = okButton;  // OK on Enter
  477. 				dropdownForm.CancelButton = cancelButton; // Cancel on Esc
  478. 				dropdownForm.Activate( );
  479.  
  480. 				// Populate the dropdown list
  481. 				foreach ( string item in list.Split( delimiter ) )
  482. 				{
  483. 					combobox.Items.Add( item );
  484. 				}
  485. 				// Preselect an item
  486. 				combobox.SelectedIndex = selectedindex;
  487.  
  488. 				#endregion Build Form
  489.  
  490.  
  491. 				dropdownForm.TopMost = topmost;
  492. 				DialogResult result = dropdownForm.ShowDialog( );
  493. 				if ( result == DialogResult.OK )
  494. 				{
  495. 					selectedText = combobox.SelectedItem.ToString( );
  496. 					Console.WriteLine( selectedText );
  497. 					return ( returnindex ? combobox.SelectedIndex + 1 : 0 );
  498. 				}
  499. 				else
  500. 				{
  501. 					return ( returnindex ? 0 : 2 );
  502. 				}
  503. 			}
  504. 			catch ( Exception e )
  505. 			{
  506. 				return ShowHelp( e.Message );
  507. 			}
  508. 		}
  509.  
  510.  
  511. 		#region Error handling
  512.  
  513. 		public static int ShowHelp( params string[] errmsg )
  514. 		{
  515. 			/*
  516. 			DropDownBox,  Version 1.10
  517. 			Batch tool to present a DropDown dialog and return the selected item
  518.  
  519. 			Usage:    DROPDOWNBOX     [ "list" ]  [ "prompt"  [ "title" ] ]  [ options ]
  520.  
  521. 			Where:    "list"          is the list of items to populate the dropdown control
  522. 			          "prompt"        is the optional text above the dropdown control
  523. 			                          (default: none)
  524. 			          "title"         is the window title
  525. 			                          (default: "DropDownBox,  Version 1.10")
  526. 			Options:  /W:width        sets the Width of the input box
  527. 			                          (default: 200; minimum: 200; maximum: screen width)
  528. 			          /H:height       sets the Height of the input box
  529. 			                          (default: 90; minimum: 90; maximum: screen height)
  530. 			          /C:index        use iCon at index from shell32.dll (default: 23)
  531. 			          /D:"delimiter"  sets the Delimiter character for "list"
  532. 			                          (default: semicolon)
  533. 			          /F:"listfile"   use list from text File (one list item per line)
  534. 			          /I:index        sets the zero based Index of the preselected item
  535. 			                          (default: 0)
  536. 			          /L[:"captions"] Localize or customize button captions
  537. 			                          (e.g. /L:"OK=Why Not?;Cancel=No Way!")
  538. 			          /T:tablength    sets the number of spaces for Tabs in prompt
  539. 			                          (4..16; default: 4)
  540. 			          /MF             use Monospaced Font in prompt (default: proportional)
  541. 			          /NM             make dialog Non-Modal (default: Modal, i.e. on top)
  542. 			          /RI             Return code equals selected Index + 1, or 0 on
  543. 			                          (command line) errors or if "Cancel" was clicked
  544. 			                          (default: 0 on "OK", 1 on error, 2 on "Cancel")
  545.  
  546. 			Notes:    The selected item text is written to Standard Out if "OK" is clicked,
  547. 			          otherwise an empty string is returned.
  548. 			          Use either "list" or /F:"listfile", not both.
  549. 			          Linefeeds (\n), tabs (\t) and doublequotes (\") are allowed in the
  550. 			          prompt text (but not in the title); with tabs, /MF is recommended.
  551. 			          If specified without captions, switch /L forces localized button
  552. 			          captions (e.g. "Cancel" button caption is "Annuleren" on Dutch
  553. 			          systems); if only a single custom caption is specified, the other
  554. 			          one is localized (e.g. with /L:"OK=Gaan" on Dutch systems, "OK"
  555. 			          button caption is "Gaan", "Cancel" button caption is "Annuleren").
  556. 			          Return code 0 for \"OK\", 1 for (command line) errors, 2 for "Cancel".
  557. 			          With /RI return code equals selected index +1 or 0 for "Cancel".
  558.  
  559. 			Credits:  On-the-fly form based on code by Gorkem Gencay on StackOverflow:
  560. 			          http://stackoverflow.com/questions/97097#17546909
  561. 			          Code to retrieve localized button captions by Martin Stoeckli:
  562. 			          http://martinstoeckli.ch/csharp/csharp.html#windows_text_resources
  563. 			          Code to extract icons from Shell32.dll by Thomas Levesque:
  564. 			          http://stackoverflow.com/questions/6873026
  565.  
  566. 			Written by Rob van der Woude
  567. 			http://www.robvanderwoude.com
  568. 			*/
  569.  
  570. 			if ( errmsg.Length > 0 )
  571. 			{
  572. 				List<string> errargs = new List<string>( errmsg );
  573. 				errargs.RemoveAt( 0 );
  574. 				Console.Error.WriteLine( );
  575. 				Console.ForegroundColor = ConsoleColor.Red;
  576. 				Console.Error.Write( "ERROR:\t" );
  577. 				Console.ForegroundColor = ConsoleColor.White;
  578. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  579. 				Console.ResetColor( );
  580. 			}
  581.  
  582. 			Console.Error.WriteLine( );
  583.  
  584. 			Console.Error.WriteLine( "DropDownBox,  Version {0}", progver );
  585.  
  586. 			Console.Error.WriteLine( "Batch tool to present a DropDown dialog and return the selected item" );
  587.  
  588. 			Console.Error.WriteLine( );
  589.  
  590. 			Console.Error.Write( "Usage:    " );
  591. 			Console.ForegroundColor = ConsoleColor.White;
  592. 			Console.Error.WriteLine( "DROPDOWNBOX     [ \"list\" ]  [ \"prompt\"  [ \"title\" ] ]  [ options ]" );
  593. 			Console.ResetColor( );
  594.  
  595. 			Console.Error.WriteLine( );
  596.  
  597. 			Console.Error.Write( "Where:    " );
  598. 			Console.ForegroundColor = ConsoleColor.White;
  599. 			Console.Error.Write( "\"list\"" );
  600. 			Console.ResetColor( );
  601. 			Console.Error.WriteLine( "          is the list of items to populate the dropdown control" );
  602.  
  603. 			Console.ForegroundColor = ConsoleColor.White;
  604. 			Console.Error.Write( "          \"prompt\"" );
  605. 			Console.ResetColor( );
  606. 			Console.Error.WriteLine( "        is the optional text above the dropdown control" );
  607.  
  608. 			Console.Error.WriteLine( "                          (default: none)" );
  609.  
  610. 			Console.ForegroundColor = ConsoleColor.White;
  611. 			Console.Error.Write( "          \"title\"" );
  612. 			Console.ResetColor( );
  613. 			Console.Error.WriteLine( "         is the window title" );
  614.  
  615. 			Console.Error.WriteLine( "                          (default: \"DropDownBox,  Version {0}\")", progver );
  616.  
  617. 			Console.ForegroundColor = ConsoleColor.White;
  618. 			Console.Error.Write( "Options:  /W:width" );
  619. 			Console.ResetColor( );
  620. 			Console.Error.Write( "        sets the " );
  621. 			Console.ForegroundColor = ConsoleColor.White;
  622. 			Console.Error.Write( "W" );
  623. 			Console.ResetColor( );
  624. 			Console.Error.WriteLine( "idth of the input box" );
  625.  
  626. 			Console.Error.WriteLine( "                          (default: 200; minimum: 200; maximum: screen width)" );
  627.  
  628. 			Console.ForegroundColor = ConsoleColor.White;
  629. 			Console.Error.Write( "          /H:height" );
  630. 			Console.ResetColor( );
  631. 			Console.Error.Write( "       sets the " );
  632. 			Console.ForegroundColor = ConsoleColor.White;
  633. 			Console.Error.Write( "H" );
  634. 			Console.ResetColor( );
  635. 			Console.Error.WriteLine( "eight of the input box" );
  636.  
  637. 			Console.Error.WriteLine( "                          (default: 90; minimum: 90; maximum: screen height)" );
  638.  
  639. 			Console.ForegroundColor = ConsoleColor.White;
  640. 			Console.Error.Write( "          /C:index" );
  641. 			Console.ResetColor( );
  642. 			Console.Error.Write( "        use i" );
  643. 			Console.ForegroundColor = ConsoleColor.White;
  644. 			Console.Error.Write( "C" );
  645. 			Console.ResetColor( );
  646. 			Console.Error.Write( "on at " );
  647. 			Console.ForegroundColor = ConsoleColor.White;
  648. 			Console.Error.Write( "index" );
  649. 			Console.ResetColor( );
  650. 			Console.Error.WriteLine( " from shell32.dll (default: 23)" );
  651.  
  652. 			Console.ForegroundColor = ConsoleColor.White;
  653. 			Console.Error.Write( "          /D:\"delimiter\"" );
  654. 			Console.ResetColor( );
  655. 			Console.Error.Write( "  sets the " );
  656. 			Console.ForegroundColor = ConsoleColor.White;
  657. 			Console.Error.Write( "D" );
  658. 			Console.ResetColor( );
  659. 			Console.Error.Write( "elimiter character for " );
  660. 			Console.ForegroundColor = ConsoleColor.White;
  661. 			Console.Error.WriteLine( "\"list\"" );
  662. 			Console.ResetColor( );
  663.  
  664. 			Console.Error.WriteLine( "                          (default: semicolon)" );
  665.  
  666. 			Console.ForegroundColor = ConsoleColor.White;
  667. 			Console.Error.Write( "          /F:\"listfile\"" );
  668. 			Console.ResetColor( );
  669. 			Console.Error.Write( "   use list from text " );
  670. 			Console.ForegroundColor = ConsoleColor.White;
  671. 			Console.Error.Write( "F" );
  672. 			Console.ResetColor( );
  673. 			Console.Error.WriteLine( "ile (one list item per line)" );
  674.  
  675. 			Console.ForegroundColor = ConsoleColor.White;
  676. 			Console.Error.Write( "          /I:index" );
  677. 			Console.ResetColor( );
  678. 			Console.Error.Write( "        sets the zero based " );
  679. 			Console.ForegroundColor = ConsoleColor.White;
  680. 			Console.Error.Write( "I" );
  681. 			Console.ResetColor( );
  682. 			Console.Error.WriteLine( "ndex of the preselected item" );
  683.  
  684. 			Console.Error.WriteLine( "                          (default: 0)" );
  685.  
  686. 			Console.ForegroundColor = ConsoleColor.White;
  687. 			Console.Error.Write( "          /L[:\"captions\"] L" );
  688. 			Console.ResetColor( );
  689. 			Console.Error.Write( "ocalize or customize button " );
  690. 			Console.ForegroundColor = ConsoleColor.White;
  691. 			Console.Error.WriteLine( "captions" );
  692. 			Console.ResetColor( );
  693.  
  694. 			Console.Error.Write( "                          (e.g. " );
  695. 			Console.ForegroundColor = ConsoleColor.White;
  696. 			Console.Error.Write( "/L:\"OK=Why Not?;Cancel=No Way!\"" );
  697. 			Console.ResetColor( );
  698. 			Console.Error.WriteLine( ")" );
  699.  
  700. 			Console.ForegroundColor = ConsoleColor.White;
  701. 			Console.Error.Write( "          /T:tablength" );
  702. 			Console.ResetColor( );
  703. 			Console.Error.Write( "    sets the number of spaces for " );
  704. 			Console.ForegroundColor = ConsoleColor.White;
  705. 			Console.Error.Write( "T" );
  706. 			Console.ResetColor( );
  707. 			Console.Error.Write( "abs in " );
  708. 			Console.ForegroundColor = ConsoleColor.White;
  709. 			Console.Error.WriteLine( "prompt" );
  710. 			Console.ResetColor( );
  711.  
  712. 			Console.Error.WriteLine( "                          (4..16; default: 4)" );
  713.  
  714. 			Console.ForegroundColor = ConsoleColor.White;
  715. 			Console.Error.Write( "          /MF" );
  716. 			Console.ResetColor( );
  717. 			Console.Error.Write( "             use " );
  718. 			Console.ForegroundColor = ConsoleColor.White;
  719. 			Console.Error.Write( "M" );
  720. 			Console.ResetColor( );
  721. 			Console.Error.Write( "onospaced " );
  722. 			Console.ForegroundColor = ConsoleColor.White;
  723. 			Console.Error.Write( "F" );
  724. 			Console.ResetColor( );
  725. 			Console.Error.Write( "ont in " );
  726. 			Console.ForegroundColor = ConsoleColor.White;
  727. 			Console.Error.Write( "prompt" );
  728. 			Console.ResetColor( );
  729. 			Console.Error.WriteLine( " (default: proportional)" );
  730.  
  731. 			Console.ForegroundColor = ConsoleColor.White;
  732. 			Console.Error.Write( "          /NM" );
  733. 			Console.ResetColor( );
  734. 			Console.Error.Write( "             make dialog " );
  735. 			Console.ForegroundColor = ConsoleColor.White;
  736. 			Console.Error.Write( "N" );
  737. 			Console.ResetColor( );
  738. 			Console.Error.Write( "on-" );
  739. 			Console.ForegroundColor = ConsoleColor.White;
  740. 			Console.Error.Write( "M" );
  741. 			Console.ResetColor( );
  742. 			Console.Error.WriteLine( "odal (default: modal, i.e. on top)" );
  743.  
  744. 			Console.ForegroundColor = ConsoleColor.White;
  745. 			Console.Error.Write( "          /RI             R" );
  746. 			Console.ResetColor( );
  747. 			Console.Error.Write( "eturn code equals selected " );
  748. 			Console.ForegroundColor = ConsoleColor.White;
  749. 			Console.Error.Write( "I" );
  750. 			Console.ResetColor( );
  751. 			Console.Error.WriteLine( "ndex + 1, or 0 on" );
  752.  
  753. 			Console.Error.WriteLine( "                          (command line) errors or if \"Cancel\" was clicked" );
  754.  
  755. 			Console.Error.WriteLine( "                          (default: 0 on \"OK\", 1 on error, 2 on \"Cancel\")" );
  756.  
  757. 			Console.Error.WriteLine( );
  758.  
  759. 			Console.Error.WriteLine( "Notes:    The selected item text is written to Standard Out if \"OK\" is clicked," );
  760.  
  761. 			Console.Error.WriteLine( "          otherwise an empty string is returned." );
  762.  
  763. 			Console.Error.Write( "          Use either " );
  764. 			Console.ForegroundColor = ConsoleColor.White;
  765. 			Console.Error.Write( "\"list\"" );
  766. 			Console.ResetColor( );
  767. 			Console.Error.Write( " or " );
  768. 			Console.ForegroundColor = ConsoleColor.White;
  769. 			Console.Error.Write( "/F:\"listfile\"" );
  770. 			Console.ResetColor( );
  771. 			Console.Error.WriteLine( ", not both." );
  772.  
  773. 			Console.Error.WriteLine( "          Linefeeds (\\n), tabs (\\t) and doublequotes (\\\") are allowed in the" );
  774.  
  775. 			Console.ForegroundColor = ConsoleColor.White;
  776. 			Console.Error.Write( "          prompt" );
  777. 			Console.ResetColor( );
  778. 			Console.Error.Write( " text (but not in the " );
  779. 			Console.ForegroundColor = ConsoleColor.White;
  780. 			Console.Error.Write( "title" );
  781. 			Console.ResetColor( );
  782. 			Console.Error.Write( "); with tabs, " );
  783. 			Console.ForegroundColor = ConsoleColor.White;
  784. 			Console.Error.Write( "/MF" );
  785. 			Console.ResetColor( );
  786. 			Console.Error.WriteLine( " is recommended." );
  787.  
  788. 			Console.Error.Write( "          If specified without " );
  789. 			Console.ForegroundColor = ConsoleColor.White;
  790. 			Console.Error.Write( "captions" );
  791. 			Console.ResetColor( );
  792. 			Console.Error.Write( ", switch " );
  793. 			Console.ForegroundColor = ConsoleColor.White;
  794. 			Console.Error.Write( "/L" );
  795. 			Console.ResetColor( );
  796. 			Console.Error.WriteLine( " forces localized button" );
  797.  
  798. 			Console.Error.WriteLine( "          captions (e.g. \"Cancel\" button caption is \"Annuleren\" on Dutch" );
  799.  
  800. 			Console.Error.WriteLine( "          systems); if only a single custom caption is specified, the other" );
  801.  
  802. 			Console.Error.Write( "          one is localized (e.g. with " );
  803. 			Console.ForegroundColor = ConsoleColor.White;
  804. 			Console.Error.Write( "/L:\"OK=Gaan\"" );
  805. 			Console.ResetColor( );
  806. 			Console.Error.WriteLine( " on Dutch systems, \"OK\"" );
  807.  
  808. 			Console.Error.WriteLine( "          button caption is \"Gaan\", \"Cancel\" button caption is \"Annuleren\")." );
  809.  
  810. 			Console.Error.WriteLine( "          Return code 0 for \"OK\", 1 for (command line) errors, 2 for \"Cancel\"." );
  811.  
  812. 			Console.Error.Write( "          With " );
  813. 			Console.ForegroundColor = ConsoleColor.White;
  814. 			Console.Error.Write( "/RI" );
  815. 			Console.ResetColor( );
  816. 			Console.Error.WriteLine( " return code equals selected index + 1, or 0 for \"Cancel\"." );
  817.  
  818. 			Console.Error.WriteLine( );
  819.  
  820. 			Console.Error.WriteLine( "Credits:  On-the-fly form based on code by Gorkem Gencay on StackOverflow:" );
  821.  
  822. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  823. 			Console.Error.WriteLine( "          http://stackoverflow.com/questions/17546909" );
  824. 			Console.ResetColor( );
  825.  
  826. 			Console.Error.WriteLine( "          Code to retrieve localized button captions by Martin Stoeckli:" );
  827.  
  828. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  829. 			Console.Error.WriteLine( "          http://martinstoeckli.ch/csharp/csharp.html#windows_text_resources" );
  830. 			Console.ResetColor( );
  831.  
  832. 			Console.Error.WriteLine( "          Code to extract icons from Shell32.dll by Thomas Levesque:" );
  833.  
  834. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  835. 			Console.Error.WriteLine( "          http://stackoverflow.com/questions/6873026" );
  836. 			Console.ResetColor( );
  837.  
  838. 			Console.Error.WriteLine( );
  839.  
  840. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  841.  
  842. 			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  843.  
  844. 			return ( returnindex ? 0 : 1 );
  845. 		}
  846.  
  847. 		#endregion Error handling
  848.  
  849.  
  850. 		#region Get Localized Captions
  851.  
  852. 		// Code to retrieve localized captions by Martin Stoeckli
  853. 		// http://martinstoeckli.ch/csharp/csharp.html#windows_text_resources
  854.  
  855. 		/// <summary>
  856. 		/// Searches for a text resource in a Windows library.
  857. 		/// Sometimes, using the existing Windows resources, you can make your code
  858. 		/// language independent and you don't have to care about translation problems.
  859. 		/// </summary>
  860. 		/// <example>
  861. 		///   btnCancel.Text = Load("user32.dll", 801, "Cancel");
  862. 		///   btnYes.Text = Load("user32.dll", 805, "Yes");
  863. 		/// </example>
  864. 		/// <param name="libraryName">Name of the windows library like "user32.dll"
  865. 		/// or "shell32.dll"</param>
  866. 		/// <param name="ident">Id of the string resource.</param>
  867. 		/// <param name="defaultText">Return this text, if the resource string could
  868. 		/// not be found.</param>
  869. 		/// <returns>Requested string if the resource was found,
  870. 		/// otherwise the <paramref name="defaultText"/></returns>
  871. 		public static string Load( string libraryName, UInt32 ident, string defaultText )
  872. 		{
  873. 			IntPtr libraryHandle = GetModuleHandle( libraryName );
  874. 			if ( libraryHandle != IntPtr.Zero )
  875. 			{
  876. 				StringBuilder sb = new StringBuilder( 1024 );
  877. 				int size = LoadString( libraryHandle, ident, sb, 1024 );
  878. 				if ( size > 0 )
  879. 					return sb.ToString( );
  880. 			}
  881. 			return defaultText;
  882. 		}
  883.  
  884. 		[DllImport( "kernel32.dll", CharSet = CharSet.Auto )]
  885. 		private static extern IntPtr GetModuleHandle( string lpModuleName );
  886.  
  887. 		[DllImport( "user32.dll", CharSet = CharSet.Auto )]
  888. 		private static extern int LoadString( IntPtr hInstance, UInt32 uID, StringBuilder lpBuffer, Int32 nBufferMax );
  889.  
  890. 		#endregion Get Localized Captions
  891.  
  892.  
  893. 		#region Extract Icons
  894.  
  895. 		// Code to extract icons from Shell32.dll by Thomas Levesque
  896. 		// http://stackoverflow.com/questions/6873026
  897.  
  898. 		public class IconExtractor
  899. 		{
  900.  
  901. 			public static Icon Extract( string file, int number, bool largeIcon )
  902. 			{
  903. 				IntPtr large;
  904. 				IntPtr small;
  905. 				ExtractIconEx( file, number, out large, out small, 1 );
  906. 				try
  907. 				{
  908. 					return Icon.FromHandle( largeIcon ? large : small );
  909. 				}
  910. 				catch
  911. 				{
  912. 					return null;
  913. 				}
  914.  
  915. 			}
  916.  
  917. 			[DllImport( "Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall )]
  918. 			private static extern int ExtractIconEx( string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons );
  919. 		}
  920.  
  921. 		#endregion Extract Icons
  922. 	}
  923. }
  924.  

page last uploaded: 2017-04-06, 13:33