Re: Passing Args to Event Handlers

new topic     » goto parent     » topic index » view thread      » older message » newer message

Derek Parnell wrote:

>
> Hi Ron,
> let me see if I understand your problem.
>
> When a Windows event happens, you want to be able to handle the event and in
> handling it, call a function of your own devising that returns some info to
> the handler routine.
>
> Are you also hoping to pass back some info to Windows?
>
> Anyhow, try this...

The example you gave looks like it'll do most of what I want, Derek (it even
looks like it'll handle a variable-length argument list) but I forgot to mention
one thing... I want to be able to pass the results from one function call
(tirggered by event one, let's say) to another function (triggered by event
two). So...

This afternoon I took another look through the examples distributed with
win32lib and found Buttons5.exw and realized that by combining that example with
the code snippet in the call_proc() documentation I could do more or less what
I'm aiming for. What I ended up with was a dispatch routine that pulls arguments
from a global arguments sequence (and any of those arguments can be modified by
any function called during a triggering event) and calls the appropriate
function. I'm likely not being very clear about this (I've been coding for over
ten hours today and I've got scrambled eggs in my head) so I'll just stop this
explanation and show you the code I came up with:


---------------
-- callfnc4.exw
---------------
-- Dynamic event-driven function calls using win32lib.ew
--
-- This is based on the win32lib example "Button5.exw"
-- and the Euphoria documentation for the call_proc()
-- routine.

include win32lib.ew
without warning

-- win32 controls
constant
 Win     =  create( Window, "Tab Controls", 0, Default, Default, 460, 490, 0 ),
 myMenu = create(Menu, "File", Win, 0,0,0,0,0),
 fileMenuAdd = create(MenuItem, "Add Something", myMenu, 0,0,0,0,0),
 fileMenuSubtract = create(MenuItem, "Subtract Something", myMenu, 0,0,0,0,0),
 fileMenuExit = create(MenuItem, "Exit", myMenu, 0,0,0,0,0)


-- IDs for functions that do the actual work
integer addID, subtractID, cleanUpAndDieID

-- variable ID for making calls to 'worker' functions
integer doWorkID

atom globalResults -- storage for results of function calls
sequence args -- multi-dimensional sequence of args for functions
atom penPos -- where to write in the window

-- initializations
penPos = 0
globalResults = 0


-----------------------
-- onClickCloseWindow()
-----------------------
-- worker function: close the window
--
function onClickCloseWindow(sequence args)

    closeWindow(args[1])
    return(0)
end function -- onClickCloseWindow()

cleanUpAndDieID = routine_id("onClickCloseWindow")


--------
-- add()
--------
-- worker function: add a variable-length list
-- of numbers
--
function add(sequence args)

 atom results

 results = 0

 for i = 1 to length(args) do
  results += args[i]
 end for

 return(results)
end function

addID = routine_id("add") -- assign an ID to the 'add' function


-------------
-- subtract()
-------------
-- worker function: subtract second number from first
--
function subtract(sequence args)

 atom results

 if length(args) = 2 then
  results = args[1] - args[2]
 else
  results = 0
  puts(1, "subtraction error, too many numbers\n")
 end if
 return(results)
end function

subtractID = routine_id("subtract") -- assign an ID to the 'subtract' function


-------
-- args
-------
-- storage for event IDs, their cooresponding functions,
-- and the arguments to pass to those functions
--
args = { -- control ID   func ID    args
    {fileMenuAdd,    addID,    {4, 3, 5, 7, 6}},
    {fileMenuSubtract, subtractID,   {4, 3}},
    {fileMenuExit,   cleanUpAndDieID, {Win}}
   }


---------------------
-- setGlobalResults()
---------------------
-- set the global results so they can be accessed from anywhere
--
procedure setGlobalResults(atom results)
 globalResults = results
 args[1][3][1] = globalResults   -- Just to prove a point, change args before
 args[2][3][1] = globalResults + 1 -- the next call to one of these functions.
end procedure -- setGlobalResults()



----------------------
-- onClickDispatcher()
----------------------
-- the 'master' function, called by all controls
--
procedure onClickDispatcher()

 atom results
 integer lResult
 integer funcToCall
 sequence myArgs

 lResult = getSelf()

 for i = 1 to length(args) do  -- look through the args sequence
  if args[i][1] = lResult then
   funcToCall = args[i][2]  -- assign which function to call
   myArgs = args[i][3]   -- assign which arguments to pass
  end if
 end for

 -- call the function that actually does the work
 results = call_func(funcToCall, {myArgs})

 penPos += 20
 setPenPosition(Win, 1, penPos)
 wPrintf(Win, "Results of this operation: %d ", results)

 setGlobalResults(results)

 penPos += 20 -- move the pen down so we don't overwrite previous text
 setPenPosition(Win, 1, penPos)
 wPrintf(Win, "globalResults: %d\n", globalResults)

end procedure

------------------
-- set routine IDs
------------------
--
onClick[Win]     = routine_id("onClickDispatcher")
onClick[fileMenuExit]  = routine_id("onClickDispatcher")
onClick[fileMenuAdd]   = routine_id("onClickDispatcher")
onClick[fileMenuSubtract] = routine_id("onClickDispatcher")

-----------
-- run code
-----------
--
WinMain(Win, Normal)


It translated really well into the code design I've been working with (thank
God) so I'm happy.

Anyway, I really appreciate your input. There are some interesting bits in your
code that I'll likely borrow if that's okay.

-Ron

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu