; VisualINI - by Titan (with thanks to Chris for StatusBar and Minimum Window Size function) v = 1.1 #SingleInstance ignore #NoTrayIcon WelcomeMsg = ( Welcome to VisualINI! Version %v% Coded by Titan with thanks to Chris for a few functions. This program can manipulate basic INI setting files. To start, simply click the 'Open' button to open an INI file to edit or create a new one by pressing 'New'. This script and the code is under the Creative Commons Attribution license which can be found at http://creativecommons.org/licenses/by/2.5/legalcode (or http://creativecommons.org/licenses/by/2.5/). For help with this script, see the forums. ) Gui, +Resize Gui, Add, Text, Section, VisualINI allows you to edit INI files with a GUI. Gui, Font, underlined Gui, Add, Text, Section xm ys+20 vFileINI_DisL, Editing file: Gui, Font, Norm Gui, Add, Edit, vFileINI_Dis xs+60 ys w315 r1 ReadOnly -Multi -E0x200 0x400, (none) Gui, Font Gui, Add, Button, vNew x445 y10 w45 gNew, New Gui, Add, Button, vOpen x495 y10 w45 gOpen, Open Gui, Add, Button, vSave x545 y10 w45 gSave, Save Gui, Add, Button, vClose x595 y10 w45 gClose, Close Gui, Add, ListView, vListV xm y55 w630 h200 Grid NoSort -ReadOnly gListControl AltSubmit, Entity|Value Gui, Add, Edit, vListHV xm y55 w630 h250 ReadOnly, % WelcomeMsg Gui, Add, Checkbox, vShowGrid x575 y265 gShowGrid Checked, Show grid Gui, Add, Button, vDelRow x570 y290 gDelRow, Delete Row Gui, Add, Button, vAddSection xm y265 w85 gAddSec, Add Section Gui, Add, Button, vAddKey xm y290 w85 gAddVal, Add Key/Value Gui, Add, Text, vDataTypeL x125 y265 w60, Data type: Gui, Add, Radio, vDataTypeSec x180 y265 w60 gDTSec, Section Gui, Add, Radio, vDataTypeKey x240 y265 w70 gDTKey, Key/Value Gui, Add, Text, vValL x125 y290 w40, Value: Gui, Add, Edit, vVal x165 y290 h18 w350 ReadOnly Gui, Add, Button, vValCh x520 y290 h18 gChangeVal, ~ GuiControl, Focus, Static1 Screen("edit") iW := 650 iH := 350 ; ----- If a file was passed in on launch, open it if 0 != 0 { ; ----- Replace colon (from C:\) as it is an illegal character for variables. StringReplace, FileIn,1, :, ?, All Open( FileIn) } ; ----- Gui, Show, w%iW% h%iH%, VisualINI Gui, Add, Text, vStatusPlaceholder xm GuiControl, Hide, StatusPlaceholder Gui, +LastFound BarHWND := DllCall("CreateStatusWindow", int, 0x50000000, str, "Welcome to VisualINI", UInt, WinExist(), UInt, 5555) WinGetPos, , , tW, tH OnMessage(0x24, "WM_GETMINMAXINFO") SetTimer, Cycle Return Cycle: ListControl: LV_GetText(t, LV_GetNext(-1, "F"), 2) GuiControl, , Val, % t If (LV_GetNext(-1, "F") = 0) t1 = Disable else t1 = Enable t = DelRow,ValCh,DataTypeSec,DataTypeKey Loop, Parse, t, `, GuiControl, % t1, % A_LoopField LV_GetText(t, LV_GetNext(-1, "F"), 1) If IsSec(t) { GuiControl, , DataTypeSec , 1 GuiControl, Disable, ValCh } else { GuiControl, , DataTypeKey , 1 GuiControl, Enable, ValCh } Return DTSec: LV_GetText(t, LV_GetNext(-1, "F"), 1) LV_Modify(LV_GetNext(-1, "F"), "", "[" . t . "]", "") Status("Key changed to section") Return DTKey: LV_GetText(t, LV_GetNext(-1, "F"), 1) StringTrimLeft, t, t, 1 StringTrimRight, t, t, 1 LV_Modify(LV_GetNext(-1, "F"), "", t) Status("Section changed to key") Return ChangeVal: Gui, +OwnDialogs InputBox, t, Change value, What would you like to change the value of the selected INI key? Enter text below (or leave blank) and press OK., , 350, 150 LV_GetText(t1, LV_GetNext(-1, "F"), 1) LV_Modify(LV_GetNext(-1, "F"), "Select Focus", t1, t) Status("Value changed") Return ShowGrid: ShowGrid_t := !ShowGrid_t If ShowGrid_t GuiControl, -Grid, ListV Else GuiControl, +Grid, ListV Status("Grid option toggled") Return AddSec: AddRow("sec") Return AddVal: AddRow("val") Return DelRow: DelRow() Return New: New() Return Open: Open() Return Save: Save() Return Close: Close() Return GuiSize: LV_ModifyCol() SendMessage, 5, 0, 0, , ahk_id %BarHWND% Anchor("FileINI_Dis", "w", 0, 0, 315) Anchor("ListV", "wh", 0, 0, 630, 200) Anchor("ListHV", "wh", 0, 0, 630, 250) Anchor("New", "x", 445) Anchor("Open", "x", 495) Anchor("Save", "x", 545) Anchor("Close", "x", 595) Anchor("ShowGrid", "xy", 575, 265) Anchor("DelRow", "xy", 570, 290) Anchor("AddSection", "y", 0, 265) Anchor("AddKey", "y", 0, 290) Anchor("DataTypeL", "y", 0, 265) Anchor("DataTypeSec", "y", 0, 265) Anchor("DataTypeKey", "y", 0, 265) Anchor("ValL", "y", 0, 290) Anchor("Val", "yw", 0, 290, 350) Anchor("ValCh", "xy", 520, 290) Return New() { global FileINI Status("Creating data structure...") LV_Delete() FileINI = ; LV_Add("", "[Section]") LV_Add("", "Example-Key", "Example Value...") LV_ModifyCol() Screen("list") Status("New INI created from base template") } Open(FileIn = "" ) { global FileINI FileINI := FileIn Status("Requesting file...") Gui, +OwnDialogs ; ----- Return colon if FileIn was passed a value. ; ----- SelectFile if no value was passed. If FileINI { StringReplace, FileINI, FileINI, ?, :, All } Else { FileSelectFile, FileINI, 3, %A_MyDocuments%, VisualINI - Select an INI File..., Settings File (*.ini; *inf; *.txt) If (not FileINI) { Status("Cancelled") Return } } Status("Reading file...") LV_Delete() FileRead, contents, % FileINI StringReplace, contents, contents, `r, , 1 Loop, Parse, contents, `n { StringLeft, s, A_LoopField, 1 StringRight, f, A_LoopField, 1 If ((s = "[") and (f = "]")) { If pre_br LV_Add() LV_Add("", A_LoopField) pre_br := true } Else If A_LoopField contains = { StringLeft, e, A_LoopField, % InStr(A_LoopField, "=") - 1 StringRight, v, A_LoopField, % StrLen(A_LoopField) - InStr(A_LoopField, "=") LV_Add("", e, v) } } LV_ModifyCol() GuiControl, , FileINI_Dis, % FileINI Screen("list") Status("File opened") } Save() { global FileINI Status("Saving file...") If FileINI { MsgBox, 68, Overwrite?, Do you wish to overwrite the current file:`n`n%FileINI% IfMsgBox, No FileSelectFile, FileINI, S18, %A_MyDocuments%\Settings-%A_Now%, Save INI file as..., INI Settings File (*.ini) } If (not FileINI) FileSelectFile, FileINI, S18, %A_MyDocuments%\Settings-%A_Now%, Save INI file as..., INI Settings File (*.ini) If (not FileINI) Return StringRight, t, FileINI, 4 If (t != ".ini") FileINI := FileINI . ".ini" FileDelete, % FileINI Loop, % LV_GetCount() { LV_GetText(t, A_Index, 1) If (not t) { f := f . "`n" Continue } If IsSec(t) f := f . t . "`n" Else { LV_GetText(t1, A_Index, 2) f := f . t . "=" . t1 . "`n" } } StringReplace, f, f, `r, , 1 StringReplace, f, f, `n, `r`n, 1 FileAppend, % f, % FileINI GuiControl, , FileINI_Dis, % FileINI Status("File saved sucessfully") } Close() { global FileINI Status("Closing file...") GuiControl, , FileINI_Dis, (none) FileINI = ; LV_Delete() Screen("edit") Status("File closed") } IsSec(str) { StringLeft, t, str, 1 StringRight, t1, str, 1 If (t = "[" and t1 = "]") Return, % true else Return, % false } DelRow() { LV_Delete(LV_GetNext(-1, "F")) Status("Deleted row") } AddRow(type) { If (type = "sec") t1 = section else If (type = "val") { t1 = value t2 = You can change the value later by clicking the '~' button. } Gui, +OwnDialogs InputBox, t, Add %t1%, Please type the name of the %t1% you wish to add then press OK. %t2%, , 350, 150 If ErrorLevel Return If (type = "sec") { LV_Add() LV_Add("Select Focus", "[" . t . "]") } else If (type = "val") LV_Add("Select Focus", t) Status("Added row: '" . t . "'") } Screen(type) { If (type = "edit") { i = Show in = Hide GuiControl, Disable, Save GuiControl, Disable, Close } Else If (type = "list") { i = Hide in = Show GuiControl, Enable, Save GuiControl, Enable, Close } GuiControl, % i, ListHV list = ListV,ShowGrid,AddSection,AddKey,DataTypeL,DataTypeSec,DataTypeKey,ValL,Val,DelRow,ValCh Loop, Parse, list, `, GuiControl, % in, % A_LoopField } Status(txt=0) { Gui, +LastFound If (not txt) txt = Done ControlSetText, msctls_statusbar321, % txt } Anchor(Control, Anchors="", x=0, y=0, w=0, h=0) { global iW, iH If (not Anchors) Anchors = xy If Anchors contains x GuiControl, Move, % Control, % "x" x+(A_GuiWidth-iW) If Anchors contains y GuiControl, Move, % Control, % "y" y+(A_GuiHeight-iH) If Anchors contains w GuiControl, Move, % Control, % "w" w+(A_GuiWidth-iW) If Anchors contains h GuiControl, Move, % Control, % "h" h+(A_GuiHeight-iH) } WM_GETMINMAXINFO(wParam, lParam) { global tW,tH If (not A_Gui) Return InsertIntegerAtAddress(tW, lParam, 24, 4) InsertIntegerAtAddress(tH, lParam, 28, 4) Return 0 } InsertIntegerAtAddress(pInteger, pAddress, pOffset = 0, pSize = 4) { mask := 0xFF Loop %pSize% { DllCall("RtlFillMemory", UInt, pAddress + pOffset + A_Index - 1, UInt, 1, UChar, (pInteger & mask) >> 8 * (A_Index - 1)) mask := mask << 8 } } Exit: GuiClose: ExitApp