[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Getting to the windowpeek fields of a window



> (rref (find-window "Listener") window.strucrgn)
> 
> gives me:
> 
>> Error: Bad Pointer.
>> While executing: %GET-PTR
>> Type Command-/ to continue, Command-. to abort.
> 1 > 
> 
> rather than a pointer to a region as seems it should.  

RREF needs an honest-to-god pointer to a Pascal record on the Macintosh
memory heap.  FIND-WINDOW returns a _Lisp_ window object.  What you want
to say is

  (ask (find-window "Listener") wptr)

WPTR is a window object variable which contains a pointer to the
Macintosh window record (that C and Pascal Mac programmers use).

> What I really
> need is what should be returned by:
> 
> (rref wind window.strucrgn.rgnbbox.top)
> 
> but for this I get:
> 
>> Error: (:REGION :HANDLE) is not a record type
>> While executing: RECORD-INFO
>> Type Command-/ to continue, Command-. to abort.

You need to look at the documentation for RREF in the manual.  It has
this to say (among other things), about the field components of RREF's
ACCESSOR argument:

  If field is also a record type, its fields may be accessed by
  appending an additional period and field name.  If that field is a
  record type, the process can continue.

Now, strucrgn isn't a record, it's a handle.  RREF doesn't know that it
points to memory which just happens to contain another record.  And it
certainly doesn't know that the record is a region.  The following will
do what you want:

  (rref (rref (ask (find-window "Listener") wptr) :window.strucrgn)
             :region.rgnbbox.top)

The inner RREF returns yet another handle (which points to a Region
record).  This gets passed to the outer RREF for further processing.

Notice that since RGNBBOX is also a record (i.e. a Pascal Rect), we can
string two fields together here.

Maybe a picture'll help.  Here's how part of a window structure looks in
the Macintosh heap.

Window:
-------------
|           |
|strucrgn --+--> * ----> Region:
|...        |            -------------------
|           |            |                 |
-------------            | Rect:           |
                         | -Rgnbbox-----   |
                         | | Top       |   |
                         | | Left      |   |
                         | | Bottom    |   |
                         | | Right     |   |
                         | -------------   |
                         -------------------

Looking at the Region first: Rgnbbox is contained within the Region.
RREF is perfectly happy to jump around within the same contiguous chunk
of memory.  On the other hand, Strucrgn's data is located someoen
entirely different.  The strucrgn field in the window record is just a
pointer to that different place.  RREF knows nothing about transitioning
across pointers or handles.

These are pretty subtle issues.  You need to read the docs (which are
quite well written BTW IMHO etc.) carefully before crying bug.

Wayne();

P.S. As a matter of style I think code looks cleaner if the accessors
are written as keywords (i.e. ":region.rgnbbox" instead of
"region.rgnbbox") but I wouldn't go changing my code for someone as
obviously compulsive as myself :-)