Jump to content

Is it possible to press a button and delay part of its actions?


Recommended Posts

Ok im trying on a gui that i need to disable the button to stop multi press and continue on with the button commands that it has to perform

then after 30 secs i want the button to come alive again

Ive made an example with sleep but it holds the processes i want to run as well

Is there a way to set a timer? or something that doesnt hold the shellexecute?

I cant put the shellexecute at the top button kill must be first as the real gui has long process to do and double press would happen again buythe time it got to the kill button

#include <GUIConstantsEx.au3>
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example")
    Local $idOK = GUICtrlCreateButton("OK", 200, 200, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        Case $idOK
            _ButtonDelay($idOK) ; now trying like this but it holds the shellexecute as well
;~          GUICtrlSetState($idOK, $GUI_DISABLE) ; was disabling like this <<<<
            ShellExecute('ncpa.cpl') ;but i dont want this to wait 30 secs before it works, it cant be at the top as i have really complicated ones
        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _ButtonDelay($button)
    GUICtrlSetState($button, $GUI_DISABLE)
    Sleep(3000) ;<<<< need something better than this that doesnt halt the processes
    GUICtrlSetState($button, $GUI_ENABLE)
EndFunc

If i havent explained myself correctly just ask for another try

Edited by Chimaera
Link to comment
Share on other sites

  • Developers

Something like this? (untested)

#include <GUIConstantsEx.au3>
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example")
    Local $idOK = GUICtrlCreateButton("OK", 200, 200, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        Case $idOK
            _ButtonDelay($idOK) ; now trying like this but it holds the shellexecute as well
;~          GUICtrlSetState($idOK, $GUI_DISABLE) ; was disabling like this <<<<
            ShellExecute('ncpa.cpl') ;but i dont want this to wait 30 secs before it works, it cant be at the top as i have really complicated ones
        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _ButtonDelay($button)
    GUICtrlSetState($button, $GUI_DISABLE)
    AdlibRegister("_Enable_Button",3000)
EndFunc

Func _Enable_Button($button)
    AdlibUnRegister("_Enable_Button")
    GUICtrlSetState($button, $GUI_ENABLE)
EndFunc

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Moderators

Chimaera,

I would do something like this: :)

#include <GUIConstantsEx.au3>

; Array with expected GUI name and space for the button CtrlID
Global $aCheck_Data[2] = ["Network Connections"]

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example")
    Local $idOK = GUICtrlCreateButton("OK", 200, 200, 85, 25)
    $aCheck_Data[1] = $idOK                       ; Store the button CtrlID

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        Case $idOK
            GUICtrlSetState($idOK, $GUI_DISABLE)  ; Disable button
            ShellExecute('ncpa.cpl')              ; Run the ShellExecute
            AdlibRegister("_NCPA_Check", 10000)   ; Start an Adlib to check every 10 secs if the window is still open
        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _NCPA_Check()
    ; Check if window is still open
    If Not WinExists("Network Connections") Then
        GUICtrlSetState($aCheck_Data[1], $GUI_ENABLE) ; Re-enable button
        AdlibUnRegister("_NCPA_Check")                ; Cancel Adlib
        ConsoleWrite("Ended" & @CRLF)                 ;
    Else                                              ; These 23 lines are just for testing
        ConsoleWrite("Still running" & @CRLF)         ;
    EndIf
EndFunc
M23

Edit: I see Jos and I both had the same idea - so there must be a better way! :D

Edited by Melba23

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

@jos: can't adlib a function with parameters.

@melba: I think the idea is not to pause the button until that specific window is done, but to pause the button for X seconds after it has been pressed independent on whatever else is going on.

Chimaera says: "i need to disable the button to stop multi press", so I'm guessing the buttons do shellexecutes that run stuff that may take a while to pop up, and he's afraid of a user being impatient and run the same stuff 10 times in quick succession. (But I could be totally wrong :) )

Maybe a solution is to keep an array of TimerInit()'s for each button, and reset timer init X if button X if pressed. Then just have the main function loop through the timer array once each iteration and enable any disabled button that has a timer > 30k msecs?

Edited by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

  • Developers

@jos: can't adlib a function with parameters.

Correct ...  didn't look at it that closely nor tested, so guess it needs to be a global variable to pass it on to the Adlib func.

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

I get an error with jos's example which i think is caused by the $button pram

@Melba Sadbunny is right its user imaptient im trying to stop

so its disable button but keep other stuff running

jos example would have been good except for the param :(

I was just messing with this but i cant get it to make the button active again

Func _ButtonDelay($button)
    GUICtrlSetState($button, $GUI_DISABLE)
    Local $hTimer = TimerInit()
    If TimerDiff($hTimer) > 5000 Then
;~  Sleep(3000)
    GUICtrlSetState($button, $GUI_ENABLE)
    EndIf
EndFunc
Link to comment
Share on other sites

  • Moderators

Chimaera,

That simplifies the problem quite a lot: :)

#include <GUIConstantsEx.au3>

Global $idOK ; OK button CtrlID as Global variable

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example")
    $idOK = GUICtrlCreateButton("OK", 200, 200, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        Case $idOK
            GUICtrlSetState($idOK, $GUI_DISABLE)  ; Disable button
            ShellExecute('ncpa.cpl')              ; Run the ShellExecute
            AdlibRegister("_NCPA_Check", 5000)    ; Start an Adlib to fire after 5 secs
        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _NCPA_Check()
    GUICtrlSetState($idOK, $GUI_ENABLE)           ; Re-enable button
    AdlibUnRegister("_NCPA_Check")                ; Cancel Adlib
EndFunc
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

/edit:

@Melba: that would still require you to make a special function for every button.

 

How about this: a dynamically maintained array with buttons and their timers. All you need to do is call disableButton($button) on any pressed button, the rest is automatic :) I think using Adlib is an abuse here...

#include <GUIConstantsEx.au3>
#include <Array.au3>
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

Global $buttonTimers[0][2] ; will contain
Global $buttonDelay = 5000 ; 5 sec delay, enable a button 5 seconds after it was pressed

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example")
    Local $someButton = GUICtrlCreateButton("Thing 1", 10, 10, 85, 25)
    Local $anotherButton = GUICtrlCreateButton("Thing 2", 10, 40, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $someButton
                disableButton($someButton)
                ShellExecute("explorer")

            Case $anotherButton
                disableButton($anotherButton)
                ShellExecute('ncpa.cpl')
        EndSwitch

        enableButtons()

        Sleep(10)
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func enableButtons()
    For $i = 0 To UBound($buttonTimers) - 1
        Local $button = $buttonTimers[$i][0]
        Local $timer = $buttonTimers[$i][1]
        If (TimerDiff($timer) > $buttonDelay) Then
            GUICtrlSetState($button, $GUI_ENABLE)
            beep(1000,100)
            _ArrayDelete($buttonTimers, $i)
            enableButtons() ; recursive function call, so that we don't have to worry about changing the array size while looping through it
            Return
        EndIf
    Next
EndFunc   ;==>enableButtons

Func disableButton($button)
    GUICtrlSetState($button, $GUI_DISABLE)
    _ArrayAdd($buttonTimers, $button & "|" & TimerInit())
EndFunc   ;==>disableButton
Edited by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

  • Moderators

Chimaera,

Or try something like this which allows for any number of buttons: :)

#include <GUIConstantsEx.au3>

; Array to hold button IDs with timer info
Global $aCID[1][2] = [[0]]

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example")
    $idOK = _CreateButton("OK", 200, 200, 85, 25) ; Use custom function to create button

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        Case $idOK
            GUICtrlSetState($idOK, $GUI_DISABLE)  ; Disable button
            ShellExecute('ncpa.cpl')              ; Run the ShellExecute
            _DisableButon($idOK)
        EndSwitch

        ; Loop through butons to see if any need to be re-enabled
        _CheckButtons()

    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _CreateButton($sText, $iX, $iY, $iW, $iH)

    ; Add button to the array
    $aCID[0][0] += 1
    ReDim $aCID[$aCID[0][0] + 1][2]
    $aCID[$aCID[0][0]][0] = GUICtrlCreateButton($sText, $iX, $iY, $iW, $iH)
    Return $aCID[$aCID[0][0]][0]

EndFunc

Func _DisableButon($cCID)

    ; Find button in array
    For $i = 1 To $aCID[0][0]
        If $aCID[$i][0] = $cCID Then
            ; Start a timer
            $aCID[$i][1] = TimerInit()
            ExitLoop
        EndIf
    Next

EndFunc

Func _CheckButtons()

    ; Loop through array
    For $i = 1 To $aCID[0][0]
        ; If the timer is running
        If $aCID[$i][1] Then
            ; Check for how long
            If TimerDiff($aCID[$i][1]) > 5000 Then
                ; Reset timer
                $aCID[$i][1] = 0
                ; Re-enable button
                GUICtrlSetState($aCID[$i][0], $GUI_ENABLE)
            EndIf
        EndIf
    Next

EndFunc
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

  • Moderators

SadBunny,

Quite possibly, but I promise it was all my own work! :D

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

For a matter of performance I would simplify it this way... my 2 cents  :)

#include <GUIConstantsEx.au3>

Global $buttons[2][2], $delayed = 0
Global $buttonDelay = 5000 ; 5 sec delay

$hGUI = GUICreate("Example")
$buttons[0][0] = GUICtrlCreateButton("Thing 1", 10, 10, 85, 25)
$buttons[1][0] = GUICtrlCreateButton("Thing 2", 10, 40, 85, 25)
GUISetState(@SW_SHOW, $hGUI)
;ToolTip("0", 0, 0)

While 1
    Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit

            Case $buttons[0][0]
               $delayed += 1
               ;ToolTip($delayed, 0, 0)
               GUICtrlSetState($buttons[0][0], $GUI_DISABLE)
               $buttons[0][1] = TimerInit()
               Run(@AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(0, '''', ''Thing 1'')"')  ;ShellExecute("explorer")

            Case $buttons[1][0]
               $delayed += 1
               ;ToolTip($delayed, 0, 0)
                GUICtrlSetState($buttons[1][0], $GUI_DISABLE)
                $buttons[1][1] = TimerInit()
                Run(@AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(0, '''', ''Thing 2'')"') ;ShellExecute('ncpa.cpl')
        EndSwitch

        If $delayed > 0 Then enableButtons()

        Sleep(10)
WEnd


Func enableButtons()
    For $i = 0 To UBound($buttons) - 1
        If $buttons[$i][1] <> 0 and (TimerDiff($buttons[$i][1]) > $buttonDelay) Then
            GUICtrlSetState($buttons[$i][0], $GUI_ENABLE)
            beep(1000,100)
            $buttons[$i][1] = 0
            $delayed -= 1
            ;ToolTip($delayed, 0, 0)
        EndIf
    Next
EndFunc   ;==>enableButtons
Link to comment
Share on other sites

I thought about that, but you need to define your buttons beforehand in that way and lose the "well-naming" of the button variables. Much less "fluent" IMHO. Also, not that I have tested it, but is that testing of the delayed really that more efficient than doing "for $i = 0 to -1" (in case of no disabled buttons)?

(/edit: Of course there are big advantages to keeping your buttons and other controls in arrays. But only if the controls are dynamic enough to actually change often or have dynamic content or something... All depends on the situation, one is not necessarily better than the other of course.)

And I don't think your code is all that simplified... My code looks much nicer and cleaner. But that's my opinion :)

Case $someButton
                disableButton($someButton)
                Run("explorer")

... vs...
 

Case $buttons[1][0]
               $delayed += 1
               ;ToolTip($delayed, 0, 0)
                GUICtrlSetState($buttons[1][0], $GUI_DISABLE)
                $buttons[1][1] = TimerInit()
                Run("explorer")

?
:)

My functions are concise enough as well I would say, for this purpose at least.

Edited by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Link to comment
Share on other sites

@mikell, where is #pragma compile(AutoItExecuteAllowed, True)? Please read the help file page >> https://www.autoitscript.com/autoit3/docs/intro/running.htm

Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

In this code (which was about delays) the AutoIt3ExecuteLine was used as a kind of 'non-blocking msgbox' to avoid interfering with the delay returned by the timer

Such a sample code is rough and obviously not intended to be compiled as is

Thanks anyway for reminding me the existence of the help file  ;)

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