[V2-beta] - Example Gui Set Settings & Ini file

Post your working scripts, libraries and tools.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

[V2-beta] - Example Gui Set Settings & Ini file

23 Oct 2021, 15:01

This Gui is made to create easily a Gui of your settings, that can save and load this into your script and the ini file.
It is based on the property gui of windows explorer.

To add a control:
- Create it and set the name the same as the key. (one line of code)
- Add the value to the oSettings_Default

=> Setting the value is not necessary and will be based on the name, the key is assumed the same as the control name, the section will be copied from oSettings_Default, assuming that the key is unique. If the key is not unique, add a property "Section" to the control with the name of the Section.

=> loading and saving of the value will be done automatically, you do not even need to define the initial value, this will be used from the ini file or oSettings_Default

Update:
- Changed buttons to dark mode
- Added support for hotkey controls

Code: Select all

#SingleInstance force

global SettingsFile := A_ScriptDir "\" A_UserName ".ini"
global oSettings ; object variable for settings



; Setting the script menu to dark mode
uxtheme := DllCall("GetModuleHandle", "str", "uxtheme", "ptr")
SetPreferredAppMode := DllCall("GetProcAddress", "ptr", uxtheme, "ptr", 135, "ptr")
FlushMenuThemes := DllCall("GetProcAddress", "ptr", uxtheme, "ptr", 136, "ptr")
DllCall(SetPreferredAppMode, "int", 1)	; Dark
DllCall(FlushMenuThemes)

; Build 2D-array object to define the default values
; Put here the default settings
oSettings_Default := []	
oSettings_Default.NavMouseMenu := { NavMM_CreoView: "true"
    , NavMM_WorkbenchRevise: "true"
    , NavMM_WorkbenchCopy: "true"
    , NavMM_CommonSpace: "true"
    , NavMM_Iprint: "false"
    , NavMM_OpenFile: "true"
    , NavMM_ReplaceSelected: "true"
    , NavMM_Koppeling: "true"
    , NavMM_Electr_drw: "true"
    , NavMM_Eplan_drw: "false"
    , NavMM_Hotkey: "XButton1"
    , NavMM_Language: "Dutch"
    , NavMM_Hotkey2: "false" }
oSettings_Default.OutMouseMenu := { OutMM_Find_Articles: "true" }
oSettings_Default.CreoMouseMenu := { CreoMM_AdvancedHotkey: "true"
    , CreoMM_CheckOut: "true"
    , CreoMM_ExportTree: "true"
    , CreoMM_RadialMenu: "!Capslock"
    , CreoMM_RadialMenu2: "#Capslock" }
oSettings_Default.Creo := { Creo_CommentHandler: "true"
    , Creo_ParameterManager: "true"
    , Creo_disableNavImport: "false"
    , Creo_defaultBrowser: "Chrome" }
oSettings_Default.Test := { TestEdit: "TestEdit1" 
    , TestRadio: "Radio1" 
    , TestSlider: 40
    , TestDateTime : 20200101
    , TestMonthCal : 20200101
    , TestHotkey : "Ctrl+v"
    , TestListBox: "Green"}

;Load the existing settings 
oSettings := FileExist(SettingsFile) ? ReadINI(SettingsFile, oSettings_Default) : oSettings_Default

GuiSettings()
return

