Just a little ini file viewer with ability to sort and save section keys. See comments.
Update: Code by by George Bleck for enhanced sorting if key ends with number implemented in Function GetIniSectionKeys.
A discussion exist at https://forum.powerbasic.com/forum/u...ile#post826725

'
Update: Code by by George Bleck for enhanced sorting if key ends with number implemented in Function GetIniSectionKeys.
A discussion exist at https://forum.powerbasic.com/forum/u...ile#post826725
'
Code:
'====================================================================== ' Simple ini file viewer with option to view and save section keys in ' sorted order. From an old idea by Gary Beene - use with care! ' Note - Keys textbox has %ES_READONLY style for safety reason. Change ' if you like. No update after save, to enable return to original keys. ' Public Domain, of course, by Borje Hagsten. 19 Sep 2023. ' 19 Sep 2023 - Code by by George Bleck for enhanced sorting if key ends ' with number implemented in Function GetIniSectionKeys. '-------------------------------------------------------------------- #COMPILE EXE #DIM ALL '-------------------------------------------------------------------- %UNICODE = 1 ' if 0, replace WSTRING with STRING ' same as above, if to compile with PB9. #INCLUDE "WIN32API.INC" '-------------------------------------------------------------------- %IDC_LABEL1 = 101 %IDC_LABEL2 = 102 %IDC_BTNOPEN = 121 %IDC_BTNSAVE = 122 %IDC_CHECK1 = 131 %IDC_CHECK2 = 132 %IDC_TEXTBOX1 = 141 %IDC_LISTBOX1 = 151 GLOBAL wsKey() AS WSTRING GLOBAL wsSortKey() AS WSTRING GLOBAL wsSections() AS WSTRING '====================================================================== FUNCTION PBMAIN () AS LONG LOCAL hDlg, nFont AS DWORD DIALOG NEW 0, "IniView",,, 386, 182, %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX, 0 TO hDlg DIALOG SET COLOR hDlg, -1, %LTGRAY '------------------------------------------------------------------ CONTROL ADD LABEL, hDlg, %IDC_LABEL1, "Sections", 5, 1, 50, 10 CONTROL ADD LABEL, hDlg, %IDC_LABEL2, "Keys", 95, 1, 50, 10 CONTROL ADD LISTBOX, hDlg, %IDC_LISTBOX1, , 5, 10, 85, 150, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %LBS_NOTIFY OR _ %LBS_NOINTEGRALHEIGHT OR %WS_VSCROLL, %WS_EX_CLIENTEDGE CONTROL ADD TEXTBOX, hDlg, %IDC_TEXTBOX1, "", 95, 10, 285, 150, _ %WS_CHILD OR %WS_VISIBLE OR %WS_VSCROLL OR %WS_HSCROLL OR _ %ES_MULTILINE OR %ES_WANTRETURN OR %ES_READONLY, %WS_EX_CLIENTEDGE CONTROL ADD CHECKBOX, hDlg, %IDC_CHECK2, "Custom colors", 96, 163, 60, 14 CONTROL ADD CHECKBOX, hDlg, %IDC_CHECK1, "Sorted &keys", 160, 163, 60, 14 ' CONTROL SET CHECK hDlg, %IDC_CHECK1, 1 CONTROL SET CHECK hDlg, %IDC_CHECK2, 1 CONTROL ADD BUTTON, hDlg, %IDC_BTNOPEN, "&Open Ini", 222, 164, 50, 14 CONTROL ADD BUTTON, hDlg, %IDC_BTNSAVE, "&Save Keys", 276, 164, 50, 14 CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Quit", 330, 164, 50, 14 CONTROL DISABLE hDlg, %IDC_BTNSAVE '------------------------------------------------------------------- CONTROL SET COLOR hDlg, %IDC_LABEL1, -1, %LTGRAY ' play with colors and font.. CONTROL SET COLOR hDlg, %IDC_LABEL2, -1, %LTGRAY CONTROL SET COLOR hDlg, %IDC_CHECK1, -1, %LTGRAY CONTROL SET COLOR hDlg, %IDC_CHECK2, -1, %LTGRAY CONTROL SET COLOR hDlg, %IDC_LISTBOX1, %YELLOW, %RGB_DARKRED CONTROL SET COLOR hDlg, %IDC_TEXTBOX1, %YELLOW, %RGB_DARKRED FONT NEW "Arial", 9, 0 TO nFont CONTROL SET FONT hDlg, %IDC_LISTBOX1, nFont CONTROL SET FONT hDlg, %IDC_TEXTBOX1, nFont '------------------------------------------------------------------- DIALOG SHOW MODAL hDlg, CALL DlgProc END FUNCTION '====================================================================== CALLBACK FUNCTION DlgProc() AS LONG LOCAL dwStyle AS DWORD, c AS LONG, wsTxt AS WSTRING STATIC wsSection, wsFile AS WSTRING SELECT CASE CB.MSG CASE %WM_INITDIALOG CASE %WM_COMMAND SELECT CASE CB.CTL CASE %IDC_LISTBOX1 IF CB.CTLMSG = %LBN_SELCHANGE THEN ' on selection change, show seleted section's keys LISTBOX GET TEXT CB.HNDL, %IDC_LISTBOX1 TO wsSection GetIniSectionKeys CB.HNDL, %IDC_TEXTBOX1, wsSection, wsFile DIALOG SEND CB.HNDL, %WM_COMMAND, MAK(LONG, %IDC_CHECK1, %BN_CLICKED), 0 ' trigger %IDC_CHECK1 END IF CASE %IDC_CHECK1 ' set sorted or original order IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN CONTROL GET CHECK CB.HNDL, %IDC_CHECK1 TO c IF c THEN ' then sorted array CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, JOIN$(wsSortKey(), $CRLF) ELSE CONTROL SET TEXT CB.HNDL, %IDC_TEXTBOX1, JOIN$(wsKey(), $CRLF) END IF IF UBOUND(wsKey) > -1 THEN CONTROL ENABLE CB.HNDL, %IDC_BTNSAVE END IF CASE %IDC_CHECK2 ' set sorted or original order IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN CONTROL GET CHECK CB.HNDL, %IDC_CHECK2 TO c IF c THEN ' then sorted array CONTROL SET COLOR CB.HNDL, %IDC_LISTBOX1, %YELLOW, %RGB_DARKRED CONTROL SET COLOR CB.HNDL, %IDC_TEXTBOX1, %YELLOW, %RGB_DARKRED ELSE CONTROL SET COLOR CB.HNDL, %IDC_LISTBOX1, -1, -1 CONTROL SET COLOR CB.HNDL, %IDC_TEXTBOX1, -1, -1 END IF CONTROL REDRAW CB.HNDL, %IDC_LISTBOX1 CONTROL REDRAW CB.HNDL, %IDC_TEXTBOX1 END IF CASE %IDC_BTNOPEN ' open ini file, scan section names and trigger %IDC_CHECK1 action IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN dwStyle = %OFN_EXPLORER OR %OFN_PATHMUSTEXIST OR %OFN_HIDEREADONLY OR %OFN_ENABLESIZING DISPLAY OPENFILE CB.HNDL, , , "", CURDIR$, _ CHR$("Ini Files", 0, "*.ini", 0, "All Files", 0, "*.*", 0), _ "", "ini", dwStyle TO wsFile IF LEN(wsFile) THEN DIALOG SET TEXT CB.HNDL, "IniView - " + wsFile GetIniSectionNames(CB.HNDL, %IDC_LISTBOX1, wsFile) LISTBOX GET COUNT CB.HNDL, %IDC_LISTBOX1 TO c IF c THEN LISTBOX SELECT CB.HNDL, %IDC_LISTBOX1, 1 LISTBOX GET TEXT CB.HNDL, %IDC_LISTBOX1, 1 TO wsSection GetIniSectionKeys CB.HNDL, %IDC_TEXTBOX1, wsSection, wsFile DIALOG SEND CB.HNDL, %WM_COMMAND, MAK(LONG, %IDC_CHECK1, %BN_CLICKED), 0 END IF END IF END IF CASE %IDC_BTNSAVE ' Save selected keys to ini file IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN CONTROL GET TEXT CB.HNDL, %IDC_TEXTBOX1 TO wsTxt ' grab current textbox text wsTxt = wsTxt + CHR$(0) ' add a 0 to clip string WritePrivateProfileSection (BYCOPY wsSection, BYVAL STRPTR(wsTxt), BYCOPY wsFile) END IF CASE %IDCANCEL ' exit also on Esc key IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN DIALOG END CB.HNDL, 0 END IF END SELECT END SELECT END FUNCTION '====================================================================== ' Get ini file section names to global arrays '---------------------------------------------------------------------- FUNCTION GetIniSectionNames(BYVAL hDlg AS LONG, BYVAL cId AS LONG, _ BYVAL wsFile AS WSTRING) AS LONG LOCAL c AS LONG, wsTxt AS WSTRING wsTxt = SPACE$(32000)' should be enough for section names c = GetPrivateProfileSectionNames (BYVAL STRPTR(wsTxt), LEN(wsTxt), BYCOPY wsFile) wsTxt = LEFT$(wsTxt, c) ' c is number of characters copied to the buffer c = TALLY(wsTxt, CHR$(0)) ' count keys IF c THEN ' if any REDIM wsSections(c-1) ' dimension global arrays PARSE wsTxt, wsSections(), CHR$(0) ' grab section names LISTBOX RESET hDlg, cId ' add names to listbox FOR c = 0 TO UBOUND(wsSections) LISTBOX ADD hDlg, cId, wsSections(c) NEXT END IF END FUNCTION '====================================================================== ' Get ini file keys under section name to global arrays '---------------------------------------------------------------------- FUNCTION GetIniSectionKeys(BYVAL hDlg AS LONG, BYVAL cId AS LONG, _ BYVAL wsSection AS WSTRING, _ BYVAL wsFile AS WSTRING) AS LONG LOCAL c AS LONG, wsTxt AS WSTRING wsTxt = SPACE$(65000) ' should be enough c = GetPrivateProfileSection (BYCOPY wsSection, BYVAL STRPTR(wsTxt), LEN(wsTxt), BYCOPY wsFile) wsTxt = LEFT$(wsTxt, c) ' c is number of characters copied to the buffer c = TALLY(wsTxt, CHR$(0)) ' count keys IF c THEN ' if any REDIM wsKey(c-1), wsSortKey(c-1) ' dimension global arrays PARSE wsTxt, wsKey(), CHR$(0) ' for original key order PARSE wsTxt, wsSortKey(), CHR$(0) ' for sorted keys '--------------------------------------------------------------------- ' enhanced sorting if key ends with number by George Bleck implemented '--------------------------------------------------------------------- LOCAL v_strKey, v_strWord AS WSTRING FOR c = 0 TO UBOUND(wsSortKey) v_strKey = PARSE$(wsSortKey(c),"=",1) IF RTRIM$(v_strKey, ANY "0123456789") <> v_strKey THEN v_strWord = RTRIM$(v_strKey, ANY "0123456789") v_strKey = v_strWord + RIGHT$(STRING$(128, CHR$(1)) + MID$(v_strKey, LEN(v_strWord) + 1), 128) wsSortKey(c) = v_strKey + MID$(wsSortKey(c), INSTR(wsSortKey(c), "=")) END IF NEXT ARRAY SORT wsSortKey(), COLLATE UCASE ' now we can sort formatted items FOR c = 0 TO UBOUND(wsSortKey) ' and remove fill character for viewing purpose wsSortKey(c) = REMOVE$(wsSortKey(c), CHR$(1)) NEXT '--------------------------------------------------------------------- ELSE REDIM wsKey(0), wsSortKey(0) ' if no keys END IF END FUNCTION '
Comment