Hi all,
just experimenting here... and strange things happen. This code compiles just fine, but it doesn't open or create a file at all...
dim adresfile as bfile
dim bestandsnaam as string
'
' start main part
'
' open adres file
'
openconsole
bestandsnaam="c:\\My Documents\\ebasic\\adressen.dat"
if openfile(adresfile, bestandsnaam,"W")=0
'
' all is well, program can continue
'
mainloop()
closefile adresfile
else
'
' file didn't open...show error message and end program
'
cls
print "fout bij openen adressenbestand"
DO:UNTIL INKEY$ <> ""
endif
closeconsole
end
Anyone has a suggestion as to what i'm doing wrong?
Regards,
Frank
Hi Frank,
If the directory exists it will make adressen.dat, and since there is no data written to it , it will be zero/0 bytes.
If you insert this between mainloop() and closefile adresfile, you'll see it does make the file.
mainloop()
cls
print "adressenbestand aangemaakt"
DO:UNTIL INKEY$ <> ""
closefile adresfile
closefile adresfile
BTW The Mainloop() subroutine is missing in your code..
Greetings/groeten,
Gertjan
Hi GertJan,
Thanks for the response.
Yes, i know if i close the file, it will be created...but the question is : why do i get thrown into my error part of the if / else /end if struicture?
That should not happen...
if you look into the multiple examples provided, they all use the same test as i do... and they seem to work???
remark : mainloop() is the main program loop, just a do loop with select case statements in it, so it doesn't matter in this piece.
regards,
Frank
Hi Frank,
First part is using c:\\adressen.dat , it should not give an error.
Second part is using c:\\ABCDebasic directory (which probably will not exist on your system) , and give an error.
If you write to the file openfile(adresfile, bestandsnaam,"W") is used
To read from a file openfile(adresfile, bestandsnaam,"R") is used
To append to a file if openfile(adresfile, bestandsnaam,"A") is used
dim adresfile as bfile
dim bestandsnaam as string
'
' start main part
'
' open adres file
'
openconsole
'---------------------- should work c:\\adressen ---------------------
bestandsnaam="c:\\adressen.dat"
if openfile(adresfile, bestandsnaam,"W")=0
'
' all is well, program can continue
'
'' mainloop()
'' cls
print "adressenbestand aangemaakt"
DO:UNTIL INKEY$ <> ""
closefile adresfile
else
'
' file didn't open...show error message and end program
'
cls
print "fout bij openen adressenbestand "+bestandsnaam
DO:UNTIL INKEY$ <> ""
endif
'------------------------- generate an error using non-existing directory ABCDebasic ---------
bestandsnaam="c:\\ABCDebasic\\adressen.dat"
if openfile(adresfile, bestandsnaam,"W")=0
'
' all is well, program can continue
'
'' mainloop()
'' cls
print "adressenbestand aangemaakt"
DO:UNTIL INKEY$ <> ""
closefile adresfile
else
'
' file didn't open...show error message and end program
'
cls
print "fout bij openen adressenbestand "+bestandsnaam
DO:UNTIL INKEY$ <> ""
endif
closeconsole
end
Greetz,
Gertjan
Hi GertJan,
Thanks for the response...but you're assuming something incorrect.... : the directories do exist...
So again, the error should not be there....
My suspicion is that the openfile command returns multiple values..not just 0 for ok, and we should know some of these return codes
I'll try to find it in MSDN...
And yes, i do read manuals...
Regards,
Frank
Just looked at the EBasic source code for the OPENFILE command.
It only returns 0 and 1.
Larry
We can use FINDOPEN to tap the directory, and loop through with FINDNEXT to get the attributes -- of each file, one at a time, in turn. It would be nice to be able to just call GETATTRIBUTES, with the fullpath filename, and get the attributes for that specific file.
Hi All,
I found it...Jerry gave me the correct hint...and using the findopen/findnext example showed it to me...
Apparently, EB's 'openfile' statement only works with the 'real' directory entries, not the XP shortcuts... this means that 'My Documents' is not accessible directly, but needs to be preceded by '\\Documents and Settings\\<user name>\\......'
Adding this to the directory name proved to the trick..
Maybe a suggestion for Paul..to add '2' as an error message...that would then mean 'directory does not exist'
Regards,
Frank
to get the "my documents" special folder you need to use some windows api functions
'compile as console
declare IMPORT, SHGetSpecialFolderLocation(INT HWND, INT nFolder, POINTER LPITEMIDLIST),int
declare IMPORT, SHGetPathFromIDList(INT ITEMIDLIST, STRING PATH),int
declare IMPORT, CoTaskMemFree(int pidl)
'CSIDL of the mydocuments folder all windows system
$define CSIDL_PERSONAL 0x0005
'//////////////////////////////////////////
OPENCONSOLE
window dummy
string folder
folder = GetFolderLocation(dummy,CSIDL_PERSONAL)
print folder
PRINT "Press Any Key"
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
'//////////////////////////////////////////
'return the path to special folders
SUB GetFolderLocation(Window Win,INT CSIDL),STRING
STRING path
INT pidl
POINTER ppidl
ppidl = pidl
SHGetSpecialFolderLocation(win.hwnd,CSIDL,ppidl)
SHGetPathFromIDList(pidl,path)
CoTaskMemFree(pidl)
RETURN path
ENDSUB
you can find more CSIDL on msdn :
http://msdn2.microsoft.com/en-us/library/bb762494(VS.85).aspx
Hmm... I believe this comment may be helpful, but when I need to use other files in my program I always put them inside other directories under the main one of my program, and then use getstartpath+<something>. The directory tree structure must be the same in every computer I use it (or to any other directory in my own computer rather than the original one), but will always work.
Actually, Krypt's piece of code is very usefull, especially if you plan on having your software installed on multiple computers...where you not always know the directory structure...
It'll be a welcome addition to my 'code snippet' library...
Thanks Krypt.
Regards,
Frank
In "windows.inc", I find this:
DECLARE IMPORT, _GetFileAttributes ALIAS GetFileAttributesA(lpFileName AS STRING),INT
Okay. Cool. Now, what am I supposed to do with that? Does that mean I just put that line at the top of my code, then do something like:
filename = GETSTARTPATH + "mydata.txt"
ret = GetFileAttributesA(filename)
if ret = SomethingOrOther then print "File is Read-Only"
and I know if the file is Read-Only? Where are the values for SomethingOrOther listed?
Apparently, I actually should use:
DECLARE IMPORT, GetFileAttributesA(lpFileName AS STRING),INT
Then, this means something:
CONST FILE_ATTRIBUTE_READONLY = 0x1
So, maybe I can do
filename = GETSTARTPATH + "mydata.txt"
ret = GetFileAttributesA(filename)
if ret = FILE_ATTRIBUTE_READONLY then print "File is Read-Only"
Is that how it works?
Hmm... Close.
if( openfile(file1,filename,"R") = 0)
ret = GetFileAttributesA(filename)
MESSAGEBOX win,"attr = "+str$(ret),"File Attribute"
I get "33" or "32", but a file with READONLY set doesn't seem to make a difference.
What do I do with the CONST FILE_ATTRIBUTE_READONLY = 0x1
information here? Is this one of those "OR" things, using some 0x... stuff?
Not actual code but a structual example of what you can do.
If ret = 0x80 Then Normal=TRUE: Exit Function
If ret - 0x20 >= 0 Then Archive = True: ret = ret - 0x20
If ret - 0x4 >= 0 Then System = True: ret = ret - 0x4
If ret - 0x2 >= 0 Then Hidden = True: ret = ret- 0x2
If ret - 0x1 >= 0 Then ReadOnly = True: ret = ret - 0x1
You could also use a mask thing; if (0x000080 & ret)
Larry
I see something is going on with your to make a selection, but I don't see how it works. Trial and error shows that normal files return a 32, and read-only files return a 33. So this works:
If ret > 32 Then print "Read-only"
That seems shaky, since I don't know what else might cause it to return > 32. Your samples show the way to isolate the 0x1, but I'm afraid I don't know how to translate that into action. The "mask" is the key, so I mask out everything but READONLY and if I have anything left, that means READONLY. But I'm afraid I don't see how such masking works.
Just use the & operator.
if (ret & FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY
'File is read only
endif
You guys make it so hard on yourselves at times. The return value is a bit field. Meaning each bit in the value has it's own meaning, and it is not meant to be used as a discreet number.
33 = 100001 binary, means there are two bits turned "on".
FILE_ATTRIBUTE_READONLY = 000001 binary
100001 & 000001 = 000001
Nothing magical, just a binary number which you can verify using windows calculator if you wish ;)
Paul.
Like I said "blind leading the blind"
Larry
Quote from: Paul Turley on March 02, 2008, 07:59:19 AM
You guys make it so hard on yourselves at times. The return value is a bit field. Meaning each bit in the value has it's own meaning, and it is not meant to be used as a discreet number.
Thanks, Paul! I know about binary, and can convert dec-to-bin and back in my head. I just didn't know about the "&" operator and what the syntax was getting bit field data out. Never did it before. A little ignorance goes a long way... or in my case,
Jerry & ignorance = infinity - 1