Jump to content

GUI newbie basics


VelvetElvis
 Share

Recommended Posts

I've written a couple dozen scripts for parsing data, FTPing, etc., but none have been GUI-based. I'm trying to write a very basic 2-input box GUI, and am having trouble with some of the workings of GUIs.

Here's the routine:

User scans barcode into first input box. The scanner is appending a CRLF, which will simulate hitting <enter>. String saved to var and focus moves to input 2 where another barcode string is captured. Focus then moves back to the first input for the next set of data.

This is all I have so far:

include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 393, 214, -1, -1)
$Input1 = GUICtrlCreateInput("Input1", 56, 24, 273, 21)
$Input2 = GUICtrlCreateInput("Input2", 56, 73, 273, 21)
$ButtonExit = GUICtrlCreateButton("E&xit", 240, 128, 113, 33)
GUISetState(@SW_SHOW)
#endregion ### END Koda GUI section ###
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $ButtonExit
   Exit
  Case <$Input1 has a String With a CRLF >    ; <-----------
    < store String To variable And Then move focus To Input 2 > <----------------
  Case <$Input2 has a String With a CRLF >   ; <-----------
    < store String To variable, move focus back To $Input1> <--------------------
EndSwitch
WEnd

Could someone give me a nudge with the Input details? There's more to this app, like data validation, writing to an output file, etc., but I think I'll be OK with that part.

Thank you!

Link to comment
Share on other sites

  • Moderators

VelvetElvis,

You do not need to append a @CRLF if the scanner dumps the whole barcode in one go like a paste operation. You just need to look for content of the input changing - like this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Global $sText1 = "", $sText2 = ""

$Form1 = GUICreate("Form1", 393, 214, -1, -1)

$Input1 = GUICtrlCreateInput("Input1", 56, 24, 273, 21)
$Input2 = GUICtrlCreateInput("Input2", 56, 73, 273, 21)
$ButtonExit = GUICtrlCreateButton("E&xit", 240, 128, 113, 33)

GUISetState(@SW_SHOW)

GUICtrlSetState($Input1, $GUI_FOCUS)

GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $ButtonExit ; use multiple arguments here <<<<<<<<<<<<<<<<<<<<<<<<<<<
            Exit
    EndSwitch

    ; Just to show it works
    If $sText1 <> "" And $sText2 <> "" Then
        MsgBox(0, "Done", $sText1 & @CRLF & $sText2)
        $sText1 = ""
        $sText2 = ""
    EndIf

WEnd

Func _WM_COMMAND($hWHnd, $iMsg, $wParam, $lParam)

    ; If it was an update message
    If _WinAPI_HiWord($wParam) = $EN_CHANGE Then
        ; See if it was one of ours
        Switch _WinAPI_LoWord($wParam)
            Case $Input1
                $sText1 = GUICtrlRead($Input1)
                GUICtrlSetState($Input2, $GUI_FOCUS)
            Case $Input2
                $sText2 = GUICtrlRead($Input2)
                GUICtrlSetData($Input1, "")
                GUICtrlSetData($Input2, "")
                GUICtrlSetState($Input1, $GUI_FOCUS)
        EndSwitch

    EndIf

EndFunc   ;==>_WM_COMMAND

If the scanner adds the @CRLF automatically, you will need to use StringTrimRight on the input content to remove it. ;)

Please ask if you have any questions. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks for the reply, Melba23.

Unfortunately, we need the ability to manually enter barcodes, should the scan fail. This is why we program in a CRLF. I think I may have muddied the waters mentioning a scanner. Sorry.

Looking back at my code, I've changed it as follows:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#NoTrayIcon
#region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 393, 214, -1, -1)
$Input1 = GUICtrlCreateInput("", 56, 24, 273, 21)
$Input2 = GUICtrlCreateInput("", 56, 73, 273, 21)
$ButtonExit = GUICtrlCreateButton("E&xit", 240, 128, 113, 33)
GUISetState(@SW_SHOW)
#endregion ### END Koda GUI section ###
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $ButtonExit
   Exit
  Case $Input1
   $scan1 = GUICtrlRead($Input1) ; Read scan to var
   GUICtrlSetState($Input2, $Gui_focus) ; Set focus to 2nd input
  Case $Input2
   $scan2 = GUICtrlRead($Input2) ; Read scan to var
   GUICtrlSetState($Input1, $Gui_focus) ; Return focus to 1st input
EndSwitch
WEnd

If you try this and enter text manually, everything seems fine. Input moves back and forth between the two inputs. However, if the text is left unchanged, and <enter> is pressed, nothing happens. If I re-type the exact same text that's already in the control, then <enter> works as it should. Is there an easy way around this?

EDIT. To simplify this, why does pressing <enter> on an empty field not do anything? It should send it to the next input control, but doesn't.

