Jump to content

Creating GUI in for-loop


flet
 Share

Recommended Posts

Is there a way to create a GUI in a for-loop? As in: I have a program which asks the user for passwords if the email is unknown. For each account that is not known, I want a GUI to be created that prompts the user for the password. After user clicks the 'OK' button on the GUI, the password is written to a file, and program continues with the next account. Something like this (I AM aware that code below doesn't work):

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
 
Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)
 
Global $accounts_file = "accountz.ini"
Global $gui_pw, $label_pw, $input_pw, $button_pw_enter
 
Func _GUIAskPasswordButtonClick()
Local $password = GUICtrlRead($input_pw)
 
Switch @GUI_CtrlId
Case $button_pw_enter
   If ($password <> "") Then
    IniWrite($accounts_file, GUICtrlRead($label_pw), "Password", $password)
    GUIDelete($gui_pw)
   Else
    MsgBox(16, "Error", "Please type password:")
    GUICtrlSetData($input_pw, "")
    GUICtrlSetState($input_pw, $GUI_FOCUS)
   EndIf
  EndSwitch
EndFunc
 
Func _Exit()
  Exit
EndFunc
 
Func GUIAskPassword($login)
  $gui_pw = GUICreate("Account unknown", 395, 180)
  GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
  GUICtrlCreateGroup("", 70, 50, 300, 80)
  GUICtrlCreateLabel("Login:", 85, 70, 75, 20)
  $label_pw = GUICtrlCreateLabel($login, 170, 70, 175, 20)
  GUICtrlCreateLabel("Password:", 85, 95, 75, 20)
  $input_pw = GUICtrlCreateInput("", 170, 95, 175, 20, $ES_PASSWORD)
  GUICtrlSetState(-1, $GUI_FOCUS)
  $button_pw_enter = GUICtrlCreateButton("&OK", 163, 145, 75, 25, $BS_DEFPUSHBUTTON)
  GUICtrlSetOnEvent(-1, "_GUIAskPasswordButtonClick")
  GUISetState(@SW_SHOW, $gui_pw)
EndFunc
 
Dim $accounts[3] = ["first@email.com", "second@email.com", "third@email.com"]
 
For $i = 0 To Ubound($accounts) - 1
  GUIAskPassword($accounts[$i])
Next
 
While 1
  Sleep(10)
WEnd

This piece of code is simplified. In my program this GUI is a child window and the number of accounts can vary. ONEVEnt mode is obligatory :graduated:

My script doesn't work because it puts all 3 GUI's in the same variable $gui_pw, so things are messed up big time: the first GUIs can't be closed. How do I wait until the user has clicked the OK button before creating the next GUI? Is there an easier and better way to do this? The only thing I came up with now, is to switch to messageloop mode and back to onevent mode after completing my function...but that is soooo ugly

Any ideas?

Link to comment
Share on other sites

  • Moderators

flet,

I would create the GUI once and then hide/show it as necessary - like this: :graduated:

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

Opt("GUIOnEventMode", 1)

Global $accounts_file = "accountz.ini"
Global $gui_pw, $label_pw, $input_pw, $button_pw_enter, $fTest = False
Global $accounts[3] = ["first@email.com", "second@email.com", "third@email.com"]

; Create the GUI and hide it
CreatePasswordGUI()

; Now check the accounts
For $i = 0 To UBound($accounts) - 1
    GUIAskPassword($accounts[$i])
Next

; We no longer need the GUI
GUICreate($gui_pw)

Exit

Func GUIAskPassword($account)

    ; Read the password
    Local $Password = IniRead($accounts_file, $account, "Password", "")
    ; if there was no password
    If Not $Password Then
        ; Shwo the GUI
        GUISetState(@SW_SHOW, $gui_pw)
        ; Set the account name
        GUICtrlSetData($label_pw, $account)
        ; Now wait until the button is pressed
        While 1
            If $fTest Then
                $fTest = False
                ; Check the password
                Local $password = GUICtrlRead($input_pw)
                If ($password <> "") Then
                    IniWrite($accounts_file, GUICtrlRead($label_pw), "Password", $password)
                    GUICtrlSetData($input_pw, "")
                    GUISetState(@SW_HIDE, $gui_pw)
                    ExitLoop
                Else
                    MsgBox(16, "Error", "Please type password:")
                    GUICtrlSetData($input_pw, "")
                    GUICtrlSetState($input_pw, $GUI_FOCUS)
                EndIf
            EndIf
            Sleep(10)
        WEnd
    EndIf

EndFunc

