In this lesson, I am going to introduce a
number of functions in kernel32.dll which will allow us to change
some file attributes. To keep the example simple, it will only be
able to change it's own
READONLY
HIDDEN, and
ARCHIVE
attributes.
A file with these and other attributes not set is
considered NORMAL.
I am going to use check-boxes to both display,
and change attributes.
The program will also display the file's
size.
The first function used in this program,
CreateFile(),
is only required because the GetFileSize()
function requires a windows file handle, in order to retrieve the
file's size. Since I have now opened a file, in effect creating a
Windows object, I've also implemented the CloseHandle()
function, to destroy this object once I'm done with it.
While
Windows would do this for me once I close the program, I thought I'd
introduce it here anyways...
Since the GetFileAttributes() and SetFileAttributes() functions only require a pointer to an allocated string which contains the file name, they are a little easier to use.
--
attrib1.exw
--attrib1.exw--
--start code--
include win32lib.ew
without warning
atom junk, file_id_ptr, attribs
--these are the file attribute bits we are concerned with.
--to keep our program small, we just refer to them by number.
--to get fancy, declare these as constants,
--so you can refer to them by name.
--FILE_ATTRIBUTE_READONLY = 1
--FILE_ATTRIBUTE_HIDDEN = 2
--FILE_ATTRIBUTE_ARCHIVE = 32
--FILE_ATTRIBUTE_NORMAL = 128
constant
zzOPEN_EXISTING = 3, -- declared as a constant.
Win = create( Window, "File Attributes", 0, 0, 0, 205, 225, 0 ),
Label0 = create( LText, "filename:", Win, 10, 12, 70, 20, 0 ),
Entry = create( EditText, "", Win, 75, 10, 110, 20, 0 ),
Label1 = create( LText, "", Win, 10, 40, 180, 20, 0 ),
Label2 = create( LText, "", Win, 10, 65, 180, 20, 0 ),
Check1 = create( CheckBox, " Read-Only (1)", Win, 10, 90, 170, 20, 0 ),
Check2 = create( CheckBox, " Hidden (2)", Win, 10, 115, 170, 20, 0 ),
Check3 = create( CheckBox, " Archive (32)", Win, 10, 140, 170, 20, 0 ),
Button1 = create( PushButton, "Change Attributes", Win, 10, 165, 130, 25, 0 ),
--**
--links to kernel32.dll functions not in Win32lib.ew
zGetFileAttributes = registerw32Function( kernel32, "GetFileAttributesA", {C_POINTER}, C_LONG ),
zSetFileAttributes = registerw32Function( kernel32, "SetFileAttributesA", {C_POINTER, C_LONG}, C_LONG ),
zCreateFile = registerw32Function( kernel32, "CreateFileA", {C_POINTER,C_LONG,C_LONG,C_LONG,C_LONG,C_LONG,C_LONG},C_LONG),
zCloseHandle = registerw32Function( kernel32, "CloseHandle", {C_LONG},C_LONG),
zGetFileSize = registerw32Function(kernel32,"GetFileSize", {C_LONG,C_LONG},C_LONG )
--set the font for the check-box labels to 'fixed'
--so everything stays lined up.
for i=Check1 to Check3 do
setFont( i,"Courier New",11,1)
end for
--on startup
procedure onLoad_Win(atom self, atom event, sequence params)
atom size
setText(Entry,"attrib1.exw")
file_id_ptr=allocate_string("attrib1.exw")
junk=w32Func(zCreateFile,{file_id_ptr,0,0,0,zOPEN_EXISTING,0,0})
size=w32Func(zGetFileSize,{junk,0})
setText(Label1,"file size = " & sprintf("%d",size))
junk=w32Func(zCloseHandle,{junk})
junk=w32Func(zGetFileAttributes,{file_id_ptr})
setText(Label2,"current attributes = " & sprintf("%d",junk))
if junk < 128 then
if junk >= 32 then setCheck(Check3,1) junk=junk-32 end if
if junk >= 2 then setCheck(Check2,1) junk=junk-2 end if
if junk = 1 then setCheck(Check1,1) end if
end if
free(file_id_ptr)
end procedure
--our 'Button1' procedure to change attributes
procedure set_attribs(atom self, atom event, sequence params)
--pre-set the variable
attribs=0
--then add up the current check-box settings
if isChecked(Check1) then attribs=attribs+1 end if
if isChecked(Check2) then attribs=attribs+2 end if
if isChecked(Check3) then attribs=attribs+32 end if
--save our file name in a 'string' structure in memory
file_id_ptr=allocate_string("attrib1.exw")
--set the attributes
junk=w32Func(zSetFileAttributes,{file_id_ptr,attribs})
--confirm our changes
junk=w32Func(zGetFileAttributes,{file_id_ptr})
--and display the numerical value in a text line.
setText(Label2,"current attributes = " & sprintf("%d",junk))
free(file_id_ptr)
end procedure
setHandler( Win, w32HOpen, routine_id( "onLoad_Win") )
setHandler( Button1, w32HClick, routine_id( "set_attribs") )
--end code--Just in case you don't know yet, where all these Windows function definitions are coming from, they are from Win32.hlp. This file is available through the Euphoria Archives. ( Win32 )
These functions are all described in the 'C' programming language style, which is why they all have to be 'wrapped' to be usable in Euphoria.
Just one caution though, if you are trying to use these in your own programs. The function name in Win32.hlp is NOT necessarily the same as the name in the DLL. For instance, the function CreateFile, described in the help file, is actually called CreateFileA in the DLL. Most common DLL's are in the \Windows\System folder. Right-clicking on a DLL, and using QuickView, if it's installed on your system, will open the file, in which ..somewhere under an EXPORT TABLE heading.. is a list of the proper names for the functions. If you don't see an export table using QuickView, it's likely that the DLL has been compressed, and your only option is to seek information about this DLL elsewhere. The Window's header ( .h ) files included with most Windows compilers are another source for this information.
(4/8/02)
There's a little bug-fix in
onLoad_Win(), by Jordah Ferguson. I had previously attempted to close
the file by using the file size as the file handle. ( .. not keeping
track of my 'junk' ;-) .. )
junk=w32Func(zGetFileSize,{junk,0}) --junk here takes up the file size
setText(Label1,"file size = " & sprintf("%d",junk))
junk=w32Func(zCloseHandle,{junk}) --then you are attempting to close file size...end...