(*************************************************************************

     $RCSfile: AppMenuItem.mod $
  Description:

   Created by: fjc (Frank Copeland)
    $Revision: 1.4 $
      $Author: fjc $
        $Date: 1995/01/25 23:56:20 $

  Copyright © 1994-1995, Frank Copeland.
  This example program is part of Oberon-A.
  See Oberon-A.doc for conditions of use and distribution.

*************************************************************************)

<* STANDARD- *>

MODULE AppMenuItem;

IMPORT
  SYS := SYSTEM,
  e   := Exec,
  u   := Utility,
  d   := Dos,
  wb  := Workbench,
  Out;

CONST
  VersionTag = "$VER: AppMenuItem 1.2 (19.9.94)\r\n";

VAR
  myport  : e.MsgPortPtr;
  appitem : wb.AppMenuItemPtr;
  appmsg  : wb.AppMessagePtr;

  result, x, count : LONGINT;
  success : BOOLEAN;
  file : d.FileHandlePtr;

  userData : e.STRPTR;

BEGIN (* AppMenuItem *)
  myport := NIL; appitem := NIL; appmsg := NIL;
  result := 0; x := 0; count := 0; success := FALSE;
  IF wb.base.version >= 37 THEN
    myport := e.CreateMsgPort();
    IF myport # NIL THEN
      (* Add our own AppMenuItem to the Workbench Tools Menu *)
      appitem := wb.AddAppMenuItem
        ( 0,                                 (* Our ID# for item *)
          SYS.VAL (LONGINT,
            SYS.ADR ("SYS:Utilities/More")), (* Our UserData *)
          "Browse Files",                    (* MenuItem text *)
          myport, u.done );                  (* MsgPort, no tags *)
      IF appitem # NIL THEN
        Out.String
          ("Select Workbench Tools demo menuitem 'Browse Files'\n");

        (* For this example, we allow the AppMenuItem to be selected *)
        (* only once, then we remove it and exit                     *)
        e.WaitPort (myport);
        LOOP
          IF count >= 1 THEN EXIT END;
          appmsg := SYS.VAL (wb.AppMessagePtr, e.GetMsg (myport));
          IF appmsg = NIL THEN EXIT END;
          (* Handle messages from the AppMenuItem - we have only one *)
          (* item so we don't have to check its appmsg.id number.    *)
          (* We'll System() the command string that we passed as     *)
          (* userdata when we added the menu item.                   *)
          (* We find our userdata pointer in appmsg.userData         *)

          Out.String ("User picked AppMenuItem with ");
          Out.Int (appmsg.numArgs, 0);
          Out.String (" icons selected\n");
          FOR x := 0 TO appmsg.numArgs - 1 DO
            Out.String ("  #"); Out.Int (x + 1, 0);
            Out.String (" name = '"); Out.String (appmsg.argList[x].name^);
            Out.String ("'\n");
          END;
          INC (count);
          file := d.Open
            ( "CON:0/40/640/150/AppMenu Example/auto/close/wait",
              d.oldFile );
          IF file # NIL THEN
            userData := SYS.VAL (e.STRPTR, appmsg.userData);
            Out.String ("userData='"); Out.String (userData^);
            Out.String ("'\n");
            result := d.SystemTags
              ( userData^,
                d.sysInput,  file,
                d.sysOutput, NIL,
                d.sysAsynch, d.DOSTRUE,
                u.done );
            Out.String ("result = "); Out.Int (result, 0); Out.Ln;
            (* If Asynch System() itself fails, we must close file *)
            IF result = -1 THEN d.OldClose (file) END
          END;
          e.ReplyMsg (appmsg)
        END;
        success := wb.RemoveAppMenuItem (appitem)
      END;
      (* Clear away any messages that arrived at the last moment *)
      LOOP
        appmsg := SYS.VAL (wb.AppMessagePtr, e.GetMsg (myport));
        IF appmsg = NIL THEN EXIT END;
        e.ReplyMsg (appmsg)
      END;
      e.DeleteMsgPort (myport)
    END
  END
END AppMenuItem.
