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
}