From: Lee_Robert_Willis@cup.portal.com
Newsgroups: comp.sys.amiga.programmer
Subject: Re: Multiple Window's messages....
Date: Thu, 16 Apr 92 15:41:40 PDT
Organization: The Portal System (TM)
Distribution: world

>  Ok...I am writing a program that will open one Control window, and up to
>four other windows. I will be getting IDCMP messages from the Control window
>(such as CLOSEWINDOW) and IF another window has been opened I want to recieve
>messages from it (such as REFRESHWINDOW). How would I construct a Wait()
>so that it will wait for messages from any open windows? Is there some way
>to combine all the messages into one and still figure out which window each
>came from? Thanks for the help....

What you want to do is

   1) Create your own message port.
   2) Open all your windows using this message port as the UserPort.

I just happen to have what some handy code to do this!  Hope it helps.

Lee




/*F:OpenWindowWithSharedUserPort*

------------------------------------------------------------

               OpenWindowWithSharedUserPort

------------------------------------------------------------

Name:          OpenWindowWithSharedUserPort - opens a window with a shared port.
Syntax:        | window = OpenWindowWithSharedPort( nw, port );
               | struct Window    *window;
               | struct NewWindow *nw;
               | struct MsgPort   *port;

Description:   To handle multiple windows within the one application, the
               best method (usually) is to have all the windows share the
               same UserPort.  This way, one can still do a 'WaitPort()' or
               'WaitForMessage()'.  (Otherwise one has to mess with signal
               bits.)

               In order to force a window to have a specific UserPort, one
               must first create the port (using 'CreatePort()'), and then
               there is a sequence of steps involved in opening the window.
               (This is described in the 1.3 RKM Libraries and Devices manual
               on page 167 "SETTING UP YOUR OWN IDCMP MONITOR TASK AND USER
               PORT")

               'OpenWindowWithSharedPort()' does all the steps after the
               creation of the MsgPort.   All you do is pass in the NewWindow
               structure and the message port, and 'OpenWindowWithSharedPort'
               will open the window and do the UserPort setup.

               NOTE: Windows opened with this function must be closed using
               'CloseWindowWithSharedPort()', NOT 'CloseWindow()'!

See Also:      CloseWindowWithSharedPort
Author:        Lee R. Willis
*/

struct Window *OpenWindowWithSharedUserPort( struct NewWindow *nw,
                                             struct MsgPort   *shared )
{
   ULONG IDCMPbuf;
   struct Window *w;

   IDCMPbuf       = nw->IDCMPFlags;
   nw->IDCMPFlags = 0;  /* no IDCMP flags. */

   if (w = OpenWindow( nw ))
   {
      Forbid();
      w->UserPort = shared;         /* assign UserPort. */
      ModifyIDCMP( w, IDCMPbuf );   /* turn on IDCMP */
      Permit();
   }
   nw->IDCMPFlags = IDCMPbuf; /* return 'nw' to its previous state. */
   return w;
}




/*F:CloseWindowWithSharedUserPort*

------------------------------------------------------------

               CloseWindowWithSharedUserPort

------------------------------------------------------------

Name:          CloseWindowWithSharedUserPort - closes a window with a shared port.
Syntax:        | CloseWindowWithSharedPort( w );
               | struct Window *w;
Description:   To handle multiple windows within the one application, the
               best method (usually) is to have all the windows share the
               same UserPort.  This way, one still to a 'WaitPort()' or
               'WaitForMessage()'.  (Otherwise one has to mess with signal
               bits.)

               Closing such a window requires some care, as Intuition normally
               deallocates the UserPort for such a window on closing, and
               since the port is shared, other windows are still using it!
               (This is described in the 1.3 RKM Libraries and Devices manual
               on page 167 "SETTING UP YOUR OWN IDCMP MONITOR TASK AND USER
               PORT")

               'CloseWindowWithSharedPort()' does all this for you.

See Also:      OpenWindowWithSharedPort
Author:        Lee R. Willis
*/


void CloseWindowWithSharedUserPort( struct Window *w )
   /* Taken from 1.3 RKM:L&D, page 171, 'CloseWindowSafely()' */
{
   Forbid();               /* Turn off multitasking */

   StripIntuiMessages( w );  /* remove all messages for this window. */

   w->UserPort = NULL;
   ModifyIDCMP( w, 0 ); /* prevents new messages from occuring. */
   Permit();

   CloseWindow( w );
}


void StripIntuiMessages( struct Window *w )
/*
   *ASSUMES* a Forbid() has been called!

   Taken from 1.3 RKM:L&D, page 171
*/
{
   struct MsgPort *mp;
   struct IntuiMessage *msg, *succ;

   mp = w->UserPort;

   /*
    * Loop through all messages waiting at this port, remove any
    * which are for Window 'w'.
    */

   msg = (struct IntuiMessage*) mp->mp_MsgList.lh_Head;
   while( succ = (struct IntuiMessage*) msg->ExecMessage.mn_Node.ln_Succ )
   {
      if (msg->IDCMPWindow == w)
      {
         Remove((struct Node *) msg);
         ReplyMsg((struct Message *) msg);
      }

      msg = succ;
   }
}
Newsgroups: comp.sys.amiga.programmer