Code archives/File Utilities/Blitz3D Filerequester (2.Update)

This code has been declared by its author to be Public Domain code.

Download source code

Blitz3D Filerequester (2.Update) by MPZ2004
Now can you use a Filerequester in Blitz 3D in the Windows Modus (Not Fullscreen) with a WINAPI Function. Usefull For Windows applikations...
I have changed two errors, Thanks to Tom Speed
Please delete the old one
; This Procedure is for free MPZ (@) from Berlin
; Version 0.2 1/2004
; 
; in the USERLIBS must be the file kernel32.decls
;.lib "kernel32.dll"
;api_RtlMoveMemory(Destination*,Source,Length) : "RtlMoveMemory"

; in the USERLIBS must be the file comdlg32.decls
;.lib "comdlg32.dll"
;api_GetOpenFileName% (pOpenfilename*) : "GetOpenFileNameA"
;api_GetSaveFileName% (pOpenfilename*) : "GetSaveFileNameA"


Graphics 800,600,0,2

; GetOpen/saveFileName consts Flags (useful ones only!)...
Const OFN_CREATEPROMPT         = $2000    ; Prompts the user as to whether they want to create a file that doesnt exist.
Const OFN_FILEMUSTEXIST        = $1000    ; File must exist for it to be returned.
Const OFN_HIDEREADONLY         = 4        ; Hides the read only button in the dialog...
Const OFN_NOCHANGEDIR          = 8        ; Stops the user from changing the initial directory.
Const OFN_NONETWORKBUTTON      = $20000   ; Hides and disables the network button.
Const OFN_NOREADONLYRETURN     = $8000    ; Stops the requester returning readonly files..
Const OFN_NOVALIDATE           = 256      ; If selected, no check will be done for invalid characters.
Const OFN_OVERWRITEPROMPT      = 2        ; Prompt for overwrite file...
Const OFN_PATHMUSTEXIST        = $800     ; Specifies that the path MUST exist for it to be able to be selected.
Const OFN_READONLY             = 1        ; Makes the read only checkbox in the dialog box to be checked immediately.

; getopenfile $(Title_of_Requester$, SearchPath$,Files_with_ending$, Flags); 	
; getsavefile $(Title_of_Requester$, Save_File_name$,Files_with_ending$, Flags); 	
;
; Title_of_Requester$= "Name of the Requester / Name des Dateifragefensters
; SearchPath$ = "C:\" ; Path for File searching / Pfad wo nach der Datei gesuchet werden soll 
; Files_with_ending$ = "All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)
;					 = "Blitzbasic" + Chr$(0) + "*.bb" + Chr$(0) + "Text" + Chr$(0) + "*.txt" + Chr$(0)
; Flags = See Flag lists
; Save_File_name$ = "C:\test.bb" ; Name of the Savefile with Path / Name der Datei mit Pfad zum speichern


Print getopenfile$("File open / Datei öffnen","d:\","All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)); flags optional

Print getsavefile$("File Save / Datei sichern","c:\Hello.bb","Blitzbasic" + Chr$(0) + "*.bb" + Chr$(0) + "Text" + Chr$(0) + "*.txt" + Chr$(0));; flags optional

While MouseHit(1) <> 1
Wend

End

;--------------------------You can use it as BlitzLIB

Function getOpenFile$(lpstrTitle$,lpstrInitialDir$,lpstrFilter$,flags=$1000)

	nextOffset%=0 
	theBank=CreateBank(76)
	lStructSize=76
	PokeInt theBank,nextOffset%,lStructSize
	nextOffset%=nextOffset%+4 
		
	hwndOwner=0
	PokeInt theBank,nextOffset%,hwndOwner
	nextOffset%=nextOffset%+4 
		
	hInstance=0
	PokeInt theBank,nextOffset%,hInstance
	nextOffset%=nextOffset%+4 

	If lpstrFilter$ = "" Then
		lpstrFilter$ = "All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)+ Chr$(0)
	Else	
		lpstrFilter$ = lpstrFilter$ + Chr$(0)		
	End If
	lpstrFilter_ = CreateBank(Len(lpstrFilter$)) 
	string_in_bank(lpstrFilter$,lpstrFilter_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrFilter_)
	nextOffset%=nextOffset%+4
		
	lpstrCustomFilter=0
	PokeInt theBank,nextOffset%,lpstrCustomFilter
	nextOffset%=nextOffset%+4 
	
	nMaxCustFilter=0
	PokeInt theBank,nextOffset%,nMaxCustFilter
	nextOffset%=nextOffset%+4 
	
	nFilterIndex=0
	PokeInt theBank,nextOffset%,nFilterIndex
	nextOffset%=nextOffset%+4 

	lpstrFile$= String$ (" ", 254)
	lpstrFile_ = CreateBank(Len(lpstrFile$)) 
	string_in_bank(lpstrFile$,lpstrFile_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrFile_)
	nextOffset%=nextOffset%+4 
	
	nMaxFile=255
	PokeInt theBank,nextOffset%,nMaxFile
	nextOffset%=nextOffset%+4 
	
	lpstrFileTitle$=String$ (" ", 254)
	lpstrFileTitle_ = CreateBank(Len(lpstrFileTitle$)) 
	string_in_bank(lpstrFileTitle$,lpstrFileTitle_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrFileTitle_)
	nextOffset%=nextOffset%+4  
	
	nMaxFileTitle=255
	PokeInt theBank,nextOffset%,nMaxFileTitle
	nextOffset%=nextOffset%+4 
	
	If lpstrInitialDir$="" Then
		lpstrInitialDir$="c:\"+Chr$(0)
	Else
		lpstrInitialDir$=lpstrInitialDir$+Chr$(0)
	End If
	lpstrInitialDir_ = CreateBank(Len(lpstrInitialDir$)) 
	string_in_bank(lpstrInitialDir$,lpstrInitialDir_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrInitialDir_)
	nextOffset%=nextOffset%+4 
	
	If lpstrTitle$="" Then
		lpstrTitle$="Open"+Chr$(0) 
	Else
		lpstrTitle$ = lpstrTitle$ + Chr$(0)
	End If	
	lpstrTitle_ = CreateBank(Len(lpstrTitle$)) 
	string_in_bank(lpstrTitle$,lpstrTitle_)	
	PokeInt theBank,nextOffset%,AddressOf(lpstrTitle_)
	nextOffset%=nextOffset%+4 

	PokeInt theBank,nextOffset%,flags
	nextOffset%=nextOffset%+4 
	
	nFileOffset=0
	PokeShort theBank,nextOffset%,nFileOffset
	nextOffset%=nextOffset%+2
	
	nFileExtension=0
	PokeShort theBank,nextOffset%,nFileExtension
	nextOffset%=nextOffset%+2
	
	lpstrDefExt=0
	PokeInt theBank,nextOffset%,lpstrDefExt
	nextOffset%=nextOffset%+4 
	
	lCustData=0
	PokeInt theBank,nextOffset%,lCustData
	nextOffset%=nextOffset%+4 
	
	lpfnHook=0
	PokeInt theBank,nextOffset%,lpfnHook
	nextOffset%=nextOffset%+4 

	lpTemplateName$=""+Chr$(0)
	lpTemplateName_ = CreateBank(Len(lpTemplateName$)) 
	string_in_bank(lpTemplateName$,lpTemplateName_)
	PokeInt theBank,nextOffset%,AddressOf(lpTemplateName_)
	nextOffset%=nextOffset%+4 
	If api_GetOpenFileName (theBank) Then
		lpstrFile$ = bank_in_string$(lpstrFile_)
	Else
		lpstrFile$ =""
	End If
	FreeBank theBank
	FreeBank lpstrFilter_
	FreeBank lpstrFile_
	FreeBank lpstrFileTitle_
	FreeBank lpstrInitialDir_
	FreeBank lpstrTitle_
	FreeBank lpTemplateName_
	Return lpstrFile$
End Function

