Sign in to follow this  
Followers 0
wraithdu

_ConsoleGetInput

5 posts in this topic

#1 ·  Posted (edited)

So I found myself needing this UDF again and made a few updates. I think a few people, especially those with other Console UDFs, may also find it useful. Function headers should be pretty self explanatory.

#include-once

; #FUNCTION# ====================================================================================================
; Name...........:  _ConsoleGetInput
; Description....:  Get user input from the console
; Syntax.........:  _ConsoleGetInput([$sPrompt = ""[, $iLen = 0[, $autoReturn = False[, $validateEach = ""[, $validateFinal = ""[, $hideInput = False[, $maskChar = ""]]]]]]])
; Parameters.....:  $sPrompt        - [Optional] Prompt text to display before input
;                   $iLen           - [Optional] Maximum length of input
;                   $autoReturn     - [Optional] Automatically return when $iLen is reached
;                   $validateEach   - [Optional] Regular expression to validate each character as it is input
;                   $validateFinal  - [Optional] Regular expression to validate the final input
;                   $hideInput      - [Optional] Do no print input characters
;                   $maskChar       - [Optional] If $hideInput is true, the character to print instead of input
;
; Return values..:  Success - Input string
;                   Failure - Empty string
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _ConsoleGetInput($sPrompt = "", $iLen = 0, $autoReturn = False, $validateEach = "", $validateFinal = "", $hideInput = False, $maskChar = "")
    $iLen = Abs($iLen)
    $maskChar = StringLeft($maskChar, 1)
    If $sPrompt <> "" Then ConsoleWrite($sPrompt)
    Local $sChars = "", $sIn, $aErase[3] = [ChrW(8), " ", ChrW(8)]
    While True
        $sIn = DllCall("msvcrt.dll", "int:cdecl", "_getwch")
        If $sIn[0] < 32 Then
            ; control characters
            Switch $sIn[0]
                Case 13 ; ENTER
                    ; validate if no length or length not reached
                    ; otherwise validation was performed upon input
                    If ($validateFinal <> "") And ((Not $iLen) Or (StringLen($sChars) < $iLen)) Then
                        If Not StringRegExp($sChars, $validateFinal, 0) Then
                            ; failed validation
                            ; erase entire input
                            If Not $hideInput Or ($hideInput And ($maskChar <> "")) Then
                                For $i = 0 To 2
                                    For $j = 1 To StringLen($sChars)
                                        ConsoleWrite($aErase[$i])
                                    Next
                                Next
                            EndIf
                            $sChars = ""
                            ContinueLoop
                        EndIf
                    EndIf
                    ; no validation or passed validation
                    ExitLoop
                Case 8 ; BACKSPACE
                    If $sChars <> "" Then
                        If Not $hideInput Or ($hideInput And ($maskChar <> "")) Then ConsoleWrite(ChrW(8) & " " & ChrW(8))
                        $sChars = StringTrimRight($sChars, 1)
                    EndIf
                Case 27 ; ESCAPE
                    Return ""
            EndSwitch
        Else
            ; printable characters
            ; length reached, do nothing
            If $iLen And (StringLen($sChars) >= $iLen) Then ContinueLoop
            ; get character
            $sIn = ChrW($sIn[0])
            ; validate each character?
            If ($validateEach <> "") And (Not StringRegExp($sIn, $validateEach, 0)) Then ContinueLoop
            $sChars &= $sIn
            ; always validate when length reached
            If ($validateFinal <> "") And $iLen And (StringLen($sChars) >= $iLen) Then
                If Not StringRegExp($sChars, $validateFinal, 0) Then
                    ; failed validation
                    ; erase last char input, do not print
                    $sChars = StringTrimRight($sChars, 1)
                    ContinueLoop
                EndIf
            EndIf
            ; no validation or passed validation or no length or length not reached
            ; print character?
            If Not $hideInput Then
                ConsoleWrite($sIn)
            ElseIf $hideInput And ($maskChar <> "") Then
                ConsoleWrite($maskChar)
            EndIf
            ; autoReturn?
            If $autoReturn And $iLen And (StringLen($sChars) >= $iLen) Then ExitLoop
        EndIf
    WEnd
    Return $sChars
EndFunc   ;==>_ConsoleGetInput

; #FUNCTION# ====================================================================================================
; Name...........:  _ConsolePause
; Description....:  Pause and wait for any input
; Syntax.........:  _ConsolePause([$sPrompt = "Press any key to continue . . . "])
; Parameters.....:  $sPrompt - [Optional] Prompt text to display
;
; Return values..:  Success - Input string
;                   Failure - Empty string
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _ConsolePause($sPrompt = "Press any key to continue . . . ")
    Return _ConsoleGetInput($sPrompt, 1, True, "", "", True)
EndFunc

; #FUNCTION# ====================================================================================================
; Name...........:  _ConsoleRun
; Description....:  Run a command in the console window
; Syntax.........:  _ConsoleRun($sCmd[, $fWait = True[, $fNew = False[, $iShow = Default]]])
; Parameters.....:  $sCmd   - Command to run
;                   $fWait  - [Optional] Wait for command to finish
;                   $fNew   - [Optional] Run in new console window
;                   $iShow  - [Optional] Show flag (default for Run(Wait) is @SW_HIDE)
;
; Return values..:  Success - See Run(Wait) functions
;                   Failure - See Run(Wait) functions
; Author.........:  Erik Pilsits
; Modified.......:
; Remarks........:
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================
Func _ConsoleRun($sCmd, $fWait = True, $fNew = False, $iShow = Default)
    Local $iFlag = 0x10
    If $fNew Then $iFlag = 0x10000
    If $fWait Then
        Return RunWait($sCmd, "", $iShow, $iFlag)
    Else
        Return Run($sCmd, "", $iShow, $iFlag)
    EndIf
EndFunc

Here's a quick example (must be compiled through Scite as a console app):

#AutoIt3Wrapper_Change2CUI=y

#include <_ConsoleGetInput.au3>

Global $name = _ConsoleGetInput("Type your name: ")
ConsoleWrite(@CRLF)
Global $pass = _ConsoleGetInput("Now something secret: ", 0, False, "", "", True, "*")
ConsoleWrite(@CRLF & @CRLF)
Global $inp = _ConsoleGetInput("Do you want to print your input? [y/n] ", 1, True, "(?i)[yn]")
ConsoleWrite(@CRLF)
If $inp = "y" Then
    ConsoleWrite("Your name: " & $name & @CRLF)
    ConsoleWrite("Your secret (not really): " & $pass & @CRLF)
EndIf
ConsoleWrite(@CRLF)
_ConsolePause("Press something to quit...")
Edited by wraithdu

Share this post


Link to post
Share on other sites



mscvrt definitely has a lot of very useful stuff for consoles, and that's a pretty good example. If I had to implement it with the windows API I would probably change the console input more, read characters the same way as you do, and then change the console mode back.

Unfortunately times not on my side at the moment. I really want to get my console UDF finalised with examples so I can release it, but examples take time to write.

Share this post


Link to post
Share on other sites

Yes, they do.

There's nothing wrong with your implementation of console input. I wrote this because I wanted both restricted and validated input, such as a choice to continue where only 'y' or 'n' was allowed, and the option to act on input immediately without having to have the user hit Enter. It's also great for masking or hiding input, such as passwords.

Use case is limited, granted, but specifically functional for my purposes.

Share this post


Link to post
Share on other sites

I really like your Console UDF by the way, it will become my main goto once you release it.

Share this post


Link to post
Share on other sites

I really like your Console UDF by the way, it will become my main goto once you release it.

That last 4 words pretty much sums it up :huh2:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0