Jump to content

Recommended Posts

Posted

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?

  • Moderators
Posted

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

 

Posted

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

  • Moderators
Posted

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

 

Posted

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:

  • Moderators
Posted

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

 

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
  • Recently Browsing   0 members

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