Function getsaveFile$(lpstrTitle$,lpstrFile$,lpstrFilter$,flags=2) ; Get a SAVEFILENAME

	nextOffset%=0 
	theBank=CreateBank(76)
	lStructSize=76
	PokeInt theBank,nextOffset%,lStructSize
	nextOffset%=nextOffset%+4 
		
	hwndOwner=0
	PokeInt theBank,nextOffset%,hwndOwner
	nextOffset%=nextOffset%+4 
		
	hInstance=0
	PokeInt theBank,nextOffset%,hInstance
	nextOffset%=nextOffset%+4 

	If lpstrFilter$ = "" Then
		lpstrFilter$ = "All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)+ Chr$(0)
	Else	
		lpstrFilter$ = lpstrFilter$ + Chr$(0)		
	End If
	lpstrFilter_ = CreateBank(Len(lpstrFilter$)) 
	string_in_bank(lpstrFilter$,lpstrFilter_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrFilter_)
	nextOffset%=nextOffset%+4
		
	lpstrCustomFilter=0
	PokeInt theBank,nextOffset%,lpstrCustomFilter
	nextOffset%=nextOffset%+4 
	
	nMaxCustFilter=0
	PokeInt theBank,nextOffset%,nMaxCustFilter
	nextOffset%=nextOffset%+4 
	
	nFilterIndex=0
	PokeInt theBank,nextOffset%,nFilterIndex
	nextOffset%=nextOffset%+4 

	lpstrFile_ = CreateBank(255) 
	string_in_bank(lpstrFile$+Chr$(0),lpstrFile_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrFile_)
	nextOffset%=nextOffset%+4
	
	nMaxFile=255
	PokeInt theBank,nextOffset%,nMaxFile
	nextOffset%=nextOffset%+4 
	
	lpstrFileTitle$=String$ (" ", 254)
	lpstrFileTitle_ = CreateBank(Len(lpstrFileTitle$)) 
	string_in_bank(lpstrFileTitle$,lpstrFileTitle_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrFileTitle_)
	nextOffset%=nextOffset%+4  
	
	nMaxFileTitle=255
	PokeInt theBank,nextOffset%,nMaxFileTitle
	nextOffset%=nextOffset%+4 
	
	lpstrInitialDir$=""+Chr$(0)
	lpstrInitialDir_ = CreateBank(Len(lpstrInitialDir$)) 
	string_in_bank(lpstrInitialDir$,lpstrInitialDir_)
	PokeInt theBank,nextOffset%,AddressOf(lpstrInitialDir_)
	nextOffset%=nextOffset%+4 
	
	If lpstrTitle$="" Then
		lpstrTitle$="Save"+Chr$(0) 
	Else
		lpstrTitle$ = lpstrTitle$ + Chr$(0)
	End If	
	lpstrTitle_ = CreateBank(Len(lpstrTitle$)) 
	string_in_bank(lpstrTitle$,lpstrTitle_)	
	PokeInt theBank,nextOffset%,AddressOf(lpstrTitle_)
	nextOffset%=nextOffset%+4 

	PokeInt theBank,nextOffset%,flags
	nextOffset%=nextOffset%+4 
	
	nFileOffset=0
	PokeShort theBank,nextOffset%,nFileOffset
	nextOffset%=nextOffset%+2
	
	nFileExtension=0
	PokeShort theBank,nextOffset%,nFileExtension
	nextOffset%=nextOffset%+2
	
	lpstrDefExt=0
	PokeInt theBank,nextOffset%,lpstrDefExt
	nextOffset%=nextOffset%+4 
	
	lCustData=0
	PokeInt theBank,nextOffset%,lCustData
	nextOffset%=nextOffset%+4 
	
	lpfnHook=0
	PokeInt theBank,nextOffset%,lpfnHook
	nextOffset%=nextOffset%+4 

	lpTemplateName$=""+Chr$(0)
	lpTemplateName_ = CreateBank(Len(lpTemplateName$)) 
	string_in_bank(lpTemplateName$,lpTemplateName_)
	PokeInt theBank,nextOffset%,AddressOf(lpTemplateName_)

	If api_GetSaveFileName (theBank) Then
		lpstrFile$ = bank_in_string$(lpstrFile_)
	Else
		lpstrFile$ =""
	End If
	FreeBank theBank
	FreeBank lpstrFilter_
	FreeBank lpstrFile_
	FreeBank lpstrFileTitle_
	FreeBank lpstrInitialDir_
	FreeBank lpstrTitle_
	FreeBank lpTemplateName_
	Return lpstrFile$
End Function

Function AddressOf(Bank) ; Find the correct Adress of a Bank (for C *Pointer)
	Local Address = CreateBank(4) 
	api_RtlMoveMemory(Address,Bank+4,4) 
	Return PeekInt(Address,0) 
End Function

