From: bill@cambridge.apple.com (Bill St. Clair)
Newsgroups: comp.lang.lisp.mcl
Subject: Re: Working with pointers
Date: 13 Nov 92 17:41:25 GMT

>I've been playing around all morning, trying to get some resources to work properly.
>I need a pointer to an icon (for an icon-dialog-item) so I used the resource package
>to get a handle, but when I try to use the pointer, all sorts of problems occur.
>

>(with-open-resource-file (*my-rsrcs* "Application.rsrc")
>  (defparameter *icon-hndl-1* (get-resource "ICON" "Telephone"))
>  (defparameter *icon-hndl-2* (get-resource "ICON" "Honda")))

Here's your first problem. WITH-OPEN-RESOURCE closes the resource
file when it exits. This will deallocate (e.g. #_DisposeHandle) any
resources that belong to that file. If you want to close the
file and keep the resources, you'll have to call DETACH-RESOURCE on them:

(defvar *icon-hndl-1*)
(defvar *icon-hndl-2*)
(with-open-resource-file (*my-rsrcs* "Application.rsrc")
  (detach-resource (setq *icon-hndl-1* (get-resource "ICON" "Telephone")))
  (detach-resource (setq *icon-hndl-2* (get-resource "ICON" "Honda"))))

>  I next try to get a pointer to use by:
>
>(when *icon-hndl-1*
>  (#_MoveHHi *icon-hndl-1*)
>  (#_HLock *icon-hndl-1*)
>  (defparameter *my-icon-ptr* (%hget-ptr *icon-hndl-1*)))

Two problems here. First off, you should say (%get-ptr *icon-hndl-1*),
not (%hget-ptr *icon-hndl-1*), to get the pointer from a handle. %hget-ptr
does a double indirection, %get-ptr does a single indirection.

>
>I should now have a locked, dereferenced pointer, but when I use it to define
>and icon-dialog-item I get into trouble:
>
>(setf my-window (make-instance 'ccl::scrolling-window :color-p t))
>(add-subviews my-window (make-instance 'icon-dialog-item
>                     :icon *my-icon-ptr*
>                     :view-position #@(50 0)))
>
>Inspecting *my-icon-ptr* shows it to be:
>    #<A Mac Handle, Unlocked, Size 40 #x263364>
>as it should be.

As you may have noticed, ICON-DIALOG-ITEM's VIEW-DRAW-CONTENTS method
calls PLOT-ICON to actually do the work. PLOT-ICON's documentation says:

;;  plot-icon
;;
;;  a function for displaying icons.  It can be passed a pointer or a number
;;    if passed a pointer, it assumes this is a pointer to an icon record.
;;    if passed a number, it assumes this is the resource id of an icon.
;;    Draws to the current grafport, so call it inside WITH-FOCUSED-VIEW.

Unfortunately, this is not quite right. Instead of "an icon record" it should
say "an icon handle", which is what the #_PlotIcon & #_PlotCIcon traps expect.

Here's a working example:

(require "ICON-DIALOG-ITEM")
(require "RESOURCES")

(defvar *icon-1*)

; DEF-LOAD-POINTERS so that we can compile the file and SAVE-APPLICATION
; and the resources will be loaded when the application starts up.
; (Actually, if you want to save an application, you usually put the
; icons in the application's own resource fork so that the
; WITH-OPEN-RESOURCE-FILE and DETACH-RESOURCE are unnecessary [an
; application's resource fork is always open while it is running].)
(def-load-pointers initialize-icons ()
  (with-open-resource-file (refnum "Application.rsrc")
    (detach-resource (setq *icon-1* (get-resource "ICON" "Loudspeaker")))))

(setf my-window (make-instance 'window :color-p t))
(add-subviews my-window (make-instance 'icon-dialog-item
                          :icon *icon-1*
                          :view-position #@(50 0)))