Using the routine from the Wiki under "Saving previous load and save paths" I am able to set the filer window to open up to the directory I want to either load from or save to. However try as I might, I simply cannot find a way of setting the filename in advance - it constantly comes up with the last used file name.
So the user loads in "NewFile.txt", but when he comes to save I want to suggest the name "NewEnglish.txt" (which he can alter as he pleases, of course) simply to prevent the other file being over-written by mistake.
I suspect that $$fp{} is somehow involved, but changing that assignment doesn't work. Any ideas, anyone, please?
Thanks.
Pre-setting a file name
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: Pre-setting a file name
Hmmm.
I'm still struggling with this one. It would even be useful to know if what I want is impossible!
To repeat: I can set the load or save filer window to open to the desired directory, but I cannot get it to display a file name. It would be useful if the filer window, as well as opening to the correct directory and looking for the desired file type, also had a default file name displayed in the "File name:" line.
Thanks.
I'm still struggling with this one. It would even be useful to know if what I want is impossible!
To repeat: I can set the load or save filer window to open to the desired directory, but I cannot get it to display a file name. It would be useful if the filer window, as well as opening to the correct directory and looking for the desired file type, also had a default file name displayed in the "File name:" line.
Thanks.
Re: Pre-setting a file name
Lots of context missing here. Are we talking about BBC BASIC for Windows or BBC BASIC for SDL 2.0? What kind of 'filer window', one created using an Operating System API or one coded in BASIC?
As far as the File Selector created by the filedlg.bbc library is concerned I'm afraid there is no way of pre-setting the filename. That is probably an omission on my part, because it didn't occur to me when I wrote it that it would be useful. I don't expect it would be difficult to add, but the current library doesn't support it.
If it's an OS-supplied file selector (such as the Windows GetOpenFileName API) you will need to consult the associated documentation. There it says this: "lpstrFile: The file name used to initialize the File Name edit control", which suggests it is simply a case of passing the required (NUL-terminated) string in this parameter.
As always, if you can't make it work post a Minimal Reproducible Example (a self-contained piece of code which demonstrates the issue but is as small as possible).
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: Pre-setting a file name
Grrrr! So simple - yet could I get it to work last night? Thank you so much for pointing the way. (BB4W, I'm afraid, not SDL.)
For the benefit of anyone else who may want to do this, here is the functioning program snippet.
For the benefit of anyone else who may want to do this, here is the functioning program snippet.
Code: Select all
PROCinit
PROCsetupfiler(@dir$+CHR$0,"NewFile.txt"+CHR$0,"Text files"+CHR$0+"*.txt"+CHR$0+CHR$0)
SYS"GetSaveFileName",fs{}TOR%
IFR%THEN
REM The actual save routine
ENDIF
END
:
DEFPROCsetupfiler(dir$,filename$,type$)
InitialDir$=dir$+CHR$0
FileFilter$=type$+CHR$0+CHR$0
fs.lStructSize%=DIM(fs{})
fs.lpstrFilter%=PTR(FileFilter$)
fs.lpstrInitialDir%=PTR(InitialDir$)
fs.lpstrFile%=PTR(filename$)
ENDPROC
:
DEFPROCinit
REM ----- Structure for the load and save dialog boxes -----
DIMfs{lStructSize%,hwndOwner%,hInstance%,lpstrFilter%,lpstrCustomFilter%,nMaxCustFilter%,nFilterIndex%, \
\ lpstrFile%,nMaxFile%,lpstrFileTitle%,nMaxFileTitle%,lpstrInitialDir%,lpstrTitle%,flags%, \
\ nFileOffset{l&,h&},nFileExtension{l&,h&},lpstrDefExt%,lCustData%,lpfnHook%,lpTemplateName%}
DIMfp{t&(260)}
InitialDir$=@dir$+CHR$0
FileFilter$="Text files"+CHR$0+"*.txt"+CHR$0+CHR$0
rp$=CHR$195+CHR$170+"!Lfoebmm!L/!Epxo!3121!"
fs.lStructSize%=DIM(fs{})
fs.hwndOwner%=@hwnd%
fs.lpstrFilter%=PTR(FileFilter$)
fs.lpstrFile%=fp{}
fs.nMaxFile%=DIM(fp{})-1
fs.lpstrInitialDir%=PTR(InitialDir$)
fs.flags%=6
ENDPROC
Re: Pre-setting a file name
A real nasty I've just spotted: you are setting fs.lpstrFile% to point to the local variable filename$ and then exiting from the procedure using ENDPROC, whereupon the local variable ceases to exist! So by the time you call SYS "GetSaveFileName" fs.lpstrFile% could be pointing at anything (or nothing). The code is (or appears to be) working purely by luck!KenDown wrote: ↑Wed 13 Dec 2023, 11:45Code: Select all
PROCsetupfiler(@dir$+CHR$0,"NewFile.txt"+CHR$0,"Text files"+CHR$0+"*.txt"+CHR$0+CHR$0) SYS"GetSaveFileName",fs{}TOR% ... DEFPROCsetupfiler(dir$,filename$,type$) ... fs.lpstrFile%=PTR(filename$) ENDPROC
It's vitally important that any strings that you pass (in memory) to the API function still exist when that function is called, and aren't local or temporary variables that have since been discarded. A simple fix would be to move the API call into the subroutine:
Code: Select all
R% = FNselectfile(@dir$+CHR$0,"NewFile.txt"+CHR$0,"Text files"+CHR$0+"*.txt"+CHR$0+CHR$0)
...
DEF FNselectfile(dir$,filename$,type$)
LOCAL R%
...
fs.lpstrFile%=PTR(filename$)
SYS "GetSaveFileName", fs{} TO R%
= R%
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: Pre-setting a file name
Thank you so much. That is a bit of information of which I was completely ignorant. I will, of course, adopt your solution.
Many many thanks.
Many many thanks.
-
- Posts: 327
- Joined: Wed 04 Apr 2018, 06:36
Re: Pre-setting a file name
It didn't work: $$fp{} returned a null string.
After much brain-wracking, I finally realised my mistake: fs.lpstrFile% is set to two different values, only one of which can be correct! So this is the corrected version, which does actually work:
Now on exit $$fp{} will contain the filename.
The only annoying thing left is that without adding an extra parameter as a flag, the filer open window will always contain the word "OPEN" even when you are saving!
Code: Select all
DEFPROCsetupfiler(dir$,filename$,type$)
InitialDir$=dir$+CHR$0
FileFilter$=type$+CHR$0+CHR$0
fs.lStructSize%=DIM(fs{})
fs.lpstrFilter%=PTR(FileFilter$)
fs.lpstrFile%=fp{}
fs.lpstrInitialDir%=PTR(InitialDir$)
fs.lpstrFile%=PTR(filename$)
ENDPROC
Code: Select all
DEFFNsetupfiler(dir$,filename$,type$):LOCALR%
InitialDir$=dir$+CHR$0
FileFilter$=type$+CHR$0+CHR$0
fs.lStructSize%=DIM(fs{})
fs.lpstrFilter%=PTR(FileFilter$)
fs.lpstrFile%=fp{}
fs.nMaxFile%=DIM(fp{})-1
fs.lpstrInitialDir%=PTR(InitialDir$)
$fp{}=filename$+CHR$0
SYS"GetOpenFileName",fs{}TOR%
=R%
The only annoying thing left is that without adding an extra parameter as a flag, the filer open window will always contain the word "OPEN" even when you are saving!