Function string_in_bank(s$,bankhandle) ; Put a String in a Bank
	Local pos=1
	Local pos2=0
	Repeat
		PokeByte(bankhandle,pos2,Asc(Mid(s$,pos,Len(s$))))
		pos=pos+1
		pos2=pos2+1
	Until pos=Len(s$)+1
End Function

Function bank_in_string$(bankhandle) ; Get a String from a Bank
	Local s$=""
	Local pos=0
	Repeat
		s$=s$+Chr(PeekByte(bankhandle,pos))
		pos=pos+1
	Until pos=BankSize(bankhandle)
	s$=Replace$(s$,Chr(0)," ")
	Return s$
End Function

Comments

Bot Builder2004
Thanks! Works well, and doesn't require external userlibs :P
[edit]
Although, I do have two probs:
1.You can't have a filetype with multiple extensions (say, 3d models or pictures)
2.for openfile, it appears to only work every-other-use, reliably.


Bremer2004
I think that multiple file types does work alright, but does anyone know why this doesn't work first time its called. And then only works every second time its called?

filename$ = getopenfile$("Load Bitmap Font",CurrentDir(),"Bitmap" + Chr$(0) + "*.bmp" + Chr$(0) + "Jpg" + Chr$(0) + "*.jpg" + Chr$(0) + "Png" + Chr$(0) + "*.png" + Chr$(0) ); flags optional


The above is an example of how I got it to do 3 filetypes.


MPZ2004
Dear Zawran

I have checked my code and all times it works fine. With what kind and version of blitzbasic do you work?

best regars,
Michael


Bremer2004
I am using b3d v1.87, and I have made it work but not fully. It works at is is above, but not from within the code of a tool I am coding at the moment. I am not doing anything else but calling the getOpenFile function but for some reason it only brings forth the requester every second time, but I might have something in my code that conflicts with the code you have made for this. So I will try and figure out what that could be. But as it is now you code works just fine on its own. Sounds like I have the same problem as Bot Builder have.


joncom20002004
I get the exact same problem as Zawran, it seems to work fine in the code you provide but when you implement it in a more functional b3d application it only seems to work every other time you call it.


vibe372004
Yeah, same here. The save dialog works fine but the load one doesn't always work.


MPZ2004
Sorry for the little error, i made a mistake with a ending of a string...

best wishes Michael

Please use this code for the getopenfile function


Function getOpenFile$(lpstrTitle$,lpstrInitialDir$,lpstrFilter$,flags=$1000)

nextOffset%=0
theBank=CreateBank(76)
lStructSize=76
PokeInt theBank,nextOffset%,lStructSize
nextOffset%=nextOffset%+4

hwndOwner=0
PokeInt theBank,nextOffset%,hwndOwner
nextOffset%=nextOffset%+4

hInstance=0
PokeInt theBank,nextOffset%,hInstance
nextOffset%=nextOffset%+4

If lpstrFilter$ = "" Then
lpstrFilter$ = "All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)+ Chr$(0)
Else
lpstrFilter$ = lpstrFilter$ + Chr$(0)
End If
lpstrFilter_ = CreateBank(Len(lpstrFilter$))
string_in_bank(lpstrFilter$,lpstrFilter_)
PokeInt theBank,nextOffset%,AddressOf(lpstrFilter_)
nextOffset%=nextOffset%+4

lpstrCustomFilter=0
PokeInt theBank,nextOffset%,lpstrCustomFilter
nextOffset%=nextOffset%+4

nMaxCustFilter=0
PokeInt theBank,nextOffset%,nMaxCustFilter
nextOffset%=nextOffset%+4

nFilterIndex=0
PokeInt theBank,nextOffset%,nFilterIndex
nextOffset%=nextOffset%+4

lpstrFile$= String$ (" ", 254)
lpstrFile_ = CreateBank(Len(lpstrFile$)+1)
string_in_bank(lpstrFile$+chr$(0),lpstrFile_)
PokeInt theBank,nextOffset%,AddressOf(lpstrFile_)
nextOffset%=nextOffset%+4

nMaxFile=255
PokeInt theBank,nextOffset%,nMaxFile
nextOffset%=nextOffset%+4

lpstrFileTitle$=String$ (" ", 254)
lpstrFileTitle_ = CreateBank(Len(lpstrFileTitle$))
string_in_bank(lpstrFileTitle$,lpstrFileTitle_)
PokeInt theBank,nextOffset%,AddressOf(lpstrFileTitle_)
nextOffset%=nextOffset%+4

