Since it's been rumoured that all the original onXXX() event handling syntax in Win32lib will become obsolete with Win32lib version 1.00, and a new event handling syntax will will be required, I thought I'd introduce it here.
Future Win32lib code will require a new setHandler() syntax, that will allow win32lib code to pass additional parameters to the routine that handles the event.
This, of course means that your event handling routines will
now require three additional input parameters, as follows:
( atom
self, atom event, sequence parms ),
which usually, was not
required at all, in the old syntax style.
The cute little ellipse drawing demo below will give you a good idea of what this new syntax looks like.
Note that the onResize_Win() procedure has two 'events' in it's setHandler() code, in the form of a sequence.
Resizing this little demo will always re-draw the ellipse so that it fills the window's client area, with every WM_SIZE, and WM_SETFOCUS message the window receives.
--
ellipse2.exw
-- originally Euman's code, with C.K. Lester's patch,
-- and some re-arrangement.
without warning
include win32lib.ew
-- set up calls to two gdi graphics functions
constant
zSetViewportExtEx = registerw32Function( gdi32, "SetViewportExtEx",
{C_LONG, C_INT, C_INT, C_INT}, C_INT ),
zSetWindowExtEx = registerw32Function( gdi32, "SetWindowExtEx",
{C_LONG, C_INT, C_INT, C_POINTER}, C_INT )
constant
Win = create( Window, "Mapping Mode Scaling Demo", NULL, 25, 25, 300, 200, 0 )
atom WinDC, void
constant
zMM_ANISOTROPIC = 8
-- onOpen[Win]
procedure onOpen_Win( atom self, atom event, sequence parms )
atom oldMapMode
sequence InitExt
WinDC = getDC( Win )
InitExt = getClientRect( Win )
oldMapMode = w32Func( xSetMapMode, {WinDC, zMM_ANISOTROPIC} )
void = w32Func( zSetWindowExtEx, {WinDC, InitExt[3]-InitExt[1], InitExt[4]-InitExt[2], 0} )
setPenColor( Win, BrightRed )
end procedure
setHandler( Win, w32HOpen, routine_id( "onOpen_Win" ) )
-- onResize[Win], -- onGotFocus[Win]
procedure onResize_Win( atom self, atom event, sequence parms )
sequence CurExt
CurExt = getClientRect( Win )
repaintRect( Win, CurExt[1], CurExt[2], CurExt[3], CurExt[4] )
if w32Func( zSetViewportExtEx, {WinDC, CurExt[3]-CurExt[1], CurExt[4]-CurExt[2], 0} ) then
drawEllipse( Win, True, CurExt[1], CurExt[2], CurExt[3], CurExt[4] )
end if
end procedure
setHandler( Win, {w32HResize, w32HGotFocus}, routine_id( "onResize_Win" ) )
-- onClose[Win]
procedure onClose_Win( atom self, atom event, sequence parms )
releaseDC( Win )
end procedure
setHandler( Win, w32HClose, routine_id( "onClose_Win" ) )
WinMain( Win, Normal )At its simplest, the new setHandler() type of instruction appears to be no more than a rearrangement of the old onClick[], but there are significant differences. Consider a simple event handler in the new form:
procedure MyButton_onClick( integer self, integer event, sequence params ) -- ^^ this parameter list is invariant and must always be present FetchMyFile() -- do some action or call a procedure or function: end procedure setHandler( MyButton, w32HClick, routine_id( “MyButton_onClick” ) ) -- ^^ control ^^ event ^^ id of procedure to be called
In this example the parameter list of procedure MyButton_onClick will contain:
self : the identity of the invoking control, namely MyButton;
event : the identity of the event that triggered MyButton_onClick, namely w32HClick;
params : in the example params will be a null sequence, { }. The w32HClick event puts no arguments into params.
Now for a more complicated version of this handler:
procedure Buttons_onClick( integer self, integer event, sequence params ) -- ^^ this parameter list is invariant and must be present -- make choices: if self = MyButton then FetchMyFile() elsif self = ExitButton then closeApp() end if end procedure setHandler( { MyButton, ExitButton }, w32HClick, routine_id( “Buttons_onClick” ) ) -- ^^ control list ^^ event ^^ id of procedure to be called
We can put a list of controls, { MyButton, ExitButton }, into the setHandler statement and the handler will fire off whenever one of them is clicked. In (renamed) Buttons_onClick the self parameter, if we want, can be used to determine which of the buttons was clicked. So we have an ability to make choices in Buttons_onClick. As a matter of interest you can also replace the w32HClick atom in the SetHandler statement with a list of events, such as say { w32HClick, w32HKeyDown }, which gives even more choices (but might make the handling routine confusingly complicated).
Depending on the event atom (or list) in the setHandler statement, the params sequence may or may not contain arguments. For instance, w32HMouse places some into params:
procedure MyBitmap_onMouse( integer self, integer event, sequence params ) -- ^^ this parameter list is invariant and must be present -- some of the arguments in params: integer mouse_event = params[1] integer mouse_x = params[2] integer mouse_y = params[3] if mouse_event = MouseMove then DisplayMousePosition( x, y ) -- show where mouse is on the bitmap elsif mouse_event = LeftDown then FireGun() -- do something else end if end procedure setHandler( MyBitmap, w32HMouse, routine_id( “MyBitmap_onMouse” ) ) -- ^^ control ^^ event ^^ id of procedure to be called
Things can get even more complex than this, but that's enough for now.
..end of lesson Extra_00.