1. getSelf( )

Hi again Derek,

Apparently i had gotten confused with popSelf() and getSelf() and that's
about the size of it.  getSelf() appears to be what im after as matt
suggested.

In converting to the newer version i ran into a few problems causing
lots of confusion.  My older home-made version worked fine, then after
trying to convert i found i had to do lots of stuff outside the library
in order to achieve the same results; that's also when i ran into
the 'not able to return a zero to windows' problem, since i did that
many times with my own version by, umm, would you believe, just returning
a zero? smile  Immense task huh? hee hee

While we are on the subject perhaps someone could explain why there needs to
be an emulated 'stack' involved there?

I'll try getSelf() and post results later....

Thanks for all the suggestions.

-- Al

new topic     » topic index » view message » categorize

2. Re: getSelf( )

Al wrote:

> While we are on the subject perhaps someone
> could explain why there needs to be an emulated
> 'stack' involved there?

Take it out and you'll eventually find out why - it took a lot of hair
pulling to figure this out, even though in retrospect it's fairly obvious.

Imagine that you were handling a button push in your code - the current
context is MyButton. One of the behaviors is to change the state of a
control. This happens immediately, which triggers an onChange event. The
current context is now MyControl. In the course of repainting the control,
Windows decides that it wants to repaint the entire window, triggering an
onPaint event. The context is now MyWindow.

If you don't use a stack, when your code returns from the onPaint back to
the onChange code, the context is wrongly set to MyWindow instead of
MyControl, and when the code returns to the onChange code, the context is
still set to MyWindow instead of MyButton.

The solution is to set up a context stack - every time Win32Lib processes an
event, it saves the prior context, in case some code got interrupted. Whe
it's done handling the event, it restores the context, so if it returns to
code that was 'interrupted', that code will have the correct context.

This is only an issue for 'self'; the local variable are uneffected because
they are obviously local, and probably stored on some sort of stacked frame.

-- David Cuny

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

3. Re: getSelf( )

on return val 'stack'

dave cuny wrote:
>>
Take it out and you'll eventually find out why - it took a lot of hair
pulling to figure this out, even though in retrospect it's fairly obvious.
<<

  Hmmmm.  Funny i never had a problem with it and i've been running that
code without a stack for months now.  My older version looks like this:

  In WinLib:
    global atom EventReturnVal
    EventReturnVal=1  --default

  In user exw file onEvent():
    EventReturnVal=0 --to return a zero to windows
    return

  Then in WndProc() in WinLib:
    if EventReturnVal=0 then
      EventReturnVal=1 --resets it
      return 0
    else
      --default to no action taken
    end if

Can you offer a senerio to reproduce this problem?
What are the consequences of that problem if it does occur?
What unusual behaviour first made you realize this was a problem?

--Al

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

4. Re: getSelf( )

Al Getz wrote:

> Hmmmm.  Funny i never had a problem with it and
> i've been running that code without a stack for
> months now.

I've verified that it's broken in the current release. Bother.

Run the code at the end of this message, and click the button. The first
messagebox reports one id, the second reports (after calling a getText,
which uses sendMessage) a different id.


> Can you offer a senerio to reproduce this problem?

Any time that sendMessage is called, getId() can be altered. sendMessage
immediately sends an event to the requested control/window. Since Win32Lib
has subclassed the default event handlers for all controls and windows,
either SubProc or WndProc will be invoked, depending on whether it was a
control or window that was sent the message.

The first thing that SubProc and WndProc do it attempt to identify the
Win32Lib handle of the control/window, and place the value on the stack. At
this point, you have a problem.


> What are the consequences of that problem if it does occur?

It's only an issue if you call getSelf() after a callback invokes
sendMessage. For example:

   procedure onSomeEvent( ... )
      integer self
      self = getSelf()
      sendMessage( ... )
   end procedure

won't cause any problems, because the correct value of self was retrieved
before SubProc/WndProc replaced it. If you instead wrote:

   procedure onSomeEvent( ... )
      integer self
      sendMessage( ... )
      self = getSelf()
   end procedure

then self will contain the wrong value, because it was called after
sendMessage.


> What unusual behaviour first made you realize this was a problem?

Someone reported a bug in an application which made use of getSelf(). The
app had two windows which mutually triggered paint events in the other one.

-- David Cuny



include win32lib.ew

constant
W  = create( Window, "getSelf() Bug", 0, Default, Default, 100, 140, 0 ),
B1 = create( PushButton, "Button 1", W, 10, 10, 80, 40, 0 ),
B2 = create( PushButton, "Button 2", W, 10, 50, 80, 40, 0 )

