Page 2 of 2

Posted: Mon Aug 06, 2007 11:34 pm
by Rescator
You might find these pretty useful.

Code: Select all

Procedure.s GetKeyValue(topKey.l,sKey$,sValue$)
 Protected lType.l,lpcbData.l,hKey.l,lpData$,path$
 lpData$=Space(2048+1)
 lpcbData=Len(lpData$)-1
 If RegOpenKeyEx_(topKey,sKey$,#Null,#KEY_READ,@hKey)=#ERROR_SUCCESS
  RegQueryValueEx_(hKey,sValue$,#Null,@lType,@lpData$,@lpcbData)
  RegCloseKey_(hKey)
 EndIf
 ProcedureReturn Trim(lpData$)
EndProcedure

Procedure.s SpecialFolderLocation(csidl.l)
 Protected location$,pidl.l
 If SHGetSpecialFolderLocation_(#Null,csidl,@pidl)=#ERROR_SUCCESS
  location$=Space(#MAX_PATH)
  If SHGetPathFromIDList_(pidl,@location$)
   If Right(location$,1)<>"\"
    location$+"\"
   EndIf
  EndIf
  If pidl
   CoTaskMemFree_(pidl) ;Instead of messing with com imalloc free and whatnot.
  EndIf
 EndIf
 ProcedureReturn Trim(location$)
EndProcedure

Procedure.s GetProgramFilesDir()
 Protected os.l,value$,path$
 os=OSVersion()
 If os>#PB_OS_Windows_ME
  path$=SpecialFolderLocation(#CSIDL_PROGRAM_FILES)
 Else
  value$=GetKeyValue(#HKEY_LOCAL_MACHINE,"Software\Microsoft\Windows\Currentversion","ProgramFilesDir")
  If value$<>""
   path$=value$
   If Right(value$,1)<>"\"
    path$+"\"
   EndIf
  EndIf
 EndIf
 If FileSize(path$)<>-2
  If CreateDirectory(path$)=#False
   path$=""
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure

Procedure.s GetApplicationDataDirectory()
 Protected path$
 path$=SpecialFolderLocation(#CSIDL_APPDATA)
 If path$="" ;Needed since Windows 95 do not support CSIDL_APPDATA "out of the box".
  path$=GetProgramFilesDir()+"Application Data\"
 EndIf
 If FileSize(path$)<>-2
  If CreateDirectory(path$)=#False
   path$=""
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure

Procedure.s GetMyDocumentsDirectory()
 Protected path$
 path$=SpecialFolderLocation(#CSIDL_PERSONAL) ;My Documents\ folder, use this rather than the other CSIDL
 If FileSize(path$)<>-2
  If CreateDirectory(path$)=#False
   path$=""
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure

Procedure.s GetTempDirectory()
 Protected path$,pathlen.l,result.l
 path$=Space(2048+1)
 result=GetTempPath_(Len(path$)-1,@path$)
 If (result=0) Or (result>Len(path$))
  path$=""
 Else
  If Right(path$,1)<>"\"
   path$+"\"
  EndIf
  If FileSize(path$)<>-2
   If CreateDirectory(path$)=#False
    path$=""
   EndIf
  EndIf
 EndIf
 ProcedureReturn path$
EndProcedure
GetProgramFilesDir() ;For example C:\Program Files\
Typically the default install location for programs.
Make sure to use \Company\Appname\ as a common courtesy.

GetApplicationDataDirectory() ;For example C:\Documents and Settings\username\Application Data\
The advised place to put program settings and such files.
Make sure to do the nice \Company\Appname\ thing here too :)

GetMyDocumentsDirectory() ;For example C:\Documents and Settings\username\My Documents\
The advised place to put documents, game save files, etc.
Make sure to do the nice \Company\Appname\ thing here too :)

GetTempDirectory() ;For example C:\Documents and Settings\username\Local Settings\Temp\
The advised place to put temporary files.
Make sure the filename is pretty unique or you make a folder that you put the temp files in, and always cleanup after yourself so you don't bloat the temp folder.

Posted: Mon Aug 06, 2007 11:56 pm
by Joakim Christiansen
Hehe, well, and here is how I did it for my prog:

Code: Select all

Procedure.s GetSpecialFolderPath(CSIDL.l)
  Protected *itemid.ITEMIDLIST, location.s = Space(#MAX_PATH)
  If SHGetSpecialFolderLocation_(0,CSIDL,@*itemid) = #NOERROR
    If SHGetPathFromIDList_(*itemid,@location)
      ProcedureReturn location
    EndIf
  EndIf
EndProcedure

Global AppdataPath$ = GetSpecialFolderPath(#CSIDL_APPDATA)
Global ProgramPath$ = GetPathPart(ProgramFilename())

If Not ProgramParameter(0) = "/portable" And FileSize("portable.txt") = -1
  If Not FileSize(AppdataPath$+"\JLC's Software")=-2
    CreateDirectory(AppdataPath$+"\JLC's Software")
  EndIf
  If Not FileSize(AppdataPath$+"\JLC's Software\Radio Player")=-2
    CreateDirectory(AppdataPath$+"\JLC's Software\Radio Player")
  EndIf
  SetCurrentDirectory(AppdataPath$+"\JLC's Software\Radio Player")
EndIf
And whenever is important for something to be saved in the same path as the executable use the ProgramPath$ variable. But for me, I didn't need to. Note how the user can easily change it into "portable" mode also.

Posted: Tue Aug 07, 2007 12:04 am
by Rescator
Joakim you got a memory leak,
please compare my SpecialFolderLocation() with your GetSpecialFolderPath()
PSDK/MSDN wrote:A pointer to an item identifier list (PIDL) specifying the folder's location relative to the root of the namespace (the desktop). The calling application is responsible for freeing this pointer

Posted: Tue Aug 07, 2007 1:43 pm
by Dare
Hi guys.

Thanks! Will look at these procedures in a few days. (Not being rude, just bogged down with the final stages of a business takeover and just about everything else is on the backburner at the moment).