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

Re: rref problem ...



>I am trying to access the RGNBBOX field of the VISRGN field of a WINDOWRECORD,
>however I get an error 
>
>Error: Illegal attempt to get a pointer to a :RECT within a handle
>
>The code I am using is as follows 
>
>(setf foo (rref (wptr (front-window)) :windowrecord.visrgn))
>#<A Mac Handle, Unlocked, Size 10 #x16A760>
>
>? (setf boo (rref foo :region.rgnbbox))
>> Error: Illegal attempt to get a pointer to a :RECT within a handle
>> While executing: CCL::EXPAND-HANDLE-RECORD-GET
>> Type Command-. to abort.
>See the RestartsI menu item for further choices.
>
>I have also tried (setf foo (rref (wptr (front-window)) :windowrecord.visrgn.rgnbbox)) 
>to no avail.
>
>Do you have any ideas as to what I'm doing wrong ...

MCL is attempting to protect you from having a pointer to inside of
an unlocked handle. Since an unlocked handle points at memory that
will move whenever the Mac memory manager decides to do so, this
is a good thing. Depending on exactly what you want to do, you have
a couple of possibilities.

If you just want to have access to the values inside of the bounding
box, you can do it as:

(let ((topleft (href foo :region.rgnbbox.topleft))
      (botright (href foo :region.rgnbbox.topleft)))
  ...)

or:

(let ((top (href foo :region.rgnbbox.top))
      (left (href foo :region.rgnbbox.left))
      (bottom (href foo :region.rgnbbox.bottom))
      (right (href foo :region.rgnbbox.right)))
  ...)

If you really need to RECT structure to pass to a trap that expects
one, there are two ways to do it.

This way locks the region handle while you're referencing it.
This is usually not a good idea unless you know that no region
operations will be done on the region. Region operations often require
that the size of the handle changes. This often requires the handle
to move, which it can't if it's locked.

(with-dereferenced-handles ((foo-ptr foo))
  (with-macptrs ((rect (pref foo-ptr :region.rgnbbox)))
    ...))

Preferable is:

(rlet ((rect :rect
             :topleft (href foo :region.rgnbbox.topleft)
             :botright (href foo :region.rgnbbox.botright)))
  ...)

Note that I use HREF & PREF instead of RREF. The problem with RREF is that
unless you specify the :STORAGE explicitly, it uses the default storage,
which may or may not be what you want. HREF & PREF explicitly specify that
you are referencing a handle or pointer, respectively. I actually believe
that we should eliminate RREF and the idea of a default storage type from MCL.
We didn't do so because we knew that it would break lots of code.