Add A Second Question to a Window?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
MikeInThe901
Posts: 6
Joined: 24 Apr 2023 11:13

Add A Second Question to a Window?

#1 Post by MikeInThe901 » 03 Aug 2023 09:36

I have the following code (thx Batcher) in a batch file that accepts keyboard input from a prompt in a window. Is it possible, preferably in the same window, to give the user a second prompt with a drop-down box containing two options for choosing a city name, to become an additional variable? Thanks!

@echo off
>"%temp%\GetInput.vbs" echo WSH.Echo InputBox("What is your name:")
for /f "delims=" %%i in ('cscript "%temp%\GetInput.vbs" //nologo //e:vbscript') do (
set "Var=%%i"
)
echo,%Var%
pause

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Add A Second Question to a Window?

#2 Post by aGerman » 06 Aug 2023 14:04

Seeing a textual interface and a graphical interface together does always give me the shivers. It's like seeing a man walking on the moon. Funny for sure, but at the same time it's getting pretty clear that the moon isn't the right environment for mankind.

This having said - No, there isn't any possibility to change the predefined VBScript InputBox interface in a way that you described. To my knowledge there isn't even a predefined interface for a dropdown box. You have to choose a language that supports the creation of custom interfaces. Although it would be best to use this language for your whole program then.

That said, of course it is also possible to use a Batch script that invokes a PowerShell code that uses the .NET Forms classes to assemble the window and to specify the appearance and behavior of the main window and its children. Furthermore that code has to listens to events, and to write the output to a stream accessible by the Batch code. Doesn't sound like the best plan you ever heard, does it?

However, every now and then writing such a weird piece of code is just fun and a good exercise. And it may give you an idea ... In the code below are certainly enough comments and search terms to make you recognize how it all works together. Good luck!

Steffen

Code: Select all

