...creating a real ( .scr ) screen saver.

This lesson adds a little 'pop' sound to the previous screen saver program, by playing a short WAV sound every time the bitmap 'hits' the side of the screen. So as not to bore you with this simple addition, I'm also going to show you how to 'poke' this WAV into memory, so it can be played from there, instead of from a file.

This program will also be written so that it can use David Cuny's resource generator tool-kit. This is a set of programs and an 'include' file, which can combine a number of files into a single file. The obvious advantage to this, is that a single file can replace any number. Doing this can save disk space, because files are stored as clusters. Since a 1 byte file might take up 4 kb. of disk space, storing a large number of files as one can be a lot more efficient.

The real bonus of using David's resource generator programs, however, is that this single file can now be attached to a 'bound' program. This will then create a single executable ( .exe ) program which will contain all the 'text', 'bitmap', and 'WAV' resources it requires to run, without any additional files.

I'm not actually using any 'text' files in this program, but any static ( read-only ) data can be used in a resource file.

The resource generator consists of three items:
(1) res.e - the include file
(2) makeres.ex - which creates the single resource
and
(3) bindres.ex - which attaches the resource to an .exe.

This code will run OK as is, without an actual 'resource' file. I will show you how to create this resource after going through the source code.

-- screen3.exw

--screen3.exw--
without type_check
without warning
include win32lib.ew
-- include the 'resource' handling functions 
include res.e 
-- the next 2 lines tell makeres.ex that we want two files in screen3.res
rFile("eu.bmp")
rFile("pop.wav")

constant
   CXFULL = w32Func( xGetSystemMetrics, {SM_CXSCREEN} ),
   CYFULL = w32Func( xGetSystemMetrics, {SM_CYSCREEN} ),
   Win1   = create( Window, "", 0, 0, 0, CXFULL, CYFULL, {WS_POPUP, WS_DLGFRAME} ),
   Win2   = create( Window, "", Win1, 0, 0, 330, 148, {WS_POPUP, WS_DLGFRAME} ),
   Title5  = create( CText, "_empowered by WIN32LIB_", Win2, 1, 121, 322, 20, 0 ),
   Bitmap2 = create( Bitmap, "", Win2, 0, 0, 324, 120, 0 ),
  
  -- set up THREE timers, this time.
  Mytimer1 = 1,
  Mytimer2 = 2,
  Mytimer3 = 3,
  
  SND_MEMORY = 4,
  CX = CXFULL-330,
  CY = CYFULL-148

setFont( Title5, "Arial", 12, 3 )

setWindowBackColor( Win1, rgb(0,0,0) )
atom rgbColor
rgbColor = getSysColor( COLOR_BTNFACE )
setWindowBackColor( Win2, rgbColor )

atom posx, posy, xsize, ysize, xdir, ydir, mysound
xdir = 1   ydir = 1

-- reads WAV from resource file to memory.
-- this function requires a file name, and a file size.
function loadWavResource( sequence fileName, atom size)
  atom        wavImage
  integer     hFile, fSize, byte
  sequence    info, b
-- use rOpen() from the res.e include file
  hFile = rOpen( fileName, "rb" )
  fSize = size

-- get the WAV from the .res file into a sequence.
  b={}
  b = repeat (0, fSize)
  for index = 1 to fSize do
      b[index] = getc (hFile)
  end for
  close(hFile)

-- poke the WAV into memory.
  wavImage = allocate( length(b) )
  for i = 0 to length(b)-1 do       
    poke( wavImage+i, b[i+1] )
  end for

  return wavImage    
end function

procedure center_win(atom win_id)
  sequence loc
  loc=getRect(win_id)
  xsize=loc[3]-loc[1]
  ysize=loc[4]-loc[2]
  posx=floor((w32Func(xGetSystemMetrics,{SM_CXFULLSCREEN})/2)-(xsize/2))
  posy=floor((w32Func(xGetSystemMetrics,{SM_CYFULLSCREEN})/2)-(ysize/2))
  setRect(win_id,posx,posy,xsize,ysize,1 )
end procedure



I should, perhaps, point out that the next routine refers to a folder as our source for the BMP and WAV resources. Obviously, this would not be required if the demo used an actual resource file !

procedure start_up( integer self, integer event, sequence params )
  atom map, map2
  map=rReadBmp( ".\\Bin\\eu.bmp" )
  map2=createDIB(map)
  setBitmap( Bitmap2, map2 )
  mysound=loadWavResource(".\\Bin\\pop.wav", 2576 )
  center_win(Win2)
  openWindow(Win2,Modal)
  setTimer( Win1, Mytimer1, 25 )  -- 40 moves/sec. maximum
  setTimer( Win1, Mytimer2, 120000 ) -- 2 minutes
end procedure

procedure next_pos( integer self, integer event, sequence params )
  integer timerId = params[1]
  integer junk
  if timerId=1 then
    if posx < 1 or posx > CX then 
     -- play the WAV from memory, if we've hit the window edge
     junk=w32Func(xPlaySound,{mysound,0,or_bits(SND_MEMORY,SND_ASYNC)})
     xdir = -xdir 
    end if
    if posy < 1 or posy > CY then 
      junk=w32Func(xPlaySound,{mysound,0,or_bits(SND_MEMORY,SND_ASYNC)})
      ydir = -ydir 
    end if
    posx = posx + xdir
    posy = posy - ydir
    setRect(Win2,posx,posy,xsize,ysize,1 )
  elsif timerId=2 then
    -- every 2 minutes, move the bitmap to a random location
    -- within it's permitted 'extents'
    posx=rand(CX)
    posy=rand(CY)
    setRect(Win2,posx,posy,xsize,ysize,1 )
  end if
end procedure

procedure exit_prog( integer self, integer event, sequence params )
  closeWindow(Win2)
  closeWindow(Win1)
end procedure

procedure blah( integer self, integer event, sequence params )
  exit_prog()
end procedure

setHandler( Win1, w32HOpen, routine_id("start_up") )
setHandler( Win1, w32HTimer, routine_id("next_pos") )
setHandler( Win2, w32HClick, routine_id("exit_prog") )
setHandler( Win2, w32HKeyDown, routine_id("blah") )

WinMain( Win1,Maximize )
--end code--

...now to the interesting bits.

To create a resource file that this program will use:
You should first edit the start_up() procedure so it no longer refers to a folder for the two resources, and temporarily copy eu.bmp, and pop.wav to the same folder as the program's location.

(1) Go to a DOS box. ( MS-DOS Prompt )

(2) Go to the folder containing these tutorials.
for example: cd c:\unzipped\EuWinTutor2\Demos

(3) type:
ex makeres.ex screen3.exw
This should now create the screen3.res file.

To test that the program will now work with the data contained in the .res file, you will have to temporarily re-name eu.bmp and pop.wav.
If you don't want to re-name them, you can 'hide' them in another folder.
Re-naming these two files will now 'force' our program to find and use it's data from screen3.res !

If everything has gone successfully, the program should now work without it's original data files, using only the ONE ( screen3.res ) data file.

...creating an executable

If you have a registered version of Euphoria, you can 'bind' this program to create screen3.exe.

If you're still using Euphoria version 2.2, again, in a DOS box, type:
bindw -clear_routines screen3.exw

If you're using Euphoria 2.3,
.. just type bindw in a DOS box, enter the program's name when prompted, and select the 'defaults' for the rest of the options.
This will create screen3.exe, without the data file.

Now, to 'attach' the screen3.res data file, type:
ex bindres.ex screen3.exe
The data file, ( screen3.res ) is now included within screen3.exe !

Re-naming this file to screen3.scr, and moving it into c:\Windows, should now allow you to select this program as your default screen saver.

If you haven't noticed yet, I have put the original documentation for the resource generator programs into what used to be my Synopsis...

...and, the actual program adds a third timer routine, so the mouse cursor 'blinks'.

...end

CONTENTS