GuiSettings(){
    myGui := Gui()
    myGui.Opt("-0x30000")

    ; Changing the title bar to dark
    attr := VerCompare(A_OSVersion, "10.0.18985") >= 0 ? 20 : VerCompare(A_OSVersion, "10.0.17763") >= 0 ? 19 : ""
    DllCall("dwmapi\DwmSetWindowAttribute", "ptr", MyGui.hwnd, "int", attr, "int*", true, "int", 4) 

    ; Changing the Icon of the window
    hIcon32 := LoadPicture("wmploc", "w16 h-1 Icon18", &IMAGE_ICON := 1)
    myGui.Opt("+LastFound")	; Set our GUI as LastFound window ( affects next two lines )
    ErrorLevel := SendMessage((WM_SETICON := 0x80), 0, hIcon32)	; Set the Titlebar Icon
    ErrorLevel := SendMessage((WM_SETICON := 0x80), 1, hIcon32)	; Set the Alt-Tab icon

    Window := { Width: 300, Height: 500 }
    myGui.Title := "Settings"
    myGui.iniFile := SettingsFile

    ; Modify this part to define the outlook of your gui
    Tab := myGui.Add("Tab3", "x8 y8 w" Window.Width-14 " h" Window.Height-44 " Section", ["General", "Navision", "Creo", "Test"])

    Tab.UseTab(1)
    myGui.AddGroupBox("w" Window.Width - 37 " r4", "Hotkeys")
    myGui.AddText("x28 yp+18", "Main Hotkey")
    myGui.Add("ComboBox", "vNavMM_Hotkey yp x" Window.Width-28-100 " w100 ", ["XButton1", "XButton2", "Capslock"])
    
    myGui.AddText("x28 yp+25", "Radial Menu")
    myGui.Add("ComboBox", "vCreoMM_RadialMenu yp x" Window.Width-28-100 " w100 ", ["!Capslock"])
    myGui.AddText("x28 yp+25", "Radial Menu 2")
    myGui.Add("ComboBox", "vCreoMM_RadialMenu2 yp x" Window.Width-28-100 " w100 ", ["#Capslock"])

    ; myGui.AddProgress("xs+9 yp+30 w" Window.Width-36 " h1 BackgroundBlack") ; Line
    ogcCheckboxRunAtStartup := myGui.AddCheckbox("xs+12 yp+40 vRunAtStartup Checked ", "Run at startup")
    ogcCheckboxRunAtStartup.Section := "General" ; as this value is not defined in the Defaultsettings, we set a Section property
    myGui.AddCheckbox("xs+12 yp+25 vNavMM_OpenFile", "Open Project")

    Tab.UseTab(2)
    myGui.AddGroupBox("w" Window.Width - 37 " r5", "Menu Options")
    myGui.AddCheckbox("xp+8 yp+18 vNavMM_WorkbenchRevise ", "Workbench Revise")
    myGui.AddCheckbox("vNavMM_WorkbenchCopy ", "Workbench Copy")
    myGui.AddCheckbox("vNavMM_Koppeling ", "Koppeling")
    myGui.AddCheckbox("vNavMM_Electr_drw ", "Electrical drawing")
    myGui.AddCheckbox("vNavMM_Eplan_drw ", "Eplan drawing")
    myGui.AddText("xs+12 yp+30", "Language")
    myGui.Add("DropDownList", "vNavMM_Language yp x" Window.Width - 20 - 100 " w100 ", ["Dutch", "English"])

    Tab.UseTab(3)
    myGui.AddGroupBox("w"  Window.Width-37 " r4", "Menu Options")
    myGui.AddCheckbox("xp+8 yp+18 vNavMM_CommonSpace", "Common Space")
    myGui.AddCheckbox("vNavMM_CreoView ", "Creo View")
    myGui.AddCheckbox("vCreoMM_ExportTree", "Export Tree")
    myGui.AddCheckbox("vNavMM_IPrint", "Iprint")

    myGui.AddCheckbox("y+24 vCreo_disableNavImport", "Disable Navision Import")

    ; Test for remaining controls
    Tab.UseTab(4)
    myGui.AddEdit("vTestEdit r2 w200")
    myGui.AddRadio("vTestRadio", "Radio1")
    myGui.AddRadio(, "Radio2")
    myGui.AddListBox("vTestListBox", ["Red", "Green", "Blue", "Black", "White"] )
    myGui.AddSlider("vTestSlider")
    myGui.AddDateTime("vTestDateTime")
    myGui.AddMonthCal("vTestMonthCal")
    myGui.AddHotkey("vTestHotkey")

    ; Adding the standard buttons OK, Cancel & Apply
    Tab.UseTab()
    ogcvButtonOK := myGui.Add("Button", "x" Window.Width - 8 * 3 - 70 * 3 " y" Window.Height - 30 " w70 vButtonOK ", "OK")
    ogcvButtonOK.OnEvent("Click", gApply.Bind("Destroy"))
    ogcvButtonCancel := myGui.Add("Button", "xp+78 yp w70 vButtonCancel ", "Cancel")
    ogcvButtonCancel.OnEvent("Click", gExit)
    
    ogcvButtonApply := myGui.Add("Button", "xp+78 yp w70 vButtonApply Disabled", "Apply")
    ogcvButtonApply.OnEvent("Click", gApply.Bind(""))
    

    LoadSettings(oSettings)
;DllCall("uxtheme\SetWindowTheme", "ptr", myGui.hwnd, "str", "DarkMode_Explorer", "ptr", 0)
    myGui.Show(" w" Window.Width " h" Window.Height)
    Return

    ;Loads settings from the object
    LoadSettings(oSettings1){
        
        ; Set a reference to the Section (Keys must be unique!, if not, please add a property .Section to the control, the name will be used as the key)
        oSection := Map()
        For Section, SubObject in oSettings1.OwnProps() {
            For Key, Value in SubObject.OwnProps() {
                oSection[StrLower(Key)] := Section
            }
        }
        
        ; Loading the values based on the Object
        For Hwnd, GuiCtrlObj in MyGui{
            
            if (GuiCtrlObj.Type="Button"){
                DllCall("uxtheme\SetWindowTheme", "ptr", GuiCtrlObj.hwnd, "str", "DarkMode_Explorer", "ptr", 0)
            }

            key := GuiCtrlObj.HasOwnProp("key") ? GuiCtrlObj.key : GuiCtrlObj.Name
            if (GuiCtrlObj.Type = "Radio" and key = "" and GuiCtrlObj_Prev.Type= "Radio") {
                ; Keys of radio controls will be copied from the previous radio control if no name
                key := GuiCtrlObj_Prev.HasOwnProp("key") ? GuiCtrlObj_Prev.key : GuiCtrlObj_Prev.Name
            }
    
            Section := GuiCtrlObj.HasOwnProp("section") ? GuiCtrlObj.section : oSection.Has(StrLower(key)) ? oSection[StrLower(Key)] : ""
    
            if (Section !="" and key != ""){
                if oSettings1.HasOwnProp(Section) and oSettings1.%Section%.HasOwnProp(Key){
                    KeyValue := oSettings1.%Section%.%Key%
                }
    
                ; Add a Section and Key property to the Gui control object
                GuiCtrlObj.Section := Section
                GuiCtrlObj.Key := key
    
                ; Setting the values of the control
                if (GuiCtrlObj.Type ~= "^(?i:ComboBox|DDL|Edit|ListBox)$"){
                    GuiCtrlObj.Text := KeyValue
                    GuiCtrlObj.OnEvent("Change", gEdit)
                }
                else if (GuiCtrlObj.Type ~= "^(?i:DateTime|Hotkey|MonthCal|Slider)$") {
                    GuiCtrlObj.Value := KeyValue
                    GuiCtrlObj.OnEvent("Change", gEdit)
                }
                else if (GuiCtrlObj.Type = "Checkbox") {
                    GuiCtrlObj.Value := KeyValue = "true" ? 1 : 0
                    GuiCtrlObj.OnEvent("Click", gEdit)
                }
                else if (GuiCtrlObj.Type = "Radio") {
                    GuiCtrlObj.Value := KeyValue = GuiCtrlObj.Text ? 1 : 0
                    GuiCtrlObj.OnEvent("Click", gEdit)
                }
                else{
                    MsgBox("Error`nControl had no settings: `nname: " GuiCtrlObj.name "`nType: " GuiCtrlObj.type)
                }
            }
            else{
                if (GuiCtrlObj.Type ~= "^(?i:Checkbox|ComboBox|DateTime|DDL|Edit|Hotkey|ListBox|MonthCal|Slider)$"){
                    MsgBox("Error`nControl had no settings: `nname: " GuiCtrlObj.name "`nType: " GuiCtrlObj.type)
                }
            }
            GuiCtrlObj_Prev := GuiCtrlObj
        }
        return
    }

    ; Saves the Settings to the Ini file.
    gApply(Mode, GuiCtrlObj, Info, *){ 

        For Hwnd, GuiCtrlObj in GuiCtrlObj.Gui {

            if (GuiCtrlObj.HasOwnProp("Section")){
                KeyValue := GuiCtrlObj.Text
                if (GuiCtrlObj.Type ~= "^(?i:DateTime|Hotkey|MonthCal|Slider)$") {
                    KeyValue := GuiCtrlObj.Value
                }
                if (GuiCtrlObj.Type = "Radio"){
                    if GuiCtrlObj.Value = 0 {
                        continue
                    }
                }
                if (GuiCtrlObj.Type = "Checkbox"){
                    KeyValue := GuiCtrlObj.Value = 1 ? "true" : "false"
                }

                ; Saves the settings in the ini file and global variable oSettings
                IniWrite(KeyValue , GuiCtrlObj.Gui.iniFile, GuiCtrlObj.Section, GuiCtrlObj.Key)
                Section := GuiCtrlObj.Section
                Key := GuiCtrlObj.Key
                if !oSettings.HasOwnProp(Section) {
                    oSettings.%Section% := []
                }
                oSettings.%Section%.%Key% := KeyValue
            }
        }
        
        if (Mode="Destroy"){
            GuiCtrlObj.Gui.Destroy()
            Reload ; Just for testing, Reload may be removed
        }
        ogcvButtonApply.Enabled := False
        Return
    }

    gEdit(GuiCtrlObj, Info, *){ ; Detects a change and enables the Apply button
        ogcvButtonApply.Enabled := true
    Return
    }

    gExit(*){ ; Exit without saving the changes
        myGui.Destroy()
        ExitApp ; Just for testing, Reload may be removed
        return
    }
}

