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