...more kernel32 to find file attributes

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...

CONTENTS