Func CreatePasswordGUI()
    $gui_pw = GUICreate("Account unknown", 395, 180)
    GUICtrlCreateGroup("", 70, 50, 300, 80)
    GUICtrlCreateLabel("Login:", 85, 70, 75, 20)
    $label_pw = GUICtrlCreateLabel("", 170, 70, 175, 20)
    GUICtrlCreateLabel("Password:", 85, 95, 75, 20)
    $input_pw = GUICtrlCreateInput("", 170, 95, 175, 20, $ES_PASSWORD)
    GUICtrlSetState(-1, $GUI_FOCUS)
    $button_pw_enter = GUICtrlCreateButton("&OK", 163, 145, 75, 25, $BS_DEFPUSHBUTTON)
    GUICtrlSetOnEvent(-1, "Test")
    GUISetState(@SW_HIDE, $gui_pw)
EndFunc   ;==>CreatePasswordGUI

Func Test()
    ; Set the flag to show the button was pressed
    $fTest = True
EndFunc

I do not code much in OnEvent mode, so I have resorted to a clumsy flag to show the button is pressed. No doubt it can be done better. ;)

The only thing I came up with now, is to switch to messageloop mode and back to onevent mode after completing my function...but that is soooo ugly

On the contrary it is a very clever trick able to cope with situations like this - I was sorely tempted to do it here! :)

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 your input Melba. I'm going to try it like you're suggesting in my actual script: a few adjustments are needed though. Quick question: Do I check for the flag thingy in the 'While 1'-loop from the main GUI? cause creating an extra while loop in a child gui will freeze the script...

It's a dilemma: plain ugliness OR melting my brains trying to solve everything OnEvent for the sake of consistency :graduated:

If your suggestion doesn't work I'm tempted to do it in a message-loop..I've alreay put enough time into this

Link to comment
Share on other sites

  • Moderators

flet,

creating an extra while loop in a child gui will freeze the script

I assumed this was an initial setup process and so having a second loop to collect missing passwords was not a problem. :graduated:

This is one of the reasons I dislike OnEvent mode - having to get back to the main loop all the time. And I still dispute your ugliness claim - here is the same script with the mode change:

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

Opt("GUIOnEventMode", 1)

Global $accounts_file = "accountz.ini"
Global $gui_pw, $label_pw, $input_pw, $button_pw_enter, $fTest = False
Global $accounts[3] = ["first@email.com", "second@email.com", "third@email.com"]

CreatePasswordGUI()

For $i = 0 To UBound($accounts) - 1
    GUIAskPassword($accounts[$i])
Next

; GUI no longer needed
GUIDelete($gui_pw)

; Confirm we are in OnEvent mode
ConsoleWrite(Opt("GUIOnEventMode") & @CRLF)

Exit

Func GUIAskPassword($account)

    Local $Password = IniRead($accounts_file, $account, "Password", "")

    ConsoleWrite($account & " - " &$Password & @CRLF)

    If Not $Password Then
        GUISetState(@SW_SHOW, $gui_pw)
        GUICtrlSetData($label_pw, $account)
        ; Switch to MessageLoop mode
        Opt("GUIOnEventMode", 0)
        While 1
            Switch GUIGetMsg()
                Case $button_pw_enter
                    Local $password = GUICtrlRead($input_pw)
                    If ($password <> "") Then
                        IniWrite($accounts_file, GUICtrlRead($label_pw), "Password", $password)
                        GUICtrlSetData($input_pw, "")
                        GUISetState(@SW_HIDE, $gui_pw)
                        ExitLoop
                    Else
                        MsgBox(16, "Error", "Please type password:")
                        GUICtrlSetData($input_pw, "")
                        GUICtrlSetState($input_pw, $GUI_FOCUS)
                    EndIf
            EndSwitch

        WEnd
        ; Switch back to OnEvent Mode
        Opt("GUIOnEventMode", 1)
    EndIf

EndFunc

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Func CreatePasswordGUI()
    $gui_pw = GUICreate("Account unknown", 395, 180)
    GUICtrlCreateGroup("", 70, 50, 300, 80)
    GUICtrlCreateLabel("Login:", 85, 70, 75, 20)
    $label_pw = GUICtrlCreateLabel("", 170, 70, 175, 20)
    GUICtrlCreateLabel("Password:", 85, 95, 75, 20)
    $input_pw = GUICtrlCreateInput("", 170, 95, 175, 20, $ES_PASSWORD)
    GUICtrlSetState(-1, $GUI_FOCUS)
    $button_pw_enter = GUICtrlCreateButton("&OK", 163, 145, 75, 25, $BS_DEFPUSHBUTTON)
    GUISetState(@SW_HIDE, $gui_pw)
EndFunc   ;==>CreatePasswordGUI

While 1
    Sleep(10)
WEnd

Looks cleaner to me! ;)

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

you're probably right..

btw, i meant ugliness in the sense: mixing onevent and message-loop in 1 script really hurts my eyes, but after spending a couple of hours on this problem i'm going for ugly now. user won't see a thing of it when my script is compiled to exe :graduated:

Link to comment
Share on other sites

  • Moderators

flet,

user won't see a thing of it

I do this sometimes in my UDFs - store the mode on entry, use MessageLoop mode within the UDF, and then very carefully reset the original mode on exit. And as you said, completely transparent to the user. :graduated:

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

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...