nMaxFileTitle=255
PokeInt theBank,nextOffset%,nMaxFileTitle
nextOffset%=nextOffset%+4

If lpstrInitialDir$="" Then
lpstrInitialDir$="c:\"+Chr$(0)
Else
lpstrInitialDir$=lpstrInitialDir$+Chr$(0)
End If
lpstrInitialDir_ = CreateBank(Len(lpstrInitialDir$))
string_in_bank(lpstrInitialDir$,lpstrInitialDir_)
PokeInt theBank,nextOffset%,AddressOf(lpstrInitialDir_)
nextOffset%=nextOffset%+4

If lpstrTitle$="" Then
lpstrTitle$="Open"+Chr$(0)
Else
lpstrTitle$ = lpstrTitle$ + Chr$(0)
End If
lpstrTitle_ = CreateBank(Len(lpstrTitle$))
string_in_bank(lpstrTitle$,lpstrTitle_)
PokeInt theBank,nextOffset%,AddressOf(lpstrTitle_)
nextOffset%=nextOffset%+4

PokeInt theBank,nextOffset%,flags
nextOffset%=nextOffset%+4

nFileOffset=0
PokeShort theBank,nextOffset%,nFileOffset
nextOffset%=nextOffset%+2

nFileExtension=0
PokeShort theBank,nextOffset%,nFileExtension
nextOffset%=nextOffset%+2

lpstrDefExt=0
PokeInt theBank,nextOffset%,lpstrDefExt
nextOffset%=nextOffset%+4

lCustData=0
PokeInt theBank,nextOffset%,lCustData
nextOffset%=nextOffset%+4

lpfnHook=0
PokeInt theBank,nextOffset%,lpfnHook
nextOffset%=nextOffset%+4

lpTemplateName$=""+Chr$(0)
lpTemplateName_ = CreateBank(Len(lpTemplateName$))
string_in_bank(lpTemplateName$,lpTemplateName_)
PokeInt theBank,nextOffset%,AddressOf(lpTemplateName_)
nextOffset%=nextOffset%+4
If api_GetOpenFileName (theBank) Then
lpstrFile$ = bank_in_string$(lpstrFile_)
Else
lpstrFile$ =""
End If
FreeBank theBank
FreeBank lpstrFilter_
FreeBank lpstrFile_
FreeBank lpstrFileTitle_
FreeBank lpstrInitialDir_
FreeBank lpstrTitle_
FreeBank lpTemplateName_
Return lpstrFile$
End Function
[/EDIT]


Darth Testine2004
Two questions:

1) Where do I find the file "comdlg32.decls"?
I can't seem to find it anywhere.

2) The title says "(2.update)". Does this mean the source in the above post has been integrated into the source code at the top? I suppose if I wasn't so lazy, I'd compare. :-)

Thanks!


MPZ2004
Solution

1) You must write two files in the Blitz3d/userlib directory

a) first file has the name "kernel32.decls"
You write in the file:

.lib "kernel32.dll"
api_RtlMoveMemory(Destination*,Source,Length) : "RtlMoveMemory"

b) Second file has the name "comdlg32.decls"
You write in the file:

.lib "comdlg32.dll"
api_GetOpenFileName% (pOpenfilename*) : "GetOpenFileNameA"
api_GetSaveFileName% (pOpenfilename*) : "GetSaveFileNameA"

2) i write this function and found some bad errors in the first edition. The (2.update) was better, but the "getopenfile" function has had little bug too. All second times the getopenfile function doesn't work. The post (Posted 2004-10-11 10:21:17) show the correct "getopenfile" function...

best michael


JoeGr2005
As a 'finishing touch' try adding the line
Global hWnd=SystemProperty("AppHWND")
just after
Graphics 800,600,0,2
and changing
hwndOwner=0
to
hwndOwner=hWnd
in the getOpenFile$() and getSaveFile() functions. This should mean that the file requester 1) keeps the focus if a user clicks in the application's main window and 2) that it is drawn at the top left of the application's client area rather than the very top left of the screen.


John Blackledge2005
Yo! Joe's the man!

Don't I remember that the extensions string should have two chr$(0)'s at the end?
For those having trouble it's worth a try.


Ross C2006
This is good stuff. Thanks for this guys!


Code Archives Forum