Page 1 of 1

Special folder paths in configuration files

Posted: Sun Nov 10, 2019 2:12 pm
by Lincon
Hello everyone,,
I've got a configuration file for an application that needs to store a path. I can store a fixed path easily enough, such as "C:\foo\bar". However, I'd like to make it able to handle special paths. Easy enough for some things, as I can include a call to ExpandEnvironmentStrings_() so my paths can be written as "%systemdrive%\foo\bar".

However, the only user relative special folder path that seems to be exposed is %USERPROFILE% or %ALLUSERSPROFILE%. Ideally I'd like to be able to specify anything that changes with the OS or language (e.g. the desktop folder isn't always "%USERPROFILE%\Desktop" - or is it?), but there doesn't seem to be a standard way to do it. I don't want to have to add environment variables to the system, and I don't particularly want to have my own special environment variables that I parse first.

It also needs to look like a standard path if possible, something that you'd type on the command line.

Has anyone come across such a thing or am I going to have to go down the custom path string route?

Thanks.

Re: Special folder paths in configuration files

Posted: Sun Nov 10, 2019 2:33 pm
by mk-soft
You should always put it there what the OS recommends.

So always for user dependent data 'GetUserDirectory(#PB_Directory_ProgramData)'.

However, you should still create subfolders in these folders, since all programs in this folder also create their own subfolders.

So folder of creator 'CompanyName' and in this folder a folder for the application 'ApplicationName'.

Wrote here for me some ready-made routines...

Update v0.2

Code: Select all

;-TOP ProgramData, by mk-soft, v0.2

EnableExplicit

#CompanyName = "mk-soft"
#ApplicationName = "MyApp"

Structure udtWindowPosition
  x.i
  y.i
  w.i
  h.i
  state.i
EndStructure

Structure udtProgramData
  LastPath.s
  List LastFiles.s()
  Window.udtWindowPosition
EndStructure

Global ProgramData.udtProgramData

; ----

Enumeration
  #MainWindow
EndEnumeration

; ----

Procedure DefaultWindowPosition()
  With ProgramData
    \Window\x = #PB_Ignore
    \Window\y = #PB_Ignore
    \Window\w = 800
    \Window\h = 600
  EndWith
  
EndProcedure

; ----

Procedure CheckWindowPosition()
  Protected cnt, i 
  With ProgramData\Window
    cnt = ExamineDesktops()
    For i = 0 To cnt - 1
      If \x >= DesktopX(i) And \x < DesktopX(i) + DesktopWidth(i)
        If \y >= DesktopY(i) And \y < DesktopY(i) + DesktopHeight(i)
          If \x - DesktopX(i) + \w <= DesktopWidth(i) And \y - DesktopY(i) + \h <= DesktopHeight(i)
            ProcedureReturn #True
          EndIf
        EndIf
      EndIf
    Next
  EndWith
  ProcedureReturn #False
EndProcedure

; ----

Procedure GetWindowPosition(state)
  With ProgramData\Window
    \x = WindowX(#MainWindow)
    \y = WindowY(#MainWindow)
    \w = WindowWidth(#MainWindow)
    \h = WindowHeight(#MainWindow)
    \state = state
  EndWith
EndProcedure
    
; ----

Procedure LoadProgramData(FileName.s = "ProgramData.xml")
  Protected basepath.s, subpath.s, datapath.s, filepath.s, xml
  
  basepath = GetUserDirectory(#PB_Directory_ProgramData)
  subpath = basepath + #CompanyName + #PS$
  datapath = subpath  + #ApplicationName + #PS$
  
  filepath = datapath + FileName
  If FileSize(filepath) > 0
    xml = LoadXML(#PB_Any, filepath)
    If xml And XMLStatus(xml) = #PB_XML_Success
      ExtractXMLStructure(MainXMLNode(xml), @ProgramData, udtProgramData, #PB_XML_NoCase)
      FreeXML(xml)
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

; ----

Procedure SaveProgramData(FileName.s = "ProgramData.xml")
  Protected basepath.s, subpath.s, datapath.s, filepath.s, xml
  
  basepath = GetUserDirectory(#PB_Directory_ProgramData)
  subpath = basepath + #CompanyName + #PS$
  datapath = subpath  + #ApplicationName + #PS$
  
  If FileSize(datapath) <> -2
    If FileSize(subpath) <> -2
      CreateDirectory(subpath)
    EndIf
    If FileSize(datapath) <> -2
      CreateDirectory(datapath)
    EndIf
  EndIf
  
  filepath = datapath + FileName
  xml = CreateXML(#PB_Any)
  If xml
    If InsertXMLStructure(RootXMLNode(xml), @ProgramData, udtProgramData)
      FormatXML(xml, #PB_XML_ReFormat)
      SaveXML(xml, filepath)
    EndIf
  EndIf

EndProcedure

; ----

Procedure Main()
  Protected state
  
  If Not LoadProgramData()
    DefaultWindowPosition()
  EndIf
  
  If Not CheckWindowPosition()
    DefaultWindowPosition()
  EndIf
  
  With ProgramData\Window
    OpenWindow(#MainWindow, \x, \y, \w, \h, "", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)
    SetWindowState(#MainWindow, \state)
  EndWith
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
    EndSelect
  ForEver
  
  state = GetWindowState(#MainWindow)
  If state = #PB_Window_Maximize Or #PB_Window_Minimize
    SetWindowState(#MainWindow, #PB_Window_Normal)
  EndIf
  
  GetWindowPosition(state)
  SaveProgramData()
  
EndProcedure : Main()