(I'm using this as a learning tool as well, so the sparser the code, the better.) :)

Edited by VelvetElvis
Link to comment
Share on other sites

  • Moderators

VelvetElvis,

Inputs are a little special in that regard - you have to have entered at least one character for the input to action on ENTER. If it stays empty you do not get an event triggered. Note that once the input has had something entered it will fire even if you backspace the entry and leave the input empty. But you get no return if the input has had no data entered at all since it last fired.

So to get round this problem I often use ENTER as an Accelerator key like this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$Form1 = GUICreate("Form1", 393, 214, -1, -1)
$Input1 = GUICtrlCreateInput("", 56, 24, 273, 21)
$Input2 = GUICtrlCreateInput("", 56, 73, 273, 21)
$ButtonExit = GUICtrlCreateButton("E&xit", 240, 128, 113, 33)

; Create dummy control  ; <<<<<<<<<<<<<<<<<<<<<<<<
$hDummy = GUICtrlCreateDummy()

GUISetState(@SW_SHOW)

; Set accelerator for ENTER to action the dummy control  ; <<<<<<<<<<<<<<<<<<<<<<<<
Global $aAccelKeys[1][2]=[["{ENTER}", $hDummy]]
GUISetAccelerators($aAccelKeys)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $ButtonExit
            Exit
        Case $hDummy ; Our dummy control is actioned ; <<<<<<<<<<<<<<<<<<<<<<<<
            ; Which input has focus? ; <<<<<<<<<<<<<<<<<<<<<<<<
            If _WinAPI_GetFocus() = GUICtrlGetHandle($Input1) Then
                $scan1 = GUICtrlRead($Input1) ; Read scan to var
                ConsoleWrite("Input1 holds: " & $scan1 & @CRLF)
                GUICtrlSetState($Input2, $GUI_FOCUS) ; Set focus to 2nd input
            ElseIf _WinAPI_GetFocus() = GUICtrlGetHandle($Input2) Then
                $scan2 = GUICtrlRead($Input2) ; Read scan to var
                ConsoleWrite("Input2 holds: " & $scan2 & @CRLF)
                GUICtrlSetState($Input1, $GUI_FOCUS) ; Return focus to 1st input
            EndIf
    EndSwitch
WEnd

Accelerator keys are a bit like HotKeys, exept that they only work when your GUI is active. ;)

Once again, please ask if you have any questions. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

VelvetElvis,

Inputs are a little special in that regard - you have to have entered at least one character for the input to action on ENTER. If it stays empty you do not get an event triggered. Note that once the input has had something entered it will fire even if you backspace the entry and leave the input empty. But you get no return if the input has had no data entered at all since it last fired.

Ah, so that's it! Despite my rummaging through the help file, I didn't run across this. Definitely going into my Tips N Tricks file.

So to get round this problem I often use ENTER as an Accelerator key like this:

#include <buttonconstants.au3>
#include <editconstants.au3>
#include <guiconstantsex.au3>
#include <windowsconstants.au3>
#include <winapi.au3>

$Form1 = GUICreate("Form1", 393, 214, -1, -1)
$Input1 = GUICtrlCreateInput("", 56, 24, 273, 21)
$Input2 = GUICtrlCreateInput("", 56, 73, 273, 21)
$ButtonExit = GUICtrlCreateButton("E&xit", 240, 128, 113, 33)

; Create dummy control  ; <<<<<<<<<<<<<<<<<<<<<<<<
$hDummy = GUICtrlCreateDummy()

GUISetState(@SW_SHOW)

; Set accelerator for ENTER to action the dummy control  ; <<<<<<<<<<<<<<<<<<<<<<<<
Global $aAccelKeys[1][2]=[["{ENTER}", $hDummy]]
GUISetAccelerators($aAccelKeys)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $ButtonExit
            Exit
        Case $hDummy ; Our dummy control is actioned ; <<<<<<<<<<<<<<<<<<<<<<<<
            ; Which input has focus? ; <<<<<<<<<<<<<<<<<<<<<<<<
            If _WinAPI_GetFocus() = GUICtrlGetHandle($Input1) Then
                $scan1 = GUICtrlRead($Input1) ; Read scan to var
                ConsoleWrite("Input1 holds: " & $scan1 & @CRLF)
                GUICtrlSetState($Input2, $GUI_FOCUS) ; Set focus to 2nd input
            ElseIf _WinAPI_GetFocus() = GUICtrlGetHandle($Input2) Then
                $scan2 = GUICtrlRead($Input2) ; Read scan to var
                ConsoleWrite("Input2 holds: " & $scan2 & @CRLF)
                GUICtrlSetState($Input1, $GUI_FOCUS) ; Return focus to 1st input
            EndIf
    EndSwitch
WEnd

Accelerator keys are a bit like HotKeys, exept that they only work when your GUI is active. :D

Once again, please ask if you have any questions. ;)

M23

That is indeed slick. Thank you very much Melba23! :)
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...