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

page last uploaded: 2018-12-04, 10:47