Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for inputboxwf.cs

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Timers;
  11. using System.Windows.Forms;
  12.  
  13.  
  14. namespace RobvanderWoude
  15. {
  16.     static class InputBoxWF
  17.     {
  18.         /// <summary>
  19.         /// The main entry point for the application.
  20.         /// </summary>
  21.  
  22.         public const string progver = "1.00";
  23.  
  24.  
  25.         #region Global Variables
  26.  
  27.         public const int defheight = 110;
  28.         public const int deftimeout = 60;
  29.         public const int defwidth = 200;
  30.         public const string defaulttitle = "© 2019 Rob van der Woude";
  31.  
  32.         public static MaskedTextBox maskedtextbox;
  33.         public static TextBox textbox;
  34.         public static RegexOptions casesensitivity = RegexOptions.None;
  35.         public static bool asciionly = false;
  36.         public static bool filtered = true;
  37.         public static bool oddrow = false;
  38.         public static bool ontheflyregexset = false;
  39.         public static bool password = false;
  40.         public static bool timeoutelapsed = false;
  41.         public static bool usemask = false;
  42.         public static bool regexset = false;
  43.         public static bool returnunmasked = false;
  44.         public static bool sendoutputtoclipboard = false;
  45.         public static string currentinput = String.Empty;
  46.         public static string defanswer = "Default answer";
  47.         public static string ontheflypattern = ".*";
  48.         public static string outputfile = string.Empty;
  49.         public static string previousinput = String.Empty;
  50.         public static string regexpattern = ".*";
  51.  
  52.         #endregion Global Variables
  53.  
  54.  
  55.         [STAThread]
  56.         static void Main()
  57.         {
  58.             Application.EnableVisualStyles( );
  59.             Application.SetCompatibleTextRenderingDefault( false );
  60.             string[] arguments = Environment.GetCommandLineArgs( ).Skip( 1 ).ToArray( );
  61.             InputBox( arguments );
  62.         }
  63.  
  64.  
  65.         [STAThread]
  66.         static int InputBox( string[] args )
  67.         {
  68.             // Based on code by Gorkem Gencay on StackOverflow.com:
  69.             // http://stackoverflow.com/questions/97097/what-is-the-c-sharp-version-of-vb-nets-inputdialog#17546909
  70.  
  71.             #region Initialize variables
  72.  
  73.             const string deftitle = "Title";
  74.             const string deftext = "Prompt";
  75.  
  76.             bool heightset = false;
  77.             bool showpassword = false;
  78.             bool timeoutset = false;
  79.             bool widthset = false;
  80.             string input = string.Empty;
  81.             string mask = String.Empty;
  82.             string showpasswordprompt = "Show password";
  83.             string text = deftext;
  84.             string title = deftitle;
  85.             int height = defheight;
  86.             int timeout = 0;
  87.             int width = defwidth;
  88.             string cancelcaption = "&Cancel";
  89.             string okcaption = "&OK";
  90.             string localizationstring = String.Empty;
  91.             bool localizedcaptionset = false;
  92.  
  93.             #endregion Initialize variables
  94.  
  95.  
  96.             #region Command Line Parsing
  97.  
  98.             if ( args.Length == 0 )
  99.             {
  100.                 return ShowHelp( );
  101.             }
  102.  
  103.             foreach ( string arg in args )
  104.             {
  105.                 if ( arg == "/?" )
  106.                 {
  107.                     return ShowHelp( );
  108.                 }
  109.             }
  110.  
  111.             text = String.Empty;
  112.             title = String.Empty;
  113.             defanswer = String.Empty;
  114.  
  115.             foreach ( string arg in args )
  116.             {
  117.                 if ( arg[0] == '/' )
  118.                 {
  119.                     if ( arg.Length == 1 )
  120.                     {
  121.                         return ShowHelp( );
  122.                     }
  123.                     else if ( arg.Length == 2 )
  124.                     {
  125.                         switch ( arg.ToString( ).ToUpper( ) )
  126.                         {
  127.                             case "/A":
  128.                                 if ( asciionly )
  129.                                 {
  130.                                     return ShowHelp( "Duplicate command line switch /A" );
  131.                                 }
  132.                                 asciionly = true;
  133.                                 break;
  134.                             case "/C":
  135.                                 if ( !string.IsNullOrWhiteSpace( outputfile ) )
  136.                                 {
  137.                                     return ShowHelp( "Command line switches /C and /E are mutually exclusive" );
  138.                                 }
  139.                                 if ( sendoutputtoclipboard )
  140.                                 {
  141.                                     return ShowHelp( "Duplicate command line switch /C" );
  142.                                 }
  143.                                 sendoutputtoclipboard = true;
  144.                                 break;
  145.                             case "/E":
  146.                                 if ( sendoutputtoclipboard )
  147.                                 {
  148.                                     return ShowHelp( "Command line switches /C and /E are mutually exclusive" );
  149.                                 }
  150.                                 if ( !string.IsNullOrWhiteSpace( outputfile ) )
  151.                                 {
  152.                                     return ShowHelp( "Duplicate command line switch /E" );
  153.                                 }
  154.                                 sendoutputtoclipboard = false;
  155.                                 outputfile = Path.Combine( Directory.GetParent( Application.ExecutablePath ).FullName, Path.GetFileNameWithoutExtension( Application.ExecutablePath ) + ".tmp" );
  156.                                 break;
  157.                             case "/I":
  158.                                 if ( casesensitivity == RegexOptions.IgnoreCase )
  159.                                 {
  160.                                     return ShowHelp( "Duplicate command line switch /I" );
  161.                                 }
  162.                                 casesensitivity = RegexOptions.IgnoreCase;
  163.                                 break;
  164.                             case "/L":
  165.                                 if ( localizedcaptionset )
  166.                                 {
  167.                                     return ShowHelp( "Duplicate command line switch /L" );
  168.                                 }
  169.                                 localizedcaptionset = true;
  170.                                 break;
  171.                             case "/M":
  172.                                 return HelpMessage( "mask" );
  173.                             case "/N":
  174.                                 if ( !filtered )
  175.                                 {
  176.                                     return ShowHelp( "Duplicate command line switch /N" );
  177.                                 }
  178.                                 filtered = false;
  179.                                 break;
  180.                             case "/P":
  181.                                 if ( password )
  182.                                 {
  183.                                     return ShowHelp( "Duplicate command line switch /P" );
  184.                                 }
  185.                                 password = true;
  186.                                 break;
  187.                             case "/S":
  188.                                 if ( showpassword )
  189.                                 {
  190.                                     return ShowHelp( "Duplicate command line switch /S" );
  191.                                 }
  192.                                 showpassword = true;
  193.                                 break;
  194.                             case "/T":
  195.                                 if ( timeoutset )
  196.                                 {
  197.                                     return ShowHelp( "Duplicate command line switch /T" );
  198.                                 }
  199.                                 timeout = deftimeout;
  200.                                 timeoutset = true;
  201.                                 break;
  202.                             case "/U":
  203.                                 if ( returnunmasked )
  204.                                 {
  205.                                     return ShowHelp( "Duplicate command line switch /U" );
  206.                                 }
  207.                                 returnunmasked = true;
  208.                                 break;
  209.                             default:
  210.                                 return ShowHelp( "Invalid command line switch {0}", arg );
  211.                         }
  212.                     }
  213.                     else if ( arg.Length > 3 && arg[2] == ':' )
  214.                     {
  215.                         switch ( arg.Substring( 0, 3 ).ToUpper( ) )
  216.                         {
  217.                             case "/E:":
  218.                                 if ( sendoutputtoclipboard )
  219.                                 {
  220.                                     return ShowHelp( "Command line switches /C and /E are mutually exclusive" );
  221.                                 }
  222.                                 if ( !string.IsNullOrWhiteSpace( outputfile ) )
  223.                                 {
  224.                                     return ShowHelp( "Duplicate command line switch /E" );
  225.                                 }
  226.                                 sendoutputtoclipboard = false;
  227.                                 outputfile = String.Format( "^{0}$", arg.Substring( 3 ) );
  228.                                 break;
  229.                             case "/F:":
  230.                                 if ( ontheflyregexset )
  231.                                 {
  232.                                     return ShowHelp( "Duplicate command line switch /F" );
  233.                                 }
  234.                                 ontheflypattern = String.Format( "^{0}$", arg.Substring( 3 ) );
  235.                                 ontheflyregexset = true;
  236.                                 break;
  237.                             case "/H:":
  238.                                 if ( heightset )
  239.                                 {
  240.                                     return ShowHelp( "Duplicate command line switch /H" );
  241.                                 }
  242.                                 try
  243.                                 {
  244.                                     height = Convert.ToInt32( arg.Substring( 3 ) );
  245.                                     if ( height < defheight || height > Screen.PrimaryScreen.Bounds.Height )
  246.                                     {
  247.                                         return ShowHelp( "Invalid screen height: \"{0}\"\n\tHeight must be an integer between {1} and {2} (screen height)", arg.Substring( 3 ), defheight.ToString( ), Screen.PrimaryScreen.Bounds.Height.ToString( ) );
  248.                                     }
  249.                                     heightset = true;
  250.                                 }
  251.                                 catch ( FormatException e )
  252.                                 {
  253.                                     return ShowHelp( "Invalid height: \"{0}\"\n\t{1}", arg.Substring( 3 ), e.Message );
  254.                                 }
  255.                                 break;
  256.                             case "/L:":
  257.                                 if ( localizedcaptionset )
  258.                                 {
  259.                                     return ShowHelp( "Duplicate command line switch /L" );
  260.                                 }
  261.                                 localizedcaptionset = true;
  262.                                 localizationstring = arg.Substring( 3 );
  263.                                 break;
  264.                             case "/M:":
  265.                                 if ( usemask )
  266.                                 {
  267.                                     return ShowHelp( "Duplicate command line switch /M" );
  268.                                 }
  269.                                 mask = arg.Substring( 3 ).Trim( "\"".ToCharArray( ) );
  270.                                 if ( String.IsNullOrWhiteSpace( mask ) )
  271.                                 {
  272.                                     ShowHelp( "No mask specified with /M" );
  273.                                     Console.WriteLine( "\n\n" );
  274.                                     return HelpMessage( "mask" );
  275.                                 }
  276.                                 usemask = true;
  277.                                 break;
  278.                             case "/R:":
  279.                                 if ( regexset )
  280.                                 {
  281.                                     return ShowHelp( "Duplicate command line switch /R" );
  282.                                 }
  283.                                 regexpattern = arg.Substring( 3 );
  284.                                 regexset = true;
  285.                                 break;
  286.                             case "/S:":
  287.                                 if ( showpassword )
  288.                                 {
  289.                                     return ShowHelp( "Duplicate command line switch /S" );
  290.                                 }
  291.                                 showpassword = true;
  292.                                 showpasswordprompt = arg.Substring( 3 );
  293.                                 break;
  294.                             case "/T:":
  295.                                 if ( timeoutset )
  296.                                 {
  297.                                     return ShowHelp( "Duplicate command line switch /T" );
  298.                                 }
  299.                                 try
  300.                                 {
  301.                                     timeout = Convert.ToInt32( arg.Substring( 3 ) ) * 1000;
  302.                                     if ( timeout < 1000 )
  303.                                     {
  304.                                         return ShowHelp( "Invalid timeout: \"{0}\"\n\tTimeout value must be a positive integer, at least 1.", arg.Substring( 3 ) );
  305.                                     }
  306.                                     timeoutset = true;
  307.                                 }
  308.                                 catch ( FormatException e )
  309.                                 {
  310.                                     return ShowHelp( "Invalid timeout: \"{0}\"\n\t{1}", arg.Substring( 3 ), e.Message );
  311.                                 }
  312.                                 break;
  313.                             case "/W:":
  314.                                 if ( widthset )
  315.                                 {
  316.                                     return ShowHelp( "Duplicate command line switch /W" );
  317.                                 }
  318.                                 try
  319.                                 {
  320.                                     width = Convert.ToInt32( arg.Substring( 3 ) );
  321.                                     if ( width < defwidth || width > Screen.PrimaryScreen.Bounds.Width )
  322.                                     {
  323.                                         return ShowHelp( "Invalid screen width: \"{0}\"\n\tWidth must be an integer between {1} and {2} (screen width)", arg.Substring( 3 ), defwidth.ToString( ), Screen.PrimaryScreen.Bounds.Width.ToString( ) );
  324.                                     }
  325.                                     widthset = true;
  326.                                 }
  327.                                 catch ( FormatException e )
  328.                                 {
  329.                                     return ShowHelp( "Invalid width: \"{0}\"\n\t{1}", arg.Substring( 3 ), e.Message );
  330.                                 }
  331.                                 break;
  332.                             default:
  333.                                 return ShowHelp( "Invalid command line switch \"{0}\"", arg );
  334.                         }
  335.                     }
  336.                     else
  337.                     {
  338.                         return ShowHelp( "Invalid command line argument \"{0}\"", arg );
  339.                     }
  340.                 }
  341.                 else
  342.                 {
  343.                     if ( String.IsNullOrWhiteSpace( text ) )
  344.                     {
  345.                         text = arg;
  346.                     }
  347.                     else if ( String.IsNullOrWhiteSpace( title ) )
  348.                     {
  349.                         title = arg;
  350.                     }
  351.                     else if ( String.IsNullOrWhiteSpace( defanswer ) )
  352.                     {
  353.                         defanswer = arg;
  354.                     }
  355.                     else
  356.                     {
  357.                         return ShowHelp( "Invalid command line argument \"{0}\"", arg );
  358.                     }
  359.                 }
  360.             }
  361.  
  362.             // Default title if none specified
  363.             if ( String.IsNullOrWhiteSpace( title ) )
  364.             {
  365.                 title = defaulttitle;
  366.             }
  367.  
  368.             // Switch /A requires /M
  369.             if ( asciionly && !usemask )
  370.             {
  371.                 return ShowHelp( "Command line switch /A (ASCII only) can only be used together with /M" );
  372.             }
  373.  
  374.             // Switch /S implies /P
  375.             if ( showpassword )
  376.             {
  377.                 password = true;
  378.             }
  379.  
  380.             // Set timer if /T:timeout was specified
  381.             if ( timeoutset )
  382.             {
  383.                 System.Timers.Timer timer = new System.Timers.Timer( );
  384.                 timer.Elapsed += new ElapsedEventHandler( Timer_Elapsed );
  385.                 timer.Interval = timeout;
  386.                 timer.Start( );
  387.             }
  388.  
  389.             // For /S (Show password checkbox) add 25 px to window height unless height is specified
  390.             if ( showpassword && !heightset )
  391.             {
  392.                 height += 25;
  393.             }
  394.  
  395.             #endregion Command Line Parsing
  396.  
  397.  
  398.             #region Set Localized Captions
  399.  
  400.             if ( localizedcaptionset )
  401.             {
  402.                 cancelcaption = Load( "user32.dll", 801, cancelcaption );
  403.                 okcaption = Load( "user32.dll", 800, okcaption );
  404.                 if ( !String.IsNullOrWhiteSpace( localizationstring ) )
  405.                 {
  406.                     string pattern = @"^((OK|Cancel)=[^;\""]*;)*((OK|Cancel)=[^;\""]*);?$";
  407.                     Regex regex = new Regex( pattern, RegexOptions.IgnoreCase );
  408.                     if ( regex.IsMatch( localizationstring ) )
  409.                     {
  410.                         string[] locstrings = localizationstring.Split( ";".ToCharArray( ) );
  411.                         foreach ( string locstring in locstrings )
  412.                         {
  413.                             string key = locstring.Substring( 0, locstring.IndexOf( '=' ) );
  414.                             string val = locstring.Substring( Math.Min( locstring.IndexOf( '=' ) + 1, locstring.Length - 1 ) );
  415.                             if ( !String.IsNullOrWhiteSpace( val ) )
  416.                             {
  417.                                 switch ( key.ToUpper( ) )
  418.                                 {
  419.                                     case "OK":
  420.                                         okcaption = val;
  421.                                         break;
  422.                                     case "CANCEL":
  423.                                         cancelcaption = val;
  424.                                         break;
  425.                                     default:
  426.                                         return ShowHelp( "Invalid localization key \"{0}\"", key );
  427.                                 }
  428.                             }
  429.                         }
  430.                     }
  431.                     else
  432.                     {
  433.                         return ShowHelp( "Invalid localization string:\n\t{0}", localizationstring );
  434.                     }
  435.                 }
  436.             }
  437.  
  438.             #endregion Set Localized Captions
  439.  
  440.  
  441.             #region Define Form
  442.  
  443.             Size size = new Size( width, height );
  444.             Form inputBox = new Form
  445.             {
  446.                 FormBorderStyle = FormBorderStyle.FixedDialog,
  447.                 MaximizeBox = false,
  448.                 MinimizeBox = false,
  449.                 StartPosition = FormStartPosition.CenterParent,
  450.                 ClientSize = size,
  451.                 Text = title
  452.             };
  453.  
  454.             Label labelPrompt = new Label
  455.             {
  456.                 Size = new Size( width - 20, height - 90 ),
  457.                 Location = new Point( 10, 10 ),
  458.                 Text = text.Replace( "\\n", "\n" )
  459.             };
  460.             inputBox.Controls.Add( labelPrompt );
  461.  
  462.             textbox = new TextBox
  463.             {
  464.                 Size = new Size( width - 20, 25 )
  465.             };
  466.             if ( showpassword )
  467.             {
  468.                 textbox.Location = new Point( 10, height - 100 );
  469.             }
  470.             else
  471.             {
  472.                 textbox.Location = new Point( 10, height - 75 );
  473.             }
  474.             if ( password )
  475.             {
  476.                 textbox.PasswordChar = '*';
  477.                 if ( showpassword )
  478.                 {
  479.                     // Insert a checkbox with label "Show password" 25 px below the textbox
  480.                     CheckBox checkbox = new CheckBox
  481.                     {
  482.                         Checked = false,
  483.                         Location = new Point( 11, textbox.Location.Y + 25 ),
  484.                         Width = inputBox.Width - 22
  485.                     };
  486.                     checkbox.Click += new EventHandler( Checkbox_Click );
  487.                     checkbox.Text = showpasswordprompt;
  488.                     inputBox.Controls.Add( checkbox );
  489.                 }
  490.             }
  491.             else
  492.             {
  493.                 textbox.Text = defanswer;
  494.             }
  495.  
  496.             maskedtextbox = new MaskedTextBox
  497.             {
  498.                 Mask = mask,
  499.                 Location = textbox.Location,
  500.                 PasswordChar = textbox.PasswordChar,
  501.                 Text = textbox.Text,
  502.                 TextMaskFormat = MaskFormat.ExcludePromptAndLiterals, // return only the raw input
  503.                 Size = textbox.Size,
  504.                 AsciiOnly = asciionly
  505.             };
  506.  
  507.             if ( usemask )
  508.             {
  509.                 maskedtextbox.KeyUp += new KeyEventHandler( Maskedtextbox_KeyUp );
  510.                 inputBox.Controls.Add( maskedtextbox );
  511.             }
  512.             else
  513.             {
  514.                 textbox.KeyUp += new KeyEventHandler( Textbox_KeyUp );
  515.                 inputBox.Controls.Add( textbox );
  516.             }
  517.  
  518.             Button okButton = new Button
  519.             {
  520.                 DialogResult = DialogResult.OK,
  521.                 Name = "okButton",
  522.                 Size = new Size( 80, 25 ),
  523.                 Text = okcaption,
  524.                 Location = new Point( width / 2 - 10 - 80, height - 40 )
  525.             };
  526.             inputBox.Controls.Add( okButton );
  527.  
  528.             Button cancelButton = new Button
  529.             {
  530.                 DialogResult = DialogResult.Cancel,
  531.                 Name = "cancelButton",
  532.                 Size = new Size( 80, 25 ),
  533.                 Text = cancelcaption,
  534.                 Location = new Point( width / 2 + 10, height - 40 )
  535.             };
  536.             inputBox.Controls.Add( cancelButton );
  537.  
  538.             inputBox.AcceptButton = okButton;  // OK on Enter
  539.             inputBox.CancelButton = cancelButton; // Cancel on Esc
  540.             inputBox.Activate( );
  541.             inputBox.BringToFront( );
  542.             inputBox.Focus( );
  543.  
  544.             if ( usemask )
  545.             {
  546.                 maskedtextbox.BringToFront( ); // Bug workaround
  547.                 maskedtextbox.Select( 0, 0 ); // Move cursor to begin
  548.                 maskedtextbox.Focus( );
  549.             }
  550.             else
  551.             {
  552.                 textbox.BringToFront( ); // Bug workaround
  553.                 textbox.Select( 0, 0 ); // Move cursor to begin
  554.                 textbox.Focus( );
  555.             }
  556.  
  557.             #endregion Define Form
  558.  
  559.  
  560.             #region Show Dialog and Return Result
  561.  
  562.             DialogResult result = inputBox.ShowDialog( );
  563.             if ( result == DialogResult.OK )
  564.             {
  565.                 int rc = ValidateAndShowResult( );
  566.                 return rc;
  567.             }
  568.             else
  569.             {
  570.                 if ( timeoutelapsed )
  571.                 {
  572.                     ValidateAndShowResult( );
  573.                     return 3;
  574.                 }
  575.                 else
  576.                 {
  577.                     return 2;
  578.                 }
  579.             }
  580.  
  581.             #endregion Show Dialog and Return Result
  582.         }
  583.  
  584.  
  585.         #region Event Handlers
  586.  
  587.         public static void Checkbox_Click( object sender, System.EventArgs e )
  588.         {
  589.             // Toggle between hidden and normal text
  590.             if ( usemask )
  591.             {
  592.                 if ( maskedtextbox.PasswordChar == '*' )
  593.                 {
  594.                     maskedtextbox.PasswordChar = '\0';
  595.                 }
  596.                 else
  597.                 {
  598.                     maskedtextbox.PasswordChar = '*';
  599.                 }
  600.             }
  601.             else
  602.             {
  603.                 if ( textbox.PasswordChar == '*' )
  604.                 {
  605.                     textbox.PasswordChar = '\0';
  606.                 }
  607.                 else
  608.                 {
  609.                     textbox.PasswordChar = '*';
  610.                 }
  611.             }
  612.         }
  613.  
  614.  
  615.         private static void Maskedtextbox_KeyUp( object sender, KeyEventArgs e )
  616.         {
  617.             maskedtextbox.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals;
  618.             currentinput = maskedtextbox.Text;
  619.             if ( Regex.IsMatch( currentinput, ontheflypattern, casesensitivity ) )
  620.             {
  621.                 previousinput = currentinput;
  622.             }
  623.             else
  624.             {
  625.                 currentinput = previousinput;
  626.             }
  627.             if ( maskedtextbox.Text != currentinput )
  628.             {
  629.                 maskedtextbox.Text = currentinput;
  630.                 maskedtextbox.TextMaskFormat = MaskFormat.IncludeLiterals;
  631.                 if ( currentinput.Length > 0 )
  632.                 {
  633.                     maskedtextbox.SelectionStart = maskedtextbox.Text.LastIndexOf( currentinput.Last<char>( ) ) + 1;
  634.                 }
  635.                 else
  636.                 {
  637.                     maskedtextbox.SelectionStart = 0;
  638.                 }
  639.                 maskedtextbox.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals;
  640.             }
  641.         }
  642.  
  643.  
  644.         private static void Textbox_KeyUp( object sender, KeyEventArgs e )
  645.         {
  646.             currentinput = textbox.Text;
  647.             if ( Regex.IsMatch( currentinput, ontheflypattern, casesensitivity ) )
  648.             {
  649.                 previousinput = currentinput;
  650.             }
  651.             else
  652.             {
  653.                 currentinput = previousinput;
  654.             }
  655.             if ( textbox.Text != currentinput )
  656.             {
  657.                 textbox.Text = currentinput;
  658.                 textbox.SelectionStart = currentinput.Length;
  659.             }
  660.         }
  661.  
  662.  
  663.         public static void Timer_Elapsed( object sender, System.EventArgs e )
  664.         {
  665.             timeoutelapsed = true;
  666.             Process.GetCurrentProcess( ).CloseMainWindow( );
  667.         }
  668.  
  669.         #endregion Event Handlers
  670.  
  671.  
  672.         public static int HelpMessage( string subject )
  673.         {
  674.             switch ( subject.ToLower( ) )
  675.             {
  676.                 case "mask":
  677.                     string message = "The mask \"language\" is based on the Masked Edit control in Visual Basic 6.0:\n";
  678.                     message+= "http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask.aspx#remarksToggle\n\n";
  679.                     message += "Masking element     \tDescription\n";
  680.                     message += "===========     \t========\n";
  681.                     message += "0                                  \tDigit, required. This element will accept\n";
  682.                     message+=  "                                   \tany single digit between 0 and 9.\n";
  683.                     message += "9                                  \tDigit or space, optional.\n";
  684.                     message += "#                                  \tDigit or space, optional. If this position\n";
  685.                     message += "                                   \tis blank in the mask, it will be rendered\n";
  686.                     message += "                                   \tas a space in the Text property. Plus (+)\n";
  687.                     message += "                                   \tand minus (-) signs are allowed.\n";
  688.                     message += "L                                  \tLetter, required. Restricts input to the\n";
  689.                     message += "                                   \tASCII letters a-z and A-Z. This mask\n";
  690.                     message += "                                   \telement is equivalent to [a-zA-Z] in\n";
  691.                     message += "                                   \tregular expressions.\n";
  692.                     message += "?                                  \tLetter, optional. Restricts input to the\n";
  693.                     message += "                                   \tASCII letters a-z and A-Z. This mask\n";
  694.                     message += "                                   \telement is equivalent to [a-zA-Z]? in\n";
  695.                     message += "                                   \tregular expressions.\n";
  696.                     message += "&                                  \tCharacter, required. Any non-control\n";
  697.                     message += "                                   \tcharacter. If ASCII only is set (/A),\n";
  698.                     message += "                                   \tthis element behaves like the \"A\" element.\n";
  699.                     message += "C                                  \tCharacter, optional. Any non-control\n";
  700.                     message += "                                   \tcharacter. If ASCII only is set (/A),\n";
  701.                     message += "                                   \tthis element behaves like the \"a\" element.\n";
  702.                     message += "A                                  \tAlphanumeric, required. If ASCII only is\n";
  703.                     message += "                                   \tset (/A), the only characters it will\n";
  704.                     message += "                                   \taccept are the ASCII letters a-z and\n";
  705.                     message += "                                   \tA-Z and numbers. This mask element\n";
  706.                     message += "                                   \tbehaves like the \"&\" element.\n";
  707.                     message += "a                                  \tAlphanumeric, optional. If ASCII only is\n";
  708.                     message += "                                   \tset (/A), the only characters it will\n";
  709.                     message += "                                   \taccept are the ASCII letters a-z and\n";
  710.                     message += "                                   \tA-Z and numbers. This mask element\n";
  711.                     message += "                                   \tbehaves like the \"C\" element.\n";
  712.                     message += ".                                  \tDecimal placeholder.\n";
  713.                     message += ",                                  \tThousands placeholder.\n";
  714.                     message += ":                                  \tTime separator.\n";
  715.                     message += "/                                  \tDate separator.\n";
  716.                     message += "$                                  \tCurrency symbol.\n";
  717.                     message += "<                                  \tShift down. Converts all characters\n";
  718.                     message += "                                   \tthat follow to lowercase.\n";
  719.                     message += ">                                  \tShift up. Converts all characters\n";
  720.                     message += "                                   \tthat follow to uppercase.\n";
  721.                     message += "|                                  \tDisable a previous shift up or shift down.\n";
  722.                     message += "\\                                  \tEscape. Escapes a mask character, turning\n";
  723.                     message += "                                   \tit into a literal. \"\\\\\" is the escape sequence\n";
  724.                     message += "                                   \tfor a backslash.\n";
  725.                     message += "All other characters\tLiterals. All non-mask elements will appear\n";
  726.                     message += "                                   \tas themselves within MaskedTextBox.\n";
  727.                     message += "                                   \tLiterals always occupy a static position\n";
  728.                     message += "                                   \tin the mask at run time, and cannot be\n";
  729.                     message += "                                   \tmoved or deleted by the user.\n";
  730.                     MessageBox.Show( message, "Help for command line switch /M:mask" );
  731.                     break;
  732.                 default:
  733.                     return ShowHelp( );
  734.             }
  735.             return 1;
  736.         }
  737.  
  738.  
  739.         public static int ShowHelp( params string[] errmsg )
  740.         {
  741.             /*
  742. 			InputBoxWF,  Version 1.00
  743. 			Prompt for input (Windows Form edition)
  744.  
  745. 			Usage:   INPUTBOXWF  [ "prompt"  [ "title"  [ "default" ] ] ] [ options ]
  746.  
  747. 			Where:   "prompt"    is the text above the input field (use \n for new line)
  748. 			         "title"     is the caption in the title bar
  749. 			         "default"   is the default answer shown in the input field
  750.  
  751. 			Options: /A          accepts ASCII characters only (requires /M)
  752. 			         /C          send input to Clipboard (default: send to file)
  753. 			         /E[:file]   send input to filE (default file name: InputBoxWF.tmp)
  754. 			         /F:regex    use regex to filter input on-the-Fly (see Notes)
  755. 			         /H:height   sets the Height of the input box
  756. 			                     (default: 110; minimum: 110; maximum: screen height)
  757. 			         /I          regular expressions are case Insensitive
  758. 			                     (default: regular expressions are case sensitive)
  759. 			         /L[:string] use Localized or custom captions (see Notes)
  760. 			         /M:mask     accept input only if it matches mask (template)
  761. 			         /N          Not filtered, only doublequotes are removed from input
  762. 			                     (default: remove & < > | ")
  763. 			         /P          hides (masks) the input text (for Passwords)
  764. 			         /R:regex    accept input only if it matches Regular expression regex
  765. 			         /S[:text]   inserts a checkbox "Show password" (or specified text)
  766. 			         /T[:sec]    sets the optional Timeout in seconds (default: 60)
  767. 			         /U          return Unmasked input, without literals (requires /M)
  768. 			                     (default: include literals in result)
  769. 			         /W:width    sets the Width of the input box
  770. 			                     (default: 200; minimum: 200; maximum: screen width)
  771.  
  772. 			Example: prompt for password
  773. 			InputBox.exe "Enter your password:" "Login" /S
  774.  
  775. 			Example: fixed length hexadecimal input (enter as a single command line)
  776. 			InputBox.exe "Enter a MAC address:" "MAC Address" "0022446688AACCEE"
  777. 			             /M:">CC\:CC\:CC\:CC\:CC\:CC" /R:"[\dA-F]{16}"
  778. 			             /F:"[\dA-F]{1,16}" /U /I
  779.  
  780. 			Notes:   For hidden input (/P and/or /S), "default" will be ignored.
  781. 			         With /F, regex must test the unmasked input (without literals), e.g.
  782. 			         /M:"CC:CC:CC:CC:CC:CC:CC:CC" /F:"[\dA-F]{0,16} /I" for MAC address.
  783. 			         With /R, regex is used to test input after OK is clicked;
  784. 			         with /F, regex is used to test input each time the input
  785. 			         changes, so regex must be able to cope with partial input;
  786. 			         e.g. /F:"[\dA-F]{0,16}" is OK, but /F:"[\dA-F]{16}" will fail.
  787. 			         or redirect the result to a (temporary) file.
  788. 			         Show password (/S) implies hiding the input text (/P).
  789. 			         Use /M (without mask) to show detailed help on the mask language.
  790. 			         Use /L for Localized "OK" and "Cancel" button captions.
  791. 			         Custom captions require a string like /L:"OK=caption;Cancel=caption"
  792. 			         (button=caption pairs separated by semicolons, each button optional).
  793. 			         Text from input is written to clipboard or file only if "OK" is clicked.
  794. 			         Return code is 0 for "OK", 1 for (command line) errors, 2 for
  795. 			         "Cancel", 3 on timeout, 4 if no regex or mask match.
  796.  
  797. 			Credits: On-the-fly form based on code by Gorkem Gencay on StackOverflow:
  798. 			         http://stackoverflow.com/questions/97097#17546909
  799. 			         Code to retrieve localized button captions by Martin Stoeckli:
  800. 			         http://martinstoeckli.ch/csharp/csharp.html#windows_text_resources
  801.  
  802. 			Written by Rob van der Woude
  803. 			http://www.robvanderwoude.com
  804. 			*/
  805.  
  806.             string message = "\n";
  807.  
  808.             if ( errmsg.Length > 0 )
  809.             {
  810.                 List<string> errargs = new List<string>( errmsg );
  811.                 errargs.RemoveAt( 0 );
  812.                 message += string.Format( "ERROR:\t{0} {1}\n", errmsg[0], string.Join( " ", errargs.ToArray( ) ) );
  813.             }
  814.  
  815.             message += string.Format( "InputBoxWF,  Version {0}\n", progver );
  816.             message += "Prompt for input (Windows Form edition)\n\n";
  817.             message += "Usage:\tINPUTBOXWF  [ \"prompt\"  [ \"title\"  [ \"default\" ] ] ] [ options ]\n\n";
  818.             message += "Where:\t\"prompt\"\t\tis the text above the input field\n";
  819.             message += "         \t       \t\t(use \\n for new line)\n";
  820.             message += "         \t\"title\"\t\tis the caption in the title bar\n";
  821.             message += "         \t\"default\"\t\tis the default answer shown in\n";
  822.             message += "          \t      \t\tthe input field\n\n";
  823.             message += "Options:\t/A\t\taccepts ASCII characters only (requires /M)\n";
  824.             message += "         \t/F:regex\t\tFilter input on-the-Fly with regex (see Note)\n";
  825.             message += "         \t/H:height\tsets the Height of the input box\n";
  826.             message += string.Format( "          \t      \t\t(default: {0}; minimum: {0};\n", defheight );
  827.             message += "         \t       \t\tmaximum: screen height)\n";
  828.             message += "         \t/I\t\tregular expressions are case Insensitive\n";
  829.             message += "         \t       \t\t(default: regular expressions are case\n";
  830.             message += "         \t       \t\tsensitive)\n";
  831.             message += "         \t/L[:string]\tLocalized or custom captions (see Note)\n";
  832.             message += "         \t/M:mask\t\taccept input only if it Matches mask\n";
  833.             message += "         \t/N\t\tNot filtered, only doublequotes are\n";
  834.             message += "         \t       \t\tremoved from input\n";
  835.             message += "         \t       \t\t(default: remove & < > | \")\n";
  836.             message += "         \t/R:regex\t\taccept input only if it matches Regular\n";
  837.             message += "         \t       \t\texpression regex\n";
  838.             message += "         \t/S[:text]\t\tinserts a checkbox \"Show password\"\n";
  839.             message += "         \t       \t\t(or specified text)\n";
  840.             message += "         \t/T[:sec]\t\tsets the optional Timeout in seconds\n";
  841.             message += string.Format( "         \t       \t\t( default: {0})\n", deftimeout );
  842.             message += "         \t/U\t\treturn Unmasked input, without literals\n";
  843.             message += "         \t       \t\t(requires /M; default: include literals)\n";
  844.             message += "         \t/W:width\tsets the Width of the input box\n";
  845.             message += string.Format( "         \t       \t\t(default: {0}; minimum: {0};\n", defwidth );
  846.             message += "         \t       \t\tmaximum: screen width)\n\n";
  847.  
  848.             message += "Written by Rob van der Woude\n";
  849.  
  850.             message += "http://www.robvanderwoude.com";
  851.  
  852.             MessageBox.Show( message, "Help for InputBoxWF.exe (part 1)" );
  853.  
  854.             message = "Example:\tprompt for password, send to clipboard\n";
  855.             message += "\tInputBoxWF.exe \"Enter your password:\" \"Login\" /S /C\n\n";
  856.  
  857.             message += "Example:\tfixed length hex input (enter as a single command line)\n";
  858.             message += "\tInputBoxWF.exe \"Enter a MAC address:\" \"MAC Address\"\n";
  859.             message += "\t\"0022446688AACCEE\" /M:\">CC\\:CC\\:CC\\:CC\\:CC\\:CC\\:CC\\:CC\"\n";
  860.             message += "\t/R:\"[\\dA-F]{16}\" /F:\"[\\dA-F]{0,16}\" /U /I /C\n\n";
  861.  
  862.             message += "Notes:\tFor hidden input (/P and/or /S), \"default\" will be ignored.\n\n";
  863.  
  864.             message += "       \tWith /F, regex must test the unmasked input (without literals),\n";
  865.             message += "       \te.g. /M:\"CC:CC:CC:CC:CC:CC:CC:CC\" /F:\"[\\dA-F]{0,16}\" /I\n";
  866.             message += "       \tfor MAC address.\n\n";
  867.  
  868.             message += "        \tWith /R, regex is used to test input after OK is clicked;\n";
  869.             message += "        \twith /F, regex is used to test input each time the input\n";
  870.             message += "        \tchanges, so  regex must be able to cope with partial input;\n";
  871.             message += "        \te.g. /F:\"[\\dA-F]{0,16}\" is OK, but /F:\"[\\dA-F]{16}\" will fail.\n\n";
  872.  
  873.             message += "        \tBe careful with /N, use doublequotes for the result.\n\n";
  874.  
  875.             message += "        \tShow password (/S) implies hiding the input text (/P).\n\n";
  876.  
  877.             message += "        \tUse /M (without mask value) to show detailed help on\n";
  878.             message += "        \tthe mask language.\n\n";
  879.  
  880.             message += "        \tUse /L for Localized \"OK\" and \"Cancel\" button captions.\n";
  881.  
  882.             message += "        \tCustom captions require a string like\n";
  883.             message += "        \t / L:\"OK=caption;Cancel=caption\"\n";
  884.             message += "        \t(button=caption pairs separated by semicolons,\n";
  885.             message += "        \teach button optional).\n\n";
  886.  
  887.             message += "        \tText from input is written to clipboard or file\n";
  888.             message += "        \tonly if \"OK\" is clicked.\n\n";
  889.  
  890.             message += "        \tReturn code is 0 for \"OK\", 1 for (command line) errors,\n";
  891.             message += "        \t2 for \"Cancel\", 3 on timeout, 4 if no regex or mask match.\n\n";
  892.  
  893.             message += "Written by Rob van der Woude\n";
  894.  
  895.             message += "http://www.robvanderwoude.com";
  896.  
  897.             MessageBox.Show( message, "Help for InputBoxWF.exe (part 2)" );
  898.  
  899.             return 1;
  900.         }
  901.  
  902.  
  903.         public static int ValidateAndShowResult()
  904.         {
  905.             string input = String.Empty;
  906.             // Read input from MaskedTextBox or TextBox
  907.             if ( usemask )
  908.             {
  909.                 if ( returnunmasked )
  910.                 {
  911.                     maskedtextbox.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals;
  912.                 }
  913.                 else
  914.                 {
  915.                     maskedtextbox.TextMaskFormat = MaskFormat.IncludeLiterals;
  916.                 }
  917.                 input = maskedtextbox.Text;
  918.                 // Check if input complies with mask
  919.                 if ( !maskedtextbox.MaskCompleted )
  920.                 {
  921.                     return 4;
  922.                 }
  923.             }
  924.             else
  925.             {
  926.                 input = textbox.Text;
  927.             }
  928.  
  929.             // Check if input complies with regex
  930.             if ( regexset && Regex.IsMatch( input, regexpattern, casesensitivity ) )
  931.             {
  932.                 return 4;
  933.             }
  934.  
  935.             // Remove ampersands and redirection symbols unless /N switch was used
  936.             if ( filtered )
  937.             {
  938.                 input = Regex.Replace( input, @"[&<>|]", String.Empty );
  939.             }
  940.  
  941.             // Remove doublequotes from output
  942.             input = input.Replace( "\"", "" );
  943.  
  944.             // Send result to clipboard or file
  945.             if ( sendoutputtoclipboard )
  946.             {
  947.                 Clipboard.SetText( input );
  948.             }
  949.             else
  950.             {
  951.                 using ( StreamWriter sw = new StreamWriter( outputfile, false ) )
  952.                 {
  953.                     sw.Write( input );
  954.                 }
  955.             }
  956.             return 0;
  957.         }
  958.  
  959.  
  960.         #region Get Localized Captions
  961.  
  962.         // Code to retrieve localized captions by Martin Stoeckli
  963.         // http://martinstoeckli.ch/csharp/csharp.html#windows_text_resources
  964.  
  965.         /// <summary>
  966.         /// Searches for a text resource in a Windows library.
  967.         /// Sometimes, using the existing Windows resources, you can make your code
  968.         /// language independent and you don't have to care about translation problems.
  969.         /// </summary>
  970.         /// <example>
  971.         ///   btnCancel.Text = Load("user32.dll", 801, "Cancel");
  972.         ///   btnYes.Text = Load("user32.dll", 805, "Yes");
  973.         /// </example>
  974.         /// <param name="libraryName">Name of the windows library like "user32.dll"
  975.         /// or "shell32.dll"</param>
  976.         /// <param name="ident">Id of the string resource.</param>
  977.         /// <param name="defaultText">Return this text, if the resource string could
  978.         /// not be found.</param>
  979.         /// <returns>Requested string if the resource was found,
  980.         /// otherwise the <paramref name="defaultText"/></returns>
  981.         public static string Load( string libraryName, UInt32 ident, string defaultText )
  982.         {
  983.             IntPtr libraryHandle = GetModuleHandle( libraryName );
  984.             if ( libraryHandle != IntPtr.Zero )
  985.             {
  986.                 StringBuilder sb = new StringBuilder( 1024 );
  987.                 int size = LoadString( libraryHandle, ident, sb, 1024 );
  988.                 if ( size > 0 )
  989.                     return sb.ToString( );
  990.             }
  991.             return defaultText;
  992.         }
  993.  
  994.         [DllImport( "kernel32.dll", CharSet = CharSet.Auto )]
  995.         private static extern IntPtr GetModuleHandle( string lpModuleName );
  996.  
  997.         [DllImport( "user32.dll", CharSet = CharSet.Auto )]
  998.         private static extern int LoadString( IntPtr hInstance, UInt32 uID, StringBuilder lpBuffer, Int32 nBufferMax );
  999.  
  1000.         #endregion Get Localized Captions
  1001.     }
  1002.  
  1003. }
  1004.  

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