@echo off &setlocal

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM Save the PowerShell call for the custom dialog in variable `dialog`.
set dialog=powershell.exe -nop -ep Bypass -c ^"^
%=% Add-Type -AssemblyName System.Drawing;^
%=% Add-Type -AssemblyName System.Windows.Forms;^
%= REM `Form` is the .NET class for our dialog window. `Label` is the .NET class for a read-only text area. =% ^
%= REM `TextBox` is the .NET class for an input box. `ComboBox` is the .NET class for a dropdown box. =% ^
%= REM `Button` is the .NET class for a click button. =% ^
%= REM Start from learn.microsoft.com/en-us/dotnet/api/system.windows.forms =% ^
%=% $form=New-Object Windows.Forms.Form;^
%=% $inbox_label=New-Object Windows.Forms.Label;^
%=% $inbox=New-Object Windows.Forms.TextBox;^
%=% $dropdown_label=New-Object Windows.Forms.Label;^
%=% $dropdown=New-Object Windows.Forms.ComboBox;^
%=% $submit=New-Object Windows.Forms.Button;^
%= REM Make the controls children of the dialog window. =% ^
%=% $form.Controls.Add($inbox_label);^
%=% $form.Controls.Add($inbox);^
%=% $form.Controls.Add($dropdown_label);^
%=% $form.Controls.Add($dropdown);^
%=% $form.Controls.Add($submit);^
%= REM Window appearance and behavior. =% ^
%=% $form.AcceptButton=$submit;^
%=% $form.ActiveControl=$inbox;^
%=% $form.Add_Shown({ $form.Activate(); });^
%=% $form.ClientSize='300,180';^
%=% $form.FormBorderStyle='FixedSingle';^
%=% try { $form.Icon=Invoke-Expression \"[Drawing.SystemIcons]::$env:dialog_icon\"; } catch {}^
%=% $form.MaximizeBox=$false;^
%=% $form.MinimizeBox=$false;^
%=% $form.Text=$env:dialog_title;^
%=% $form.Topmost=$true;^
%= REM Input label appearance and behavior. =% ^
%=% $inbox_label.Font='Microsoft Sans Serif,8';^
%=% $inbox_label.Location='20,10';^
%=% $inbox_label.Size='260,25';^
%=% $inbox_label.Text=$env:input_prompt;^
%=% $inbox_label.TextAlign='BottomLeft';^
%= REM Input box appearance and behavior. =% ^
%=% $inbox.Font='Microsoft Sans Serif,10';^
%=% $inbox.Location='20,40';^
%=% $inbox.Width=260;^
%= REM Dropdown label appearance and behavior. =% ^
%=% $dropdown_label.Font='Microsoft Sans Serif,8';^
%=% $dropdown_label.Location='20,75';^
%=% $dropdown_label.Size='260,25';^
%=% $dropdown_label.Text=$env:dropdown_prompt;^
%=% $dropdown_label.TextAlign='BottomLeft';^
%= REM Dropdown box appearance and behavior. =% ^
%=% $dropdown.AutoCompleteMode='SuggestAppend';^
%=% $dropdown.AutoCompleteSource='ListItems';^
%=% $dropdown.Font='Microsoft Sans Serif,10';^
%=% $dropdown.Items.AddRange($env:dropdown_list.Split($env:dropdown_separator));^
%=% $dropdown.Location='20,105';^
%=% $dropdown.Width=260;^
%= REM Submit button appearance and behavior. =% ^
%=% $submit.Add_Click({^
%=== REM Don't accept empty input or text that isn't defined in the dropdown list =% ^
%===% if (-not $inbox.Text) {^
%=====% $inbox.Select();^
%=====% $inbox.Focus();^
%===% } elseif (-not $dropdown.SelectedItem) {^
%=====% $dropdown.Select();^
%=====% $dropdown.Focus();^
%===% } else {^
%===== REM Format lines like <index><separator><data> and write them to the stdout stream. =% ^
%=====% $delim=$(if ($env:response_separator) {$env:response_separator} else {' '});^
%=====% Write-Host ('0',$inbox.Text -join $delim);^
%=====% Write-Host ('1',$dropdown.SelectedItem -join $delim);^
%=====% $form.Close();^
%===% }^
%=% });^
%=% $submit.BackColor='#e0e0e0';^
%=% $submit.Font='Microsoft Sans Serif,10';^
%=% $submit.Location='20,145';^
%=% $submit.Size='260,25';^
%=% $submit.Text='Submit';^
%= REM Create the visible window and bring it up to screen. =% ^
%= REM This method is blocking. I.e., it doesn't return as long as the window is open. =% ^
%=% [void]$form.ShowDialog();^"

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM `dialog_icon`, `dialog_title`, `input_prompt`, `dropdown_prompt`,
REM  `dropdown_separator`, `dropdown_list`, and `response_separator` are the
REM  expected environment variables to control the customization of the dialog.

REM `dialog_icon` specifies the window icon in the title bar
REM Valid values are:
REM  Application (or WinLogo), Error (or Hand), Information (or Asterisk),
REM  Question, Shield, and Warning (or Exclamation)
REM The default Form icon is used if `dialog_icon` is undefined or invalid.
set "dialog_icon=Question"

REM `dialog_title` specifies the text of the title bar
set "dialog_title=Mind providing some information?"

REM `input_prompt` specifies the headline of the input box
set "input_prompt=What's your name?"

REM `dropdown_prompt` specifies the headline of the dropdown box
set "dropdown_prompt=What's your favorite color?"

REM `dropdown_separator` specifies the character used to separate the items in
REM  the `dropdown_items` variable
REM Space is the default separator if `dropdown_separator` is not defined.
:: set "dropdown_separator= "

REM `dropdown_list` specifies the character-separated list of dropdown items
set "dropdown_list=Red Orange Yellow Green Cyan Blue Purple"

REM `response_separator` specifies the character used to separate the data index
REM  from the belonging dialog input
REM Space is the default separator if `response_separator` is not defined.
REM The format of the response lines is <index><response_separator><data>
REM The index of the input box is 0. The index of the dropdown box is 1.
:: set "response_separator= "

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

REM Use a FOR /F loop to execute the PowerShell command line saved in `dialog`
REM  and capture the stdout stream containing the information.
REM In this example we receive two lines:
REM 0<delimiter><name>
REM 1<delimiter><color>
REM We split the line at the first delimiter. Then we check the index in the
REM  first token. If it is `0` the remaining text of the line will be assigned
REM  to variable `name`. If it is `1` the remaining text of the line will be
REM  assigned to variable `col`.
REM The delimiter that PowerShell uses to generate the lines can be defined
REM  upfront by setting the `response_separator` variable appropriately.
set "name="
for /f "tokens=1* delims= " %%i in ('%dialog%') do (
  if %%i equ 0 (set "name=%%j") else set "col=%%j"
)

if defined name (
  echo Hey %name%!
  echo %col% is your favorite color.
) else (
  echo Hey stranger!
  echo You closed the dialog box without submitting valid data.
)

pause

Post Reply