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

[Q] Options dialog from within CustomPutFile (in MCL 2.0)



This is a technical question related to MCL 2.0, but hardened Standard File
hackers familiar with other languages may also be able to help me out.

1. What I want to do.

I want to put an "Options ..." button on a variant StandardPutFile dialog,
so that the user can choose an output file type. When the button is
clicked, a dialog will appear showing the list of available file types for
the user to select. I'm aiming at something like the way Excel 4.0 does it.

2. How I'm trying to do it.

I use ResEdit to set up an appropriate DLOG/DITL template (basically copied
from the System's -6042, but with the Options button added). I then call
_CustomPutFile with the appropriate arguments, including as the dialog
hook, the following LISP defpascal procedure (for non-MCL people, this is
just a way of getting a PASCAL callback to LISP):

   (defpascal CHOOSE-NEW-FILE-WITH-OPTIONS-DIALOG-HOOK 
              (:word ItemNumber
                     :ptr  DialogPtr
                     :ptr DataPtr
                     :word)
     (declare (ignore DialogPtr DataPtr)
              (special *extended-standard-file-options-function*))
     (case ItemNumber
    
       ;;; Has the special "Options ..." button been hit? 
       ;;; If so, call the Options function, whatever it is
    
       (13
        (catch :cancel
          (when *extended-standard-file-options-function*
            (funcall *extended-standard-file-options-function*)))
        ItemNumber)
    
    ;;; If one of the standard items has been clicked, pass its 
    ;;; number back for the default dialog hook to deal with.
    
    (T ItemNumber)))

The global *extended-standard-file-options-function* contains a LISP
function which should be called when the options button is clicked; 13 is
the number of the options button in my DLOG.

3. What goes wrong.

This works fine provided I don't try to make the options function open a
window. My first test simply printed something on the Listener, and that
worked OK, making me think that I've got it basically right. However, when
I actually try displaying a modal dialog to get the user's response (I
tested it with 'y-or-n-dialog', which I figured should be fairly robust),
the dialog comes up fine, behaves appropriately, and then when it closes
..

    BUS ERROR!

Specifically, _GetClip blows up. My best guess is that the current grafport
is getting lost when I open the dialog, so that when the file dialog box
tries to redraw itself, _GetClip is called on an inappropriate address,
with lamentable results.

Presumably I should be preserving the grafport and restoring it when I've
finished. But ... I tried modifying the function above, wrapping the call
to the options function with code to create a ':grafport' record with
'rlet', store the current port to it with #_GetPort and then restore it
with #_SetPort when I was done. I'm far from convinced that I was going
about it the right way, but at least it didn't crash when I tried the
'safe' example (writing to the Listener when the options button is
clicked), which suggests that I can't have been doing anything too
misguided. But when I tried opening a window ... same thing again.

4. The question.

What's happening here? I'd have expected MCL to restore the current
grafport properly after a modal dialog, but maybe I'm wrong about it being
a grafport problem. I've done something similar before (putting a 'New'
button on a 'GetFile' dialog, ResEdit style, so that the user can launch a
PutFile dialog off a GetFile in order to make a new file rather than open
an existing one) and that worked fine. This time however ...

All suggestions, pointers to appropriate code etc. will be gratefully
received.

5. Tie-breaker question

To win a no-expenses paid, luxury holiday for none in Spitzbergen, answer
the following question: how can I do this properly, by putting a pop-up
menu actually on the PutFile dialog box (as seen in any civilised
application), instead of messing about with secondary dialogs? I spent a
while trying that this morning and I'm still picking bits of the
application heap out of my hair. When my experimental code to do that ran
off into the weeds, it didn't do so with anything as graceful or innocuous
as a bus error ... :-(

    Thanks in advance

                         A

x--------------------------------------------------------------------x
| Angus McIntyre    angus@aegypt.demon.co.uk    angus@arti.vub.ac.be |
|--------------------------------------------------------------------|
|   "I am here by the will of the people ... and I will not leave    |
|    until I get my raincoat back." ['Metrophage', Richard Kadrey]   |
x--------------------------------------------------------------------x