When the program first starts it checks to see if a folder has been created for it in the os application data folder. If it has not the program creates this folder. The same check is repeated for the basic user.ini file.
The user.ini file saves the last x/y position and width/height of the main window on event #PB_Event_CloseWindow.
There are also a few extra functions that might come in handy.
This code uses the Win32 API so it is not cross-platform (sorry!).
Some snippets may have been lifted from code posted somewhere on the PB forum, I don't remember. Please credit yourself if you see your code.
Constants.pbi
Code: Select all
Enumeration
#WB_AppData
#WB_MainWindow
EndEnumeration
; Titles
#WB_AppName="Application Name"
; Config Files
#WB_UserINI="User.ini"
Code: Select all
Declare.s GetApplicationDataDirectory() ; Found in Functions.pbi
AppData.s=GetApplicationDataDirectory()+#WB_AppName+"\"
Code: Select all
;//
;// String functions
;//
; Strip file extension from string
Procedure.s StripExt(String.s)
For i=0 To Len(String)-1
n.s=Mid(String, Len(String)-i, 1)
If n="."
a.s=Left(String,(Len(String)-i)-1)
ProcedureReturn a
EndIf
Next i
EndProcedure
;//
;// Message Boxes
;//
; Error box then close application
Procedure ErrorClose(Msg.s)
Msg.s+Chr(13)+Chr(10)
MessageBox_(#Null, Msg.s,"Error", #MB_ICONERROR)
End
EndProcedure
; Procedure Error(File.s, Line.l, Msg.s)
; Msg.s+Chr(13)+Chr(10)
; Msg.s+StripExt(GetFilePart(File.s))+" line "+Str(Line.l)+Chr(13)+Chr(10)
; MessageBox_(#Null, Msg.s,"Error", #MB_ICONERROR)
; End
; EndProcedure
;//
;// Registry functons
;//
; Get Windows registry key value
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
;//
;// Special folders
;//
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 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
; 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
;//
;// INI functions
;//
Procedure.s INI_ReadString(FileName.s,Section.s,KeyName.s,Defaultval.s)
If OpenLibrary(0,"kernel32.dll")
n.s=Space(1024)
FileName.s=GetCurrentDirectory()+""+FileName.s
CallFunctionFast(GetFunction(0,"GetPrivateProfileStringA"),Section.s,KeyName.s,Defaultval.s,n.s,Len(n.s),FileName.s)
Else
ErrorClose("There was an error while calling kernel32.dll.")
EndIf
CloseLibrary(0)
ProcedureReturn n.s
EndProcedure
Procedure INI_WriteString(FileName.s,Section.s,KeyName.s,Value.s)
If OpenLibrary(0,"kernel32.dll")
FileName.s=GetCurrentDirectory()+""+FileName.s
CallFunctionFast(GetFunction(0,"WritePrivateProfileStringA"),Section.s,KeyName.s,Value.s,FileName.s)
Else
ErrorClose("There was an error while calling kernel32.dll.")
EndIf
CloseLibrary(0)
EndProcedure
Procedure.l INI_ReadInteger(FileName.s,Section.s,KeyName.s,Defaultval.l)
n.l=Val(INI_ReadString(FileName.s,Section.s,KeyName.s,Str(Defaultval.l)))
ProcedureReturn n.l
EndProcedure
Procedure INI_WriteInteger(FileName.s,Section.s,KeyName.s,Value.l)
INI_WriteString(FileName.s,Section.s,KeyName.s,Str(Value.l))
EndProcedure
;//
;// World Builder INI functions
;//
Procedure SetupWBuilderINI()
If FileSize(#WB_UserINI)<0
INI_WriteInteger(#WB_UserINI,"WindowPositions","Reset",1) ; Reset window positions
INI_WriteString(#WB_UserINI,"WindowPositions","MainWindow","0,0,800,600") ; Window positions x,y,w,h
EndIf
EndProcedure
;//
;// End of program functions
;//
Procedure Cleanup()
INI_WriteInteger(#WB_UserINI,"WindowPositions","Reset",0)
wx.s=Str(WindowX(#WB_MainWindow))
wy.s=Str(WindowY(#WB_MainWindow))
ww.s=Str(WindowWidth(#WB_MainWindow))
wh.s=Str(WindowHeight(#WB_MainWindow))
INI_WriteString(#WB_UserINI,"WindowPositions","MainWindow",wx.s+","+wy.s+","+ww.s+","+wh.s)
EndProcedure
Code: Select all
XIncludeFile "Constants.pbi"
XIncludeFile "Globals.pbi"
XIncludeFile "Functions.pbi"
; Program start
Debug "Program Start"
; Verify that the application data directory exists
If Not ExamineDirectory(#WB_AppData,AppData.s,"*.*")
CreateDirectory(AppData.s)
EndIf
SetCurrentDirectory(AppData.s) ; Set the current directory to the os application folder
If FileSize(#WB_UserINI)=-1 ; Check ini files
SetupWBuilderINI() ; If one does Not exist rebuild it (in the current directory)
EndIf
; Position the main window. If 'Reset=1' then center it on the screen
s.s=INI_ReadString(#WB_UserINI,"WindowPositions","MainWindow","0,0,800,600")
If INI_ReadInteger(#WB_UserINI,"WindowPositions","Reset",1)=1
x=GetSystemMetrics_(#SM_CXSCREEN)/2-Val(StringField(s.s,3,","))/2
y=GetSystemMetrics_(#SM_CYSCREEN)/2-Val(StringField(s.s,4,","))/2
Else
x=Val(StringField(s.s,1,","))
y=Val(StringField(s.s,2,","))
EndIf
OpenWindow(#WB_MainWindow,x,y,Val(StringField(s.s,3,",")),Val(StringField(s.s,4,",")),"Main Window",#PB_Window_SystemMenu|#PB_Window_SizeGadget)
If CreateGadgetList(WindowID(#WB_MainWindow))
main_window_mdi=MDIGadget(#PB_Any,0,0,0,0,1,2,#PB_MDI_AutoSize|#PB_MDI_NoScrollBars|#PB_MDI_BorderLess )
CreateMenu(#WB_MainWindow, WindowID(#WB_MainWindow))
MenuTitle("File")
MenuTitle("Tools")
MenuItem(0,"Tool 1")
MenuItem(1,"Tool 2")
MenuTitle("Windows")
MenuTitle("Help")
EndIf
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
Cleanup()
End
EndSelect
ForEver