;-------------------------------------------------------------------------------
WriteINI(&Array2D, INI_File) {	; write 2D-array to INI-file
    ;-------------------------------------------------------------------------------
    for SectionName, Entry in Array2D {
        Pairs := ""
        for Key, Value in Entry
            Pairs .= Key "=" Value "`n"
        IniWrite(Pairs, INI_File, SectionName)
    }
}

;-------------------------------------------------------------------------------
ReadINI(INI_File, oResult := "") {	; return 2D-array from INI-file
    oResult := IsObject(oResult) ? oResult : []
    oResult.Section := []
    SectionNames := IniRead(INI_File)
    for each, Section in StrSplit(SectionNames, "`n") {
        OutputVar_Section := IniRead(INI_File, Section)
        if !oResult.HasOwnProp(Section){
            oResult.%Section% := []
        }
        for each, Haystack in StrSplit(OutputVar_Section, "`n"){
            RegExMatch(Haystack, "(.*?)=(.*)", &match)
            ArrayProperty := match[1]
            oResult.%Section%.%ArrayProperty% := match[2]
        }
    }
    return oResult
}
2021-10-24 09_46_06-Settings.png
2021-10-24 09_46_06-Settings.png (13.24 KiB) Viewed 1859 times
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: [V2-beta] - Example Gui Set Settings & Ini file

24 Oct 2021, 02:59

Update of first post:
- Changed buttons to dark theme
- Added support for the Hotkey controls

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: doodles333, kunkel321 and 34 guests