From: fixer@faxcsl.dcrt.nih.gov (Chris Bearded Guacamole Tate)
Subject: Re: Modeless Dialogs - Newbie
Reply-To: fixer@faxcsl.dcrt.nih.gov
Organization: Computer Systems Laboratory, DCRT, NIH
Date: Tue, 26 Jan 1993 23:51:33 GMT

In article <25JAN199314121566@vx.cis.umn.edu>, soc1070 writes:
>I am trying to write a small app that uses a single modless dialog as
>an interface. According to IM 1, if you have a modeless dialog, regardless
>of what (Get)WaitNextEvent returns, you have to call IsDialogItem (and
>SelectDialogItem (?), I can't remember the third function and don't have
>the book in front of me) in order to get the caret to blink properly.
>
>I can't seem to get my event loop to track properly, either I can't hit
>the menus & command keys, or my radios don't switch. I know the control
>code is good (things work ok if I use a modal dialog, but the menus are
>disabled).

Yes, you need to call IsDialogEvent() and DialogSelect() even if GetNextEvent()
(or WaitNextEvent()) returns false, *if* your modeless dialog contains editable
text items.

As for command keys and menus... 

You need to check for command-key combinations *before* calling DialogSelect(),
otherwise they will be treated as normal key presses by DialogSelect() (i.e. it
doesn't call MenuKey() or any such function for you).  Also, IsDialogEvent()
will return FALSE for menu clicks other than those in enabled items in the
dialog - this includes clicks in the menu bar.  The code that I use, although
probably not perfect, looks something like this (in C):

Boolean didEvent, isDlgEvent;
...
didEvent = WaitNextEvent(everyEvent, &theEvent);
if (didEvent)
{
   isDlgEvent = IsDialogEvent(&theEvent);
   if (isDlgEvent)        // is this a modeless-dialog event?
   {
      switch (theEvent.what)
      {
         case keyDown:
         case autoKey:
            if (theEvent.modifiers & cmdKey)
               HandleMenuEvent(MenuKey(theEvent.message & charCodeMask));
            break;
         ...
         case mouseDown:
            // use FindWindow() to check for clicks in non-dialog stuff
      }

      if (DialogSelect(&theEvent, &itemHit))
      {
         // handle as you would handle stuff after calling ModalDialog()
      }
   }
}

This is pretty sketchy, but I hope it illustrates the general idea. 
DialogSelect() will call userItems etc. for you, doing all the updating that
ModalDialog() does, but can't handle special-purpose stuff, such as resizing,
zooming, menus, command keys, etc.  Note that you need to write your own
command key handling in modal dialogs anyway, so this isn't too much of a
headache.

I've run into problems involving activate/update handling when using both
windows and modeless dialogs at the same time, and when using more than one
modeless dialog simultaneously.  If I had the time, I'd go back and rewrite
everything to use pure windows instead of modeless dialogs.  The new edition of
Inside Macintosh - Toolbox Essentials recommends that if you need to be able to
resize your dialog or handle non-item-related events, you should make it a
window instead.  I think this is good advice.

------------------------------------------------------------------------------
Christopher Tate             | Return of the CryptoSig (tm):
Management Systems Designers |    XHGVMFCV GBGNKJ KJ LFJG X CXZB, KG GBXIVBJ
                             |    DMF GVKJ: QVXGBTBN DMF AM, AMP'G ZKJJ.
fixer@faxcsl.dcrt.nih.gov    |    
Newsgroups: comp.sys.mac.programmer