Jump to content

Recommended Posts

Posted (edited)

I have created a settings window, but when it hid behind my browser, I forgot it was still open, so i clicked the button to open it again, which did nothing. I've spent all day today trying to figure out how to get the window to be brought to the front, ie, topmost, and for the button that opens it to not respond to further clicks if it is open, but everything is not working for me. Please can someone help...
Here's my SettingsGUI.au3:
 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <GuiListView.au3>
#include <File.au3>
#include <WinAPIFiles.au3>
#include <GuiTab.au3>
#include <GuiEdit.au3>
#include <GuiButton.au3>
#include <GuiComboBox.au3>
#include <GuiListBox.au3>
#include <GuiSlider.au3>
#include <GuiMenu.au3>
#include <Misc.au3>

Global $g_hGUI = 0, $g_hTab
Global $g_aCheckBoxCtrlIDs[0], $g_aCheckBoxNames[0]
Global $g_hSandBoxieInput, $hSandBoxieBrowse
Global $hScanLV, $hScanLV_Handle, $btnAddScan, $btnEditScan, $btnDeleteScan, $btnDebugLV, $btnScan
Global $g_aScanPaths[0], $g_aScanDepths[0]
Global $btnOK, $btnCancel

Func _DebugListView()
    Local $selText = GUICtrlRead($hScanLV)
    MsgBox(64, "DEBUG", "GUICtrlRead result: " & $selText)
    If $selText <> "" Then
        Local $parts = StringSplit($selText, "|")
        If $parts[0] >= 3 Then
            MsgBox(64, "DEBUG", "Selected index: " & (Number($parts[1]) - 1) & @CRLF & _
                "Path: " & $parts[2] & @CRLF & "Depth: " & $parts[3])
        EndIf
    EndIf
EndFunc

