1. win32lib event handling question
- Posted by ags <eu at 531pi.co.nz> Jul 19, 2005
- 597 views
Hi All I've created a window dynamically with win32lib and then created child windows in that 'parent' window. My problem is that the dynamically created windows don't seem to receive events of any kind (w32HClick, w32HMouse, etc). Is this a feature of win32lib? :) I'm trying to track the position of the child windows in the event handler (not shown in the code since it doesn't even get called). Any ideas? Example:
--/begin childtest.ew -- testing win32lib event handling of dynamically created windows -- win32lib v0.60.6 include win32lib.ew -- globals constant launchwin = create(Window, "Launcher", 0, Default, Default, 320, 240, 0), Button1 = create(Button, "Launch", launchwin, 5, 5, 50, 20, 0), Status = create(StatusBar, "", launchwin, 0, 0, 0, 0, 0) -- 'positions' indices constant NAME = 1, XPOS = 2, YPOS = 3 constant positions = {{"ONE", 10,10}, {"TWO", 110, 10}, {"THREE", 110, 110}} -- support routines procedure create_parent_and_children() atom parent, child sequence name atom x, y parent = createEx(Window, "Parent", launchwin, Default, Default, 640, 480, w32or_all({WS_THICKFRAME, WS_SYSMENU}), w32or_all({WS_EX_DLGMODALFRAME}) ) setHandler(parent, w32HMouse, routine_id("child_onMouse")) openWindow(parent, Modal) for i = 1 to length(positions) do name = positions[i][NAME] x = positions[i][XPOS] y = positions[i][YPOS] child = create(Window, name, parent, x, y, 100, 100, {WS_CHILD, WS_CLIPSIBLINGS, WS_BORDER, WS_CAPTION} ) -- this should set handler for when mouse activity occurs? setHandler(child, w32HMouse, routine_id("child_onMouse") ) openWindow(child, Normal) end for end procedure procedure child_onMouse(integer self, atom event, sequence params) atom evt, shift evt = params[1] shift = params[4] setText(Status, "Mouse event in " & getText(self)) end procedure -- handler set dynamically setHandler(launchwin, w32HMouse, routine_id("child_onMouse") ) -- test -- launch window control events procedure Button1_onClick(integer self, atom event, sequence params) create_parent_and_children() end procedure setHandler(Button1, w32HClick, routine_id("Button1_onClick") ) -- start setText(Status, sprintf("Win32Lib version %d.%d Patch#%d, %s", Win32LibVersion)) WinMain(launchwin, Normal) --/end childtest.ew
--(I hope Privoxy doesn't mangle it)
2. Re: win32lib event handling question
- Posted by ags <eu at 531pi.co.nz> Jul 19, 2005
- 481 views
Argh. Unpost. routine_id("child_onMouse") evidently would be -1 if child_onMouse() is not declared yet. (decides to attack Rob instead) (reads archived posts) (decides against it :) Anyway, of course moving the procedure declaration above the routine_id examining it works very well. Gary
3. Re: win32lib event handling question
- Posted by Derek Parnell <ddparnell at bigpond.com> Jul 19, 2005
- 513 views
- Last edited Jul 20, 2005
ags wrote: > > Argh. Unpost. > > routine_id("child_onMouse") evidently would be -1 if child_onMouse() > is not declared yet. > > (decides to attack Rob instead) > (reads archived posts) > (decides against it :) > > Anyway, of course moving the procedure declaration above the routine_id > examining it works very well. Welcome to my nightmare -- Derek Parnell Melbourne, Australia irc://irc.sorcery.net:9000/euphoria
4. Re: win32lib event handling question
- Posted by Jason Gade <jaygade at gmail.com> Jul 20, 2005
- 497 views
Derek Parnell wrote: > > > posted by: Derek Parnell <ddparnell at bigpond.com> > > ags wrote: > >>Argh. Unpost. >> >>routine_id("child_onMouse") evidently would be -1 if child_onMouse() >>is not declared yet. >> >>(decides to attack Rob instead) >>(reads archived posts) >>(decides against it :) >> >>Anyway, of course moving the procedure declaration above the routine_id >>examining it works very well. > > > Welcome to my nightmare > Yes, let's repeat again: routine_id() is already a way to get around the normal calling mechanism and should allow forward referencing. Lather, rinse, repeat. -- ============================== Too many freaks, not enough circuses. j.
5. Re: win32lib event handling question
- Posted by ags <eu at 531pi.co.nz> Jul 20, 2005
- 470 views
Derek Parnell wrote: > > Anyway, of course moving the procedure declaration above the routine_id > > examining it works very well. > > Welcome to my nightmare I realised my bigger problem was actually detecting a window move. I had a control taking up the entire space of the child window too, so getting the WM_MOVING message is the more correct route to take. But I took one look at that and decided to just fake the window and use a dragable window. I've just seen your 2001 post on adding SS_NOTIFY to LText, so that should make it easy enough, if that still works. Gary
6. Re: win32lib event handling question
- Posted by ags <eu at 531pi.co.nz> Jul 20, 2005
- 489 views
Jason Gade wrote: > >>Anyway, of course moving the procedure declaration above the routine_id > >>examining it works very well. > > > > Welcome to my nightmare > > > > Yes, let's repeat again: routine_id() is already a way to get around > the normal calling mechanism and should allow forward referencing. > Lather, rinse, repeat. Maybe. I'm too new to all this to have and informed opinion. But when I started using global atoms for routine_ids I realised that it makes it very easy to replace a routine referenced by a routine_id. eg
atom rid_Hi procedure en_say_hi() puts(1, "Good day to you!\n") end procedure procuedure to_say_hi() puts(1, "Malo e leilei!\n") end procedure procedure au_say_hi() puts(1, "Gidday!\n") end procedure procedure de_say_hi() puts(1, "Guten Tag!\n") end procedure if equal(lower(Language), "de") then rid_Hi = routine_id("de_say_hi") elsif ... else rid_Hi = routine_id("en_say_hi") -- default end if call_proc(rid_Hi, {})
A bit of a contrived example I know (since you'd use a string table for this) but more prosaically it does allow you to code a new version of say Button1_onClick and replace the global rid_.. atom for testing a new version. The great debate on routine_id seemed to take place in the late 90's so I think people are used to the way it works now, but I feel the interpreter could warn (newbies! :) about a routine_id of an as yet undeclared procedure? I mean routine_id is part and parcel of the whole win32lib programming experience now... Gary
7. Re: win32lib event handling question
- Posted by Derek Parnell <ddparnell at bigpond.com> Jul 20, 2005
- 479 views
ags wrote: > > Jason Gade wrote: > > >>Anyway, of course moving the procedure declaration above the routine_id > > >>examining it works very well. > > > > > > Welcome to my nightmare > > > > > > > Yes, let's repeat again: routine_id() is already a way to get around > > the normal calling mechanism and should allow forward referencing. > > Lather, rinse, repeat. > > Maybe. I'm too new to all this to have and informed opinion. But when I > started using global atoms for routine_ids I realised that it makes it > very easy to replace a routine referenced by a routine_id. [snipped: a good example] RDS has the programming philosophy that items ought to be declared earlier in source code than their first reference. This philosophy was implemented strictly in earlier versions of Euphoria. Later it became apparent that one circumstance needed special treatment. This was the circumstance where two routines referred to each other. Obviously, the first routine couldn't reference the second one because it occured further on down in the source code. Thus the 'routine_id()' was born. However, it also strictly adheres to the philosophy in that a routine_id cannot refer to a routine that exists further down in the source code. To use it to allow two routines to call each other, the coder must create a variable that must be placed prior to both routines, so that both routines can refer to it, and execute one or more routine_id() calls before the two routines in question are called.
integer rid_one integer rid_two . . . procedure one() . . . call_proc(rid_two) . . . end procedure procedure two() . . . call_proc(rid_one) . . . end procedure rid_one = routine_id("one") rid_two = routine_id("two")
The routine_id() technique was created to solve a special, and rare, situation. However, it has been used as a solution to many other smaller issues with the language. Your example is one very valid reason to use it. Win32lib uses it in two main ways; to assign a potential routine to an action, and to avoid the need to keep shuffling code around when enhancements bump up against the physical relationship philosophy between call and declaration. And a lot of people use it for other reasonable purposes to. When v2.5 alpha was released, RDS made a 'mistake'. They allowed routine_id() to reference routines that were further down in the code. So this proved that there was no technical reason for its documented behavior. Once people realized that this was possible, we rejoiced because it granted us some long hoped for freedom and improvement in code clarity. However, RDS corrected this mistake and returned us to their vision of proper coding. My argument now is that we should compromise. As routine_id() is a special usage technique, and not one used in common code, it should be allowed to reference routines further down in the source code, but direct references should still stick with the RDS philosophy. People who are coding are smart enough to not be confused by this. The gain in code clarity and lowered maintence cost would easily offset the perceived wrongness in forward referencing. But I really don't expect RDS to do anything at all, so I don't know why I bother. -- Derek Parnell Melbourne, Australia Skype name: derek.j.parnell
8. Re: win32lib event handling question
- Posted by cklester <cklester at yahoo.com> Jul 20, 2005
- 470 views
Derek Parnell wrote: blah blah blah about routine_id()... > Derek Parnell > Melbourne, Australia > Skype name: derek.j.parnell Derek and I spoke on Skype the other night. He's in Melbourne, I'm in Dallas. That's Australia and Texas. The clarity from my side was crystal clear. And to think that it was FREE. So cool. There's a conference call option on there, so Euphorians could get together and discuss stuff. -=ck "Programming in a state of EUPHORIA." http://www.cklester.com/euphoria/
9. Re: win32lib event handling question
- Posted by ags <eu at 531pi.co.nz> Jul 20, 2005
- 497 views
Derek Parnell wrote: > My argument now is that we should compromise. As routine_id() is a special > usage technique, > and not one used in common code, it should be allowed to reference routines > further > down in the source code, but direct references should still stick with the RDS > philosophy. > People who are coding are smart enough to not be confused by this. I think at least a warning of a forward routine_id reference would give you the chance to think about other ways of doing it (if possible). Then again maybe we should be checking that routine_id(...) doesn't = -1? eg
-- in include file include win32lib.ew procedure bad_routine_id() puts(1, "Warning: Bad routine_id used. Check for forward reference\n") -- and "Sorry but I can't tell you where it is" end procedure global constant rid_Bad_routine = routine_id("bad_routine_id") global function safe_routine_id(sequence code_name) return w32iff(routine_id(code_name), routine_id(code_name), rid_Bad_routine) -- that's if -1 is false? otherwise if.. then.. end function -- in code procedure Window1_onMouse() VOID = message_box("The mouse moved!!", "Important", MB_OK) end procedure setHandler(Button1, w32HMouse, safe_routine_id("Window1_onMouse") )
And with safe_routine_id() in an early included header most functions /procedures would be visible anyway wouldn't they? Gary
10. Re: win32lib event handling question
- Posted by Derek Parnell <ddparnell at bigpond.com> Jul 20, 2005
- 479 views
ags wrote: > > Derek Parnell wrote: > > My argument now is that we should compromise. As routine_id() is a special > > usage technique, > > and not one used in common code, it should be allowed to reference routines > > further > > down in the source code, but direct references should still stick with the > > RDS philosophy. > > People who are coding are smart enough to not be confused by this. > > I think at least a warning of a forward routine_id reference would give you > the chance to think about other ways of doing it (if possible). Then again > maybe we should be checking that routine_id(...) doesn't = -1? > eg > > }}} <eucode> > -- in include file > include win32lib.ew > > procedure bad_routine_id() > puts(1, "Warning: Bad routine_id used. Check for forward reference\n") > -- and "Sorry but I can't tell you where it is" > end procedure > global constant rid_Bad_routine = routine_id("bad_routine_id") > > global function safe_routine_id(sequence code_name) > return w32iff(routine_id(code_name), routine_id(code_name), > rid_Bad_routine) > -- that's if -1 is false? otherwise if.. then.. > end function > > -- in code > procedure Window1_onMouse() > VOID = message_box("The mouse moved!!", "Important", MB_OK) > end procedure > setHandler(Button1, w32HMouse, safe_routine_id("Window1_onMouse") ) > <font color="#330033"></eucode> {{{ </font> > > And with safe_routine_id() in an early included header most functions > /procedures would be visible anyway wouldn't they? Actually that turns out not to be the case. When the routine_id() is executed, the string passed to it will be the name of a routine that occurs further down in the source code and thus invisible to routine_id. The way to deal with this is convoluted and totally obtuse ...
-- in code global atom rid_safe_routine_id include win32lib.ew procedure Window1_onMouse() VOID = message_box("The mouse moved!!", "Important", MB_OK) end procedure setHandler(Button1, w32HMouse, call_func(rid_safe_routine_id,{"Window1_onMouse"}) ) include saferid.e -- *MUST* be and the end of the main code file.
The content of saferid.e would be like ...
procedure bad_routine_id() puts(1, "Warning: Bad routine_id used. Check for forward reference\n") -- and "Sorry but I can't tell you where it is" end procedure global constant rid_Bad_routine = routine_id("bad_routine_id") global function safe_routine_id(sequence code_name) return w32iff(routine_id(code_name), routine_id(code_name), rid_Bad_routine) -- that's if -1 is false? otherwise if.. then.. end function rid_safe_routine_id = routine_id("safe_routine_id")
Its the physical order of the lines of code that matters, and not which order they are executed in. -- Derek Parnell Melbourne, Australia Skype name: derek.j.parnell
11. Re: win32lib event handling question
- Posted by ags <eu at 531pi.co.nz> Jul 20, 2005
- 492 views
Derek Parnell wrote: > > And with safe_routine_id() in an early included header most functions > > /procedures would be visible anyway wouldn't they? > > Actually that turns out not to be the case. When the routine_id() is executed, > the > string passed to it will be the name of a routine that occurs further down in > the source > code and thus invisible to routine_id. The way to deal with this is convoluted > and > totally obtuse ... <snip example that doesn't help code clarity> > > Its the physical order of the lines of code that matters, and not which order > they > are executed in. Ah, OK, I get it. I think I'll stick with routine_id() but not spend several hours scratching my head the next time something doesn't work. :) Gary
12. Re: win32lib event handling question
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Jul 20, 2005
- 520 views
On Tue, 19 Jul 2005 18:14:57 -0700, ags <guest at RapidEuphoria.com> wrote: >I feel the interpreter >could warn (newbies! :) about a routine_id of an as yet undeclared procedure? Me too. I have often longed for a wrapper function for routine_id, but as noted Eu does not play fair. A suggestion springs to mind: global type rtnid(object r) return not equal(r,-1) end type Use that type instead of integer for any local routine_id variable definitions, and also in win32lib etc: global procedure setHandler(integer id, integer flag, rtnid rid) ... and either force use of removeHandler, or force {-1} rather than -1 for the delete feature of setHandler. Regards, Pete PS the type above should be part of the new standard library.
13. Re: win32lib event handling question
- Posted by "Juergen Luethje" <j.lue at gmx.de> Jul 22, 2005
- 513 views
Pete Lomax wrote: <snip> > A suggestion springs to mind: > > global type rtnid(object r) > return not equal(r,-1) > end type > > Use that type instead of integer for any local routine_id variable > definitions, and also in win32lib etc: > > global procedure setHandler(integer id, integer flag, rtnid rid) > ... > and either force use of removeHandler, or force {-1} rather than -1 > for the delete feature of setHandler. > > Regards, > Pete > PS the type above should be part of the new standard library. I did include this sugestion in http://home.arcor.de/luethje/esl/type.htm Thanks, Juergen