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