procedure click()
    object o
    -- should be the right value...
    o = message_box("self = " & sprintf( "%d", getSelf() ),"", MB_OK )
    o = getText( B2 )
    -- should be the wrong value...
    o = message_box("self = " & sprintf( "%d", getSelf() ),"", MB_OK )

end procedure
onClick[B1] = routine_id("click")

WinMain( W, Normal )

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

5. Re: getSelf( )

on return val and getSelf()

Dave Cuny wrote:
>>
It's only an issue if you call getSelf()
<<

Oh ok that explains why i havent had a problem with my old version.
I had made myId global as:

  global atom myId

and then made sure once the id was found in WndProc it was immediately
stored:

 procedure WndProc(atom hwnd,...)
   myId=find(hwnd,window_handle)

This technique didnt require getSelf().

I felt that making that global instead of alternately encapsulating
the id with a function call didnt matter that much because it was
important enough to have its own global variable; id's are key
to the operation of winlib.

Thanks for the ideas, and BTW do you have any idea how to upload
a bmp file (or short program file) to the list server?
I had tried to drag and drop the file into the list server
"compose message" text control but it didnt work.
It must work somehow, ive seen several peoples uploaded program files
recently.

Any ideas?

Thanks again,
--Al

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

6. Re: getSelf( )

Matthew Lewis wrote:

> I don't think that's correct, because windows
> (and win32lib) will handle that message before
> returning to onSomeEvent().  So the stack should
> be popped by then, right?

Run the example, and I think you'll see that there's still a bug. sad

-- David Cuny

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

7. Re: getSelf( )

> -----Original Message-----
> From: Cuny, David@DSS
>
> > I don't think that's correct, because windows
> > (and win32lib) will handle that message before
> > returning to onSomeEvent().  So the stack should
> > be popped by then, right?
>
> Run the example, and I think you'll see that there's still a bug. sad
>
> -- David Cuny
>

I agree with you, there is a bug, but there seems to be a much simpler
solution than what Derek proposes (especially since it doesn't address the
root of the problem :).

The getSelf() problem arises when WM_CTLCOLORBUTTON or WM_CTLCOLORSTATIC
messages are sent.  Win32Lib returns the handle to the brush, but never pops
the stack.

If you add an "if popSelf() then end if" at about line 17182, right before

return c_func( xGetClassLong, {getHandle(id), GCL_HBRBACKGROUND} )

the problem is fixed.  You'll need to do the same thing in SubProc, on line
17644 or so.  Oh, and in the WM_NOTIFY section in SubProc, lines 17694 and
17697.  I guess this is a good time to let everyone know that whenever you
add a return statement to WndProc or SubProc, you have to pop the stack.

Now Dave's little example will run as expected.

Matt

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

8. Re: getSelf( )

----- Original Message -----
From: "Matthew Lewis" <MatthewL at KAPCOUSA.COM>
To: <EUPHORIA at LISTSERV.MUOHIO.EDU>
Sent: Friday, September 15, 2000 5:34 AM
Subject: Re: getSelf( )


>
> I agree with you, there is a bug, but there seems to be a much simpler
> solution than what Derek proposes (especially since it doesn't address the
> root of the problem :).
>

Hi Matt,
True, I didn't seek to find the bug. Instead, I tried to find a solution to
the "bigger" issue. Namely that the event handler model that David had
choosen, is not the most robust one, and it has caused win32lib to be a
little more complex than what is required. My "solution" does away with the
internal stacks, getSelf(), returnValue(), popSelf(), pushSelf(), and all
the calls to these, plus having to remember to use these in the correct
places. And as a side-effect, makes supporting future sets of downgraded
features, or even optional features, managable - with little or no change of
existing code. Other side effects include simplified win32lib code, and
faster WndProc processing.

I will place your fix into 0.52b and release this today.

------
cheers
Derek.

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

9. Re: getSelf( )

Matthew W Lewis
KAPCO


> -----Original Message-----
> From: Cuny, David@DSS
> > What are the consequences of that problem if it does occur?
>
> It's only an issue if you call getSelf() after a callback invokes
> sendMessage. For example:
>
>    procedure onSomeEvent( ... )
>       integer self
>       self = getSelf()
>       sendMessage( ... )
>    end procedure
>
> won't cause any problems, because the correct value of self
> was retrieved
> before SubProc/WndProc replaced it. If you instead wrote:
>
>    procedure onSomeEvent( ... )
>       integer self
>       sendMessage( ... )
>       self = getSelf()
>    end procedure
>
> then self will contain the wrong value, because it was called after
> sendMessage.
>

I don't think that's correct, because windows (and win32lib) will handle
that message before returning to onSomeEvent().  So the stack should be
popped by then, right?

Matt Lewis

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

Search



Quick Links

User menu

Not signed in.

Misc Menu