Re: Passing Args to Event Handlers
- Posted by Ron Tarrant <rtarrant at sympatico.ca> Aug 01, 2002
- 395 views
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