programming tools for Windows applications development
  Home  |   SwiftForth Archive  |   SwiftX Archive  |

Re: Callbacks -- part 2

From: Mike Ghan <mikeghan_at_logix-controls.com>
Date: Wed, 14 Nov 2001 09:14:22 -0800

Rick, what assumptions can be made regarding the state of the Forth
environment when COUNT-WINDOWS is executed? For example, is BASE set
to decimal?, PAD pointing to a buffer (if so how large?), which User
Variables are initialized? etc.

Also a note to beginning Windows programmers: Rick is delving deep
into the inner workings of SwiftForth here. Fortunately, knowledge of
many of these details is not required to write useful SwiftForth
programs. The API function EnumWindows may seem bizarre: a operating
system function call that repeatedly calls a function in your Forth
program. EnumWindows does, however, handle a particularly tricky
problem: how to determine the presence of all windows without a window
closing midway through your program (ie calling the API GetWindow
function in a loop).

Mike

----- Original Message -----
From: "Rick VanNorman" <rick_at_forth.com>
To: <sftalk_at_forth.com>
Sent: Tuesday, November 13, 2001 9:29 PM
Subject: [sftalk] Callbacks -- part 2

>
> --------------------------------------------------------------------

--
> Callbacks, part 2
> --------------------------------------------------------------------
--
>
> Last time I explored what CB: compiled in the dictionary. Tonight,
we'll
> be looking at the behavior of RUNCB.  This is a more complicated
issue,
> so please bear with me.
>
> When a callback is invoked by Windows, the cpu knows nothing about
the
> SwiftForth processor model or memory allocations or dictionary or
> anything else. So, if we want to run a SwiftForth word, we must
> establish all of that context as soon as the callback is run. This
is
> the function of RUNCB.
>
> We want to execute a Forth word to handle the callback, and words
are
> specified by their XT. So, we have to convey the XT to run to the
callback.
> This is the purpose of the CALL RUNCB compiled by CB: .
>
> Here is the code I want to examine tonight. It simply counts all of
> the application windows known to the operating system.
>
> --------------------------------------------------------------------
--
>
>
 --------------------------------------------------------------------
> HOW-MANY is a variable holding a count.
> COUNT-WINDOWS increments the count and returns TRUE.
> The line defining ALLWINDOWS compiles the following code:
>
>       ALLWINDOWS:
>                CALL   DOCREATE
>       ALLWINDOWS-DATA:
>                CALL   RUNCB
>                RET    #8
>                NOP
>                DW     XT-OF-COUNT-WINDOWS
>
> TEST zeros the counter, calls the EnumWindows api, and returns a
count.
> --------------------------------------------------------------------
 }
>
> VARIABLE HOW-MANY
>
> : COUNT-WINDOWS ( -- flag )   1 HOW-MANY +!  1 ;
>
> ' COUNT-WINDOWS 2 CB: ALLWINDOWS
>
> : TEST ( -- )   0 HOW-MANY !
>    ALLWINDOWS 0 EnumWindows DROP  HOW-MANY @ ;
>
> --------------------------------------------------------------------
--
>
> When we execute TEST, the address of ALLWINDOWS (which is an
absolute
> address of pure machine code that Windows can execute) is pushed
onto
> the datastack, along with a zero. This is in accordance to the api
> specified for EnumWindows().
>
> EnumWindows() immediately executes the callback code, building for
it a
> WINAPI stack frame on the processor stack. SwiftForth uses the
processor
> stack for its return stack -- and yes, that's where this callback is
> built. We don't know where on our return stack, only that it is
> guaranteed by the processor model not to overwrite the data already
on
> the stack. Pushed onto the stack is the zero (which could be any
data
> that TEST wanted to pass to the callback function) and a return
address
> in the Windows kernel. Execution of this portion begins at
ALLWINDOWS
> with a clean processor context with only an initialized processor
> stack. All other registers must be assumed to be uninitialized.
>
> On my system, when ALLWINDOWS is executed, the return stack has the
> following content:
>
>    77E16661   <top    the return address in the windows kernel
>    002B013E   <top+4  the handle of the window which is being
enumerated
>    00000000   <top+8  the optional parameter passed to EnumWindows
>
> Then, RUNCB is called, which leaves the return stack looking like
>
>    0046E9A9   <top    the address of ALLWINDOWS-DATA
>    77E16661   <top+4  the return address in the windows kernel
>    002B013E   <top+8  the handle of the window which is being
enumerated
>    00000000   <top+12 the optional parameter passed to EnumWindows
>
> Next time, we'll pick up here and see what RUNCB actually does.
>
> Thanks for listening.
>
> Rick
>
> P.S.  Please give feedback! Especially on things that aren't clear
or
> need more explainations. If you only want to say "good job" or other
> very nice things that make me smile, please send those privately,
not on
> the list. Let's keep the bandwidth here for Forth content.
>
> P.P.S. Not all callbacks are immediate; some wait for events
triggered
> by asychronous events such as the mouse or keyboard, others wait for
> specified times, still others wait for I/O completion. We'll discuss
> these later.
>
>
> --------------------------------------------------------------------
--
> sftalk_at_forth.com      The SwiftForth programming discussion email
list
> To unsubscribe,  send subject "unsubscribe sftalk" to
listar_at_forth.com
> For help with listar commands, send subject "help" to
listar_at_forth.com
> Archives are located at http://www.forth.com/sftalk -- check them
out!
> Search the archives!    Visit http://www.forth.com/search for
details.
----------------------------------------------------------------------
sftalk_at_forth.com      The SwiftForth programming discussion email list
To unsubscribe,  send subject "unsubscribe sftalk" to listar_at_forth.com
For help with listar commands, send subject "help" to listar_at_forth.com
Archives are located at http://www.forth.com/sftalk -- check them out!
Search the archives!    Visit http://www.forth.com/search for details.
Received on Wed Nov 14 2001 - 09:13:59 PST

This archive was generated by hypermail 2.2.0 : Fri Nov 21 2008 - 03:04:19 PST