Func ShowSettingsGUI()
    Global $g_hGUI, $g_SettingsOpen
    $g_SettingsOpen = True
    $g_hGUI = GUICreate("Settings", 700, 420, -1, -1, $WS_SYSMENU)
    $g_hTab = GUICtrlCreateTab(10, 10, 680, 380)
    TrayItemSetState($TRAY_SETTINGS, $TRAY_DISABLE)
    ; --- Global Tab ---
    GUICtrlCreateTabItem("Global")
    SetupGlobalTab()
    ; --- Buttons Tab (NEW TAB #2) ---
    GUICtrlCreateTabItem("Buttons")
    SetupButtonsTab()
    ; --- About Tab (now TAB #3) ---
    GUICtrlCreateTabItem("About")
    SetupAboutTab()
    GUICtrlCreateTabItem("") ; End tab items
    ; OK and Cancel buttons - Always visible, not part of tabs
    $btnOK     = GUICtrlCreateButton("OK", 510, 350, 80, 30)
    $btnCancel = GUICtrlCreateButton("Cancel", 600, 350, 80, 30)
    GUISetState(@SW_SHOW, $g_hGUI)

    While 1
        Local $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop
            ; Add any button handlers for the Buttons tab here, e.g.:
            ; Case $btnMyButton
            ;     ; Do something
            Case $btnAddScan
                _AddScanPath()
            Case $btnEditScan
                _EditScanPath()
            Case $btnDeleteScan
                _DeleteScanPath()
            Case $btnDebugLV
                _DebugListView()
            Case $btnScan
                SaveScanPathsToINI()
                ScanAppsFolders()
            Case $hSandBoxieBrowse
                Local $exePath = FileOpenDialog("Select SandMan.exe (Sandboxie)", @ScriptDir, "Executable (*.exe)", 1)
                If @error Or $exePath = "" Then ContinueLoop
                GUICtrlSetData($g_hSandBoxieInput, $exePath)
            Case $g_AboutLinkCtrl
                ShellExecute($g_AboutLinkURL)
            Case $btnOK
                SaveGlobalTab()
                SaveScanPathsToINI()
                ExitLoop
            Case $btnCancel
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete($g_hGUI)
    $g_hGUI = 0
    $g_SettingsOpen = False
    TrayItemSetState($TRAY_SETTINGS, $TRAY_ENABLE)
EndFunc

Func SetupGlobalTab()
    Local $iY = 50
    GUICtrlCreateLabel("Scan Paths", 20, $iY, 100, 20)
    $hScanLV = GUICtrlCreateListView("#|Path|Depth", 20, $iY + 20, 600, 180, $LVS_SHOWSELALWAYS + $LVS_SINGLESEL)
    $hScanLV_Handle = GUICtrlGetHandle($hScanLV)
    _GUICtrlListView_SetColumnWidth($hScanLV_Handle, 0, 40)
    _GUICtrlListView_SetColumnWidth($hScanLV_Handle, 1, 480) ; Path column enlarged!
    _GUICtrlListView_SetColumnWidth($hScanLV_Handle, 2, 50)
    $btnAddScan    = GUICtrlCreateButton("Add",      630, $iY + 25, 50, 25)
    $btnEditScan   = GUICtrlCreateButton("Edit",     630, $iY + 60, 50, 25)
    $btnDeleteScan = GUICtrlCreateButton("Delete",   630, $iY + 95, 50, 25)
    $btnDebugLV    = GUICtrlCreateButton("Debug LV", 630, $iY + 130, 60, 25)
    $btnScan       = GUICtrlCreateButton("Scan",     630, $iY + 170, 50, 25)
    GUICtrlSetState($btnDebugLV, $GUI_HIDE)

    Local $iY2 = $iY + 210
    Local $aSettings = IniReadSection(@ScriptDir & "\App\Settings.ini", "GLOBAL")
    If @error Then Return
    Global $g_aCheckBoxCtrlIDs[0], $g_aCheckBoxNames[0]
    For $i = 1 To $aSettings[0][0]
        Local $key = $aSettings[$i][0]
        Local $val = $aSettings[$i][1]
        If StringRegExp($key, "^Scan\d+$") Or StringRegExp($key, "^Scan\d+Depth$") Then
            ContinueLoop
        EndIf
        If $val = "1" Or $val = "0" Then
            Local $id = GUICtrlCreateCheckbox($key, 30, $iY2, 200, 20)
            GUICtrlSetState($id, ($val = "1") ? $GUI_CHECKED : $GUI_UNCHECKED)
            _ArrayAdd($g_aCheckBoxCtrlIDs, $id)
            _ArrayAdd($g_aCheckBoxNames, $key)
            $iY2 += 30
        EndIf
    Next

    GUICtrlCreateLabel("Sandboxie Executable Path (SandMan.exe):", 30, $iY2, 250, 20)
    Local $sandboxieValue = IniRead(@ScriptDir & "\App\Settings.ini", "GLOBAL", "SandboxiePath", "")
    $g_hSandBoxieInput = GUICtrlCreateInput($sandboxieValue, 30, $iY2 + 25, 250, 20)
    $hSandBoxieBrowse = GUICtrlCreateButton("...", 250, $iY2 -4, 30, 22)

    _LoadScanPathsFromINI()
    _RefreshScanListView()
EndFunc

Func SaveGlobalTab()
    For $i = 0 To UBound($g_aCheckBoxCtrlIDs) - 1
        Local $state = GUICtrlRead($g_aCheckBoxCtrlIDs[$i])
        Local $val = ($state = $GUI_CHECKED) ? "1" : "0"
        IniWrite(@ScriptDir & "\App\Settings.ini", "GLOBAL", $g_aCheckBoxNames[$i], $val)
    Next
    Local $sandboxiePath = GUICtrlRead($g_hSandBoxieInput)
    IniWrite(@ScriptDir & "\App\Settings.ini", "GLOBAL", "SandboxiePath", $sandboxiePath)
EndFunc

Func _LoadScanPathsFromINI()
    Global $g_aScanPaths[0], $g_aScanDepths[0]
    Local $i = 1
    While True
        Local $path = IniRead(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & $i, "")
        If $path = "" Then ExitLoop
        Local $depth = IniRead(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & $i & "Depth", "1")
        _ArrayAdd($g_aScanPaths, $path)
        _ArrayAdd($g_aScanDepths, $depth)
        $i += 1
    WEnd
EndFunc

; --- New combined dialog for path/depth ---
Func ShowScanPathDialog($sPath = "", $sDepth = "1", $bEdit = False)
    Local $title = $bEdit ? "Edit Scan Path" : "Add Scan Path"
    Local $hDlg = GUICreate($title, 365, 150, -1, -1, $WS_SYSMENU)
    GUICtrlCreateLabel("Scan Path:", 10, 14, 70, 22)
    Local $inpPath = GUICtrlCreateInput($sPath, 80, 10, 220, 20)
    Local $btnBrowse = GUICtrlCreateButton("...", 310, 9, 40, 22)
    GUICtrlCreateLabel("Scan Depth:", 10, 50, 70, 22)
    Local $cboDepth = GUICtrlCreateCombo("", 80, 46, 60, 22)
    GUICtrlCreateLabel("1 = Scan path folder, 2 = Sub folder, etc.", 150, 50, 200, 22)
    For $i = 1 To 10
        GUICtrlSetData($cboDepth, $i)
    Next
    GUICtrlSetData($cboDepth, $sDepth)
    Local $btnOK = GUICtrlCreateButton("OK", 180, 85, 80, 30)
    Local $btnCancel = GUICtrlCreateButton("Cancel", 270, 85, 80, 30)
    GUISetState(@SW_SHOW, $hDlg)

    Local $result[2] = ["", ""]
    While 1
        Local $msg = GUIGetMsg()
        Select
            Case $msg = $GUI_EVENT_CLOSE Or $msg = $btnCancel
                ExitLoop
            Case $msg = $btnBrowse
                Local $selectedFolder = FileSelectFolder("Select folder for Scan Path", "", 1)
                If Not @error And $selectedFolder <> "" Then
                    GUICtrlSetData($inpPath, $selectedFolder)
                EndIf
            Case $msg = $btnOK
                $result[0] = GUICtrlRead($inpPath)
                Local $depth = GUICtrlRead($cboDepth)
                ; Auto-correct depth between 1 and 10
                If Not StringIsInt($depth) Then
                    $depth = 1
                ElseIf $depth < 1 Then
                    $depth = 1
                ElseIf $depth > 10 Then
                    $depth = 10
                EndIf
                $result[1] = $depth
                ExitLoop
        EndSelect
    WEnd
    GUIDelete($hDlg)
    Return $result
EndFunc

Func _AddScanPath()
    Local $vals = ShowScanPathDialog("", "1", False)
    If $vals[0] = "" Then Return
    If $vals[1] = "" Then $vals[1] = "1"
    _ArrayAdd($g_aScanPaths, $vals[0])
    _ArrayAdd($g_aScanDepths, $vals[1])
    _RefreshScanListView()
EndFunc

Func _GetSelectedIndex()
    Local $count = _GUICtrlListView_GetItemCount($hScanLV_Handle)
    For $i = 0 To $count - 1
        If _GUICtrlListView_GetItemSelected($hScanLV_Handle, $i) Then
            Return $i
        EndIf
    Next
    Return -1
EndFunc

Func _EditScanPath()
    Local $selIndex = _GetSelectedIndex()
    If $selIndex = -1 Then
        MsgBox(16, "Edit Scan Path", "Please select a scan path to edit.")
        Return
    EndIf
    Local $currPath = $g_aScanPaths[$selIndex]
    Local $currDepth = $g_aScanDepths[$selIndex]
    Local $vals = ShowScanPathDialog($currPath, $currDepth, True)
    If $vals[0] = "" Then Return
    If $vals[1] = "" Then $vals[1] = "1"
    $g_aScanPaths[$selIndex] = $vals[0]
    $g_aScanDepths[$selIndex] = $vals[1]
    _RefreshScanListView()
EndFunc

Func _DeleteScanPath()
    Local $selIndex = _GetSelectedIndex()
    If $selIndex = -1 Then
        MsgBox(16, "Delete Scan Path", "Please select a scan path to delete.")
        Return
    EndIf
    _ArrayDelete($g_aScanPaths, $selIndex)
    _ArrayDelete($g_aScanDepths, $selIndex)
    _RefreshScanListView()
EndFunc

Func _RefreshScanListView()
    _GUICtrlListView_DeleteAllItems($hScanLV_Handle)
    For $i = 0 To UBound($g_aScanPaths) - 1
        GUICtrlCreateListViewItem(StringFormat("%d|%s|%s", $i+1, $g_aScanPaths[$i], $g_aScanDepths[$i]), $hScanLV)
    Next
EndFunc

Func SaveScanPathsToINI()
    Local $i = 1
    While True
        Local $old = IniRead(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & $i, "")
        If $old = "" Then ExitLoop
        IniDelete(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & $i)
        IniDelete(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & $i & "Depth")
        $i += 1
    WEnd
    For $j = 0 To UBound($g_aScanPaths) - 1
        IniWrite(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & ($j + 1), $g_aScanPaths[$j])
        IniWrite(@ScriptDir & "\App\Settings.ini", "GLOBAL", "Scan" & ($j + 1) & "Depth", $g_aScanDepths[$j])
    Next
EndFunc


;~ If True Then ShowSettingsGUI()

And here's the button to open the settings:
 

Func Buttons_OpenSettings()
    Global $g_hGUI, $g_SettingsOpen
    ; Don't queue - only allow if not open
    If $g_SettingsOpen And WinExists($g_hGUI) Then
        WinActivate($g_hGUI)
        Return
    EndIf
    ; Set flag BEFORE calling GUI function to prevent queue
    $g_SettingsOpen = True
    ShowSettingsGUI()
EndFunc

I'd appreciate a lot if someone could put me out of my misery!!! Thanks. 😁

Edited by sl23
Posted
40 minutes ago, sl23 said:

I forgot it was still open, so i clicked the button to open it again,

Func main()
    Local $sTitleEx = "[TITLE:" & StringTrimRight(@ScriptName, 4) & ";CLASS:AutoIt v3 GUI;]"
    If WinExists($sTitleEx) Then
        WinActivate($sTitleEx)
        Local $aPos = WinGetPos($sTitleEx)
        If UBound($aPos) = 4 Then
            For $n = 1 To 5
                WinMove($sTitleEx, "", $aPos[0] - 20, $aPos[1] + 20)
                Sleep(50)
                WinMove($sTitleEx, "", $aPos[0] + 20, $aPos[1] - 20)
                Sleep(50)
            Next
            WinMove($sTitleEx, "", $aPos[0], $aPos[1])
        EndIf
        Exit
    EndIf
    .... the rest of your code ....

 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted
43 minutes ago, sl23 said:
    Local $title = $bEdit ? "Edit Scan Path" : "Add Scan Path"
    Local $hDlg = GUICreate($title, 365, 150, -1, -1, $WS_SYSMENU)

oops, my bad.

GUICreate ( "title" [, width [, height [, left = -1 [, top = -1 [, style = -1 [, exStyle = -1 [, parent = 0]]]]]]] )
Just tell your new GUI that it has a parent and they'll stick together.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

Thanks, I did try that here but it didn't work, I must have it wrong somehow:
 

Func ShowSettingsGUI()
    Global $g_hGUI, $g_SettingsOpen
    $g_SettingsOpen = True
    TrayItemSetState($TRAY_SETTINGS, $TRAY_DISABLE)
    $g_hGUI = GUICreate("Settings", 700, 420, -1, -1, $WS_SYSMENU)
    $g_hTab = GUICtrlCreateTab(10, 10, 680, 380)
    ; --- Global Tab ---
    GUICtrlCreateTabItem("Global")
    SetupGlobalTab()
    ; --- Buttons Tab (NEW TAB #2) ---
    GUICtrlCreateTabItem("Buttons")
    SetupButtonsTab()
    ; --- About Tab (now TAB #3) ---
    GUICtrlCreateTabItem("About")
    SetupAboutTab()
    GUICtrlCreateTabItem("") ; End tab items
    ; OK and Cancel buttons - Always visible, not part of tabs
    $btnOK     = GUICtrlCreateButton("OK", 510, 350, 80, 30)
    $btnCancel = GUICtrlCreateButton("Cancel", 600, 350, 80, 30)
    GUISetState(@SW_SHOW, $g_hGUI)

    While 1
        Local $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop
            ; Add any button handlers for the Buttons tab here, e.g.:
            ; Case $btnMyButton
            ;     ; Do something
            Case $btnAddScan
                _AddScanPath()
            Case $btnEditScan
                _EditScanPath()
            Case $btnDeleteScan
                _DeleteScanPath()
            Case $btnDebugLV
                _DebugListView()
            Case $btnScan
                SaveScanPathsToINI()
                ScanAppsFolders()
            Case $hSandBoxieBrowse
                Local $exePath = FileOpenDialog("Select SandMan.exe (Sandboxie)", @ScriptDir, "Executable (*.exe)", 1)
                If @error Or $exePath = "" Then ContinueLoop
                GUICtrlSetData($g_hSandBoxieInput, $exePath)
            Case $g_AboutLinkCtrl
                ShellExecute($g_AboutLinkURL)
            Case $btnOK
                SaveGlobalTab()
                SaveScanPathsToINI()
                ExitLoop
            Case $btnCancel
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete($g_hGUI)
    $g_hGUI = 0
    $g_SettingsOpen = False
    TrayItemSetState($TRAY_SETTINGS, $TRAY_ENABLE)
EndFunc

I used TrayItemSetState()  at the top and bottom, to create the gui, disable the  tray item and on close, to enable it again, as it was the tray item I wanted to disable until the window has closed. Least that was the only way I could think of to stop multiple windows opening one after the other.

  • 2 weeks later...
Posted

With this example, TrayItemSetState seems to work as expected.

#NoTrayIcon
#include <MsgBoxConstants.au3>
#include <StringConstants.au3>
#include <TrayConstants.au3>

Opt("TrayMenuMode", 3)

Example()

Func Example()
        Local $idAbout = TrayCreateItem("About")
        TrayCreateItem("") ; Create a separator line.

        Local $idExit = TrayCreateItem("Exit")

        TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu.

        While 1
                Switch TrayGetMsg()
                        Case $idAbout ; Display a message box about the AutoIt version and installation path of the AutoIt executable.
                                TrayItemSetState($idAbout, $TRAY_DISABLE)
                                MsgBox($MB_SYSTEMMODAL, "", "AutoIt tray menu example." & @CRLF & @CRLF & _
                                                "Version: " & @AutoItVersion & @CRLF & _
                                                "Install Path: " & StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", $STR_NOCASESENSEBASIC, -1) - 1)) ; Find the folder of a full path.
                                TrayItemSetState($idAbout, $TRAY_ENABLE)
                        Case $idExit ; Exit the loop.
                                ExitLoop
                EndSwitch
        WEnd
EndFunc   ;==>Example

I don't see $TRAY_SETTINGS defined in the code you posted. 

Perhaps it is defined elsewhere and the scope is limited to the function where it is created and the ShowSettingsGUI function can't access it?

Posted

You can refer to the following code:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <TrayConstants.au3>

; --- Global variables ---
Global $g_hMainGUI = 0, $g_hSettingsGUI = 0, $tray_ShowSettings, $tray_Exit
Global $g_SettingsOpen = False

; --- Main entry point ---
_Main()

Func _Main()
    ; Create main GUI
    $g_hMainGUI = GUICreate("Main Program", 400, 200)
    Local $btnSettings = GUICtrlCreateButton("Settings", 150, 80, 100, 30)
    GUISetState(@SW_SHOW, $g_hMainGUI)

    ; Create tray icon + menu
    Opt("TrayMenuMode", 3) ; default items off
    $tray_ShowSettings = TrayCreateItem("Settings")
    $tray_Exit = TrayCreateItem("Exit")
    TraySetClick(16) ; left click = show tray menu
    TraySetState()

    ; Message loop
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $btnSettings
                OpenSettings()
        EndSwitch

        Switch TrayGetMsg()
            Case $tray_ShowSettings
                OpenSettings()
            Case $tray_Exit
                Exit
        EndSwitch
    WEnd

    GUIDelete($g_hMainGUI)
EndFunc   ;==>_Main

; --- Settings GUI ---
Func ShowSettingsGUI()
    $g_SettingsOpen = True
    GUISetState(@SW_HIDE, $g_hMainGUI)
    $g_hSettingsGUI = GUICreate("Settings", 350, 200, -1, -1, $WS_SYSMENU, $WS_EX_TOPMOST, $g_hMainGUI)
    Local $btnOK = GUICtrlCreateButton("OK", 190, 150, 70, 30)
    Local $btnCancel = GUICtrlCreateButton("Cancel", 270, 150, 70, 30)
    GUISetState(@SW_SHOW, $g_hSettingsGUI)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $btnCancel
                ExitLoop
            Case $btnOK
                MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, ':)', 'Button OK Pressed', 0, $g_hSettingsGUI)
        EndSwitch
    WEnd

    GUIDelete($g_hSettingsGUI)
    GUISetState(@SW_SHOW, $g_hMainGUI)
    WinActivate($g_hMainGUI)
    $g_hSettingsGUI = 0
    $g_SettingsOpen = False
EndFunc   ;==>ShowSettingsGUI

; --- Wrapper to prevent duplicate windows ---
Func OpenSettings()
    If $g_SettingsOpen And WinExists($g_hSettingsGUI) Then
        ; Bring to front
        WinSetOnTop($g_hSettingsGUI, "", 1)
        WinActivate($g_hSettingsGUI)
        Return
    EndIf
    ShowSettingsGUI()
EndFunc   ;==>OpenSettings

 

Regards,
 

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