1. win32lib event handling question

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)

new topic     » topic index » view message » categorize

2. Re: win32lib event handling question

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: win32lib event handling question

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 blink

-- 
Derek Parnell
Melbourne, Australia
irc://irc.sorcery.net:9000/euphoria

new topic     » goto parent     » topic index » view message » categorize

4. Re: win32lib event handling question

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 blink
> 

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.

new topic     » goto parent     » topic index » view message » categorize

5. Re: win32lib event handling question

Derek Parnell wrote:
> > Anyway, of course moving the procedure declaration above the routine_id
> > examining it works very well.
> 
> Welcome to my nightmare blink

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

new topic     » goto parent     » topic index » view message » categorize

6. Re: win32lib event handling question

Jason Gade wrote:
> >>Anyway, of course moving the procedure declaration above the routine_id
> >>examining it works very well.
> > 
> > Welcome to my nightmare blink
> > 
> 
> 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

new topic     » goto parent     » topic index » view message » categorize

7. Re: win32lib event handling question

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 blink
> > > 
> > 
> > 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

new topic     » goto parent     » topic index » view message » categorize

8. Re: win32lib event handling question

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/

new topic     » goto parent     » topic index » view message » categorize

9. Re: win32lib event handling question

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" smile
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

new topic     » goto parent     » topic index » view message » categorize

10. Re: win32lib event handling question

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" smile
> 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" smile
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

new topic     » goto parent     » topic index » view message » categorize

11. Re: win32lib event handling question

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

new topic     » goto parent     » topic index » view message » categorize

12. Re: win32lib event handling question

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.

new topic     » goto parent     » topic index » view message » categorize

13. Re: win32lib event handling question

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu