home *** CD-ROM | disk | FTP | other *** search
/ YPA: Your Privacy Assured / YPA.ISO / other_goodies / utilities / amigaguid.lha / AmigaGuide / AG_V39 / Source / advaghelp.c < prev    next >
C/C++ Source or Header  |  1993-01-08  |  19KB  |  742 lines

  1. /* aghelp.c
  2.  *
  3.  * (c) Copyright 1992 Commodore-Amiga, Inc.  All rights reserved.
  4.  *
  5.  * This software is provided as-is and is subject to change; no warranties
  6.  * are made.  All use is at your own risk.  No liability or responsibility
  7.  * is assumed.
  8.  *
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <exec/execbase.h>
  14. #include <exec/libraries.h>
  15. #include <intuition/screens.h>
  16. #include <intuition/intuition.h>
  17. #include <graphics/gfx.h>
  18. #include <graphics/text.h>
  19. #include <libraries/amigaguide.h>
  20. #include <libraries/gadtools.h>
  21. #include <utility/hooks.h>
  22. #include <utility/tagitem.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25.  
  26. #include <clib/alib_protos.h>
  27. #include <clib/amigaguide_protos.h>
  28. #include <clib/dos_protos.h>
  29. #include <clib/exec_protos.h>
  30. #include <clib/gadtools_protos.h>
  31. #include <clib/graphics_protos.h>
  32. #include <clib/intuition_protos.h>
  33. #include <clib/utility_protos.h>
  34.  
  35. #include <pragmas/amigaguide_pragmas.h>
  36. #include <pragmas/dos_pragmas.h>
  37. #include <pragmas/exec_pragmas.h>
  38. #include <pragmas/gadtools_pragmas.h>
  39. #include <pragmas/graphics_pragmas.h>
  40. #include <pragmas/intuition_pragmas.h>
  41. #include <pragmas/utility_pragmas.h>
  42.  
  43. /*****************************************************************************/
  44.  
  45. #define    DB(x)    x
  46.  
  47. /*****************************************************************************/
  48.  
  49. void kprintf (void *, ...);
  50.  
  51. /*****************************************************************************/
  52.  
  53. #define    BASENAME    "ADVAGHELP"
  54. #define    BASENAME_LENGTH    9
  55.  
  56. /*****************************************************************************/
  57.  
  58. #define ASM        __asm __saveds
  59. #define REG(x)        register __ ## x
  60.  
  61. /*****************************************************************************/
  62.  
  63. struct AppInfo
  64. {
  65.     struct Process        *ai_Process;        /* Our process address */
  66.     struct Screen        *ai_Screen;        /* Screen that our application will open on */
  67.     APTR             ai_VI;            /* GadTools visual info */
  68.     struct Window        *ai_Window;        /* Window pointer */
  69.     struct Menu            *ai_Menu;        /* Menus */
  70.  
  71.     /* Gadgets that we want to set attributes on */
  72.     struct Gadget        *ai_GStatus;        /* Status window */
  73.  
  74.     /* Help related information */
  75.     LONG             ai_NHID;        /* Unique id */
  76.     ULONG             ai_NHFlags;        /* Help related flags */
  77.     UBYTE             ai_NHName[64];        /* Unique name */
  78.     struct Hook             ai_NHHook;        /* Dynamic node host hook */
  79.     struct AmigaGuideHost    *ai_NH;            /* Dynamic node host */
  80.     AMIGAGUIDECONTEXT         ai_AmigaGuide;        /* Pointer to the AmigaGuide context */
  81.     struct NewAmigaGuide     ai_NAG;        /* Used to start AmigaGuide */
  82.     LONG             ai_Region;        /* Region that the mouse if over */
  83.  
  84.     /* Control information */
  85.     BOOL             ai_Done;        /* Done yet? */
  86. };
  87.  
  88. #define    AGHF_CONTINUOUS    (1L<<0)
  89.  
  90. /*****************************************************************************/
  91.  
  92. extern struct Library *SysBase;
  93. extern struct Library *DOSBase;
  94. struct Library *AmigaGuideBase;
  95. struct Library *GadToolsBase;
  96. struct Library *GfxBase;
  97. struct Library *IntuitionBase;
  98. struct Library *UtilityBase;
  99.  
  100. /*****************************************************************************/
  101.  
  102. /* Context ID's to be sent to AmigaGuide */
  103. STRPTR context[] =
  104. {
  105.     "MAIN",
  106.     "STATUS",
  107.     "LISTVIEW",
  108.     "ACCEPT",
  109.     "CANCEL",
  110.     "QUIT",
  111.     "NONCONTINUOUS",
  112.     "CONTINUOUS",
  113.     NULL
  114. };
  115.  
  116. /*****************************************************************************/
  117.  
  118. #define    MCMD_MAIN        0
  119. #define    MCMD_STATUS        1
  120. #define    MCMD_LISTVIEW        2
  121. #define    MCMD_ACCEPT        3
  122. #define    MCMD_CANCEL        4
  123. #define    MCMD_QUIT        5
  124. #define    MCMD_NONCONTINUOUS    6
  125. #define    MCMD_CONTINUOUS        7
  126.  
  127. /*****************************************************************************/
  128.  
  129. /* Simple little prompts to display within the status window */
  130. STRPTR quickhelp[] =
  131. {
  132.     "AGHelp main window.",
  133.     "Quick-Help or status window.",
  134.     "List of absolutely nothing.",
  135.     "Accept changes.",
  136.     "Cancel changes.",
  137.     "",
  138.     "Window sizing gadget.",
  139.     "Window drag bar.",
  140.     "Screen drag bar.",
  141.     "Window depth gadget.",
  142.     "Screen depth gadget.",
  143.     "Window zoom gadget.",
  144.     "",
  145.     "Window close gadget.",
  146.     NULL
  147. };
  148.  
  149. #define    MAX_REGION    14
  150.  
  151. /*****************************************************************************/
  152.  
  153. struct TextAttr topaz8 = {"topaz.font", 8,};
  154.  
  155. /*****************************************************************************/
  156.  
  157. #define    IDCMP_FLAGS    IDCMP_RAWKEY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_MENUHELP | \
  158.             IDCMP_GADGETUP | IDCMP_MOUSEMOVE | IDCMP_GADGETHELP
  159.  
  160. /*****************************************************************************/
  161.  
  162. #define    V(x)    ((void *)(x))
  163.  
  164. struct NewMenu main_menu[] =
  165. {
  166.     {NM_TITLE,    "Project",},
  167.     {NM_ITEM,    "Quit",            "Q", NULL, NULL, V(MCMD_QUIT),},
  168.  
  169.     {NM_TITLE,    "Settings",},
  170.     {NM_ITEM,    "Continuous Help?",    "",  CHECKIT | MENUTOGGLE, NULL, V(MCMD_NONCONTINUOUS),},
  171.     {NM_END,},
  172. };
  173.  
  174. /*****************************************************************************/
  175. /*****************************************************************************/
  176. /*****************************************************************************/
  177.  
  178. VOID DisplayError (LONG err)
  179. {
  180.     printf ("%s\n", GetAmigaGuideString (err));
  181. }
  182.  
  183. /*****************************************************************************/
  184.  
  185. void HandleEvents (struct AppInfo * ai)
  186. {
  187.     struct Window *win = ai->ai_Window;
  188.     struct AmigaGuideMsg *agm;
  189.     struct IntuiMessage *imsg;
  190.     struct MenuItem *item;
  191.     ULONG sigr = 0L;
  192.     ULONG sigi = 0L;
  193.     ULONG sigb = 0L;
  194.     UWORD selection;
  195.     STRPTR label;
  196.     LONG region;
  197.     LONG qhelp;
  198.     LONG id;
  199.  
  200.     /* Show that we're not done running the application yet */
  201.     ai->ai_Done = FALSE;
  202.  
  203.     /* Get our signal bits */
  204.     sigb = AmigaGuideSignal (ai->ai_AmigaGuide);
  205.     sigi = (1L << win->UserPort->mp_SigBit);
  206.  
  207.     /* Clear the AmigaGuide context */
  208.     SetAmigaGuideContext (ai->ai_AmigaGuide, 0L, NULL);
  209.  
  210.     /* Continue until done */
  211.     while (!(ai->ai_Done))
  212.     {
  213.     /* Wait for something to happen */
  214.     sigr = Wait (sigb | sigi);
  215.  
  216.     /* Pull Intuition & GadTools messages */
  217.     while (imsg = GT_GetIMsg (win->UserPort))
  218.     {
  219.         switch (imsg->Class)
  220.         {
  221.         case IDCMP_CLOSEWINDOW:
  222.             ai->ai_Done = TRUE;
  223.             break;
  224.  
  225.         case IDCMP_MENUPICK:
  226.             selection = imsg->Code;
  227.             while (selection != MENUNULL)
  228.             {
  229.             item = ItemAddress (win->MenuStrip, selection);
  230.  
  231.             switch ((LONG)MENU_USERDATA (item))
  232.             {
  233.                 case MCMD_QUIT:
  234.                 ai->ai_Done = TRUE;
  235.                 break;
  236.  
  237.                 case MCMD_NONCONTINUOUS:
  238.                 if (item->Flags & CHECKED)
  239.                     ai->ai_NHFlags |= AGHF_CONTINUOUS;
  240.                 else
  241.                     ai->ai_NHFlags &= ~AGHF_CONTINUOUS;
  242.                 break;
  243.             }
  244.  
  245.             selection = item->NextSelect;
  246.             }
  247.             break;
  248.  
  249.         case IDCMP_MENUHELP:
  250.             if (item = ItemAddress (win->MenuStrip, imsg->Code))
  251.             {
  252.             /* Get the context ID */
  253.             id = (LONG) MENU_USERDATA (item);
  254.  
  255.             /* Adjust for being selected */
  256.             if (item->Flags & CHECKED)
  257.                 id++;
  258.  
  259.             /* Display the node */
  260.             SendAmigaGuideCmd (ai->ai_AmigaGuide, NULL, AGA_Context, id, TAG_DONE);
  261.             }
  262.  
  263.             break;
  264.  
  265.         case IDCMP_GADGETUP:
  266.             switch (((struct Gadget *)imsg->IAddress)->GadgetID)
  267.             {
  268.             case MCMD_ACCEPT:
  269.             case MCMD_CANCEL:
  270.                 ai->ai_Done = TRUE;
  271.                 break;
  272.             }
  273.             break;
  274.  
  275.         case IDCMP_GADGETHELP:
  276.             qhelp = region = -1;
  277.             if (imsg->IAddress == NULL)
  278.             {
  279.             /* Not over our window */
  280.             DB (printf ("not over our window\n"));
  281.             }
  282.             else if (imsg->IAddress == (APTR) win)
  283.             {
  284.             /* Over our window */
  285.             DB (printf ("over window\n"));
  286.             qhelp = region = 0;
  287.             }
  288.             else
  289.             {
  290.  
  291.             /*
  292.              * Detect system gadgets.  Figure out by looking at
  293.              * system-gadget-type bits in GadgetType field:
  294.              */
  295.             LONG sysgtype = ((struct Gadget *) imsg->IAddress)->GadgetType & 0xF0;
  296.  
  297.             /* Set the region */
  298.             qhelp = (sysgtype >> 4) + 5;
  299.             region = HTFC_SYSGADS + sysgtype;
  300.  
  301.             switch (sysgtype)
  302.             {
  303.                 case GTYP_SIZING:
  304.                 DB (printf ("Gadget Help for window sizing gadget\n"));
  305.                 break;
  306.  
  307.                 case GTYP_WDRAGGING:
  308.                 DB (printf ("Gadget Help for window drag-bar\n"));
  309.                 break;
  310.  
  311.                 case GTYP_WUPFRONT:
  312.                 DB (printf ("Gadget Help for window depth gadget\n"));
  313.                 break;
  314.  
  315.                 case GTYP_WDOWNBACK:
  316.                 DB (printf ("Gadget Help for window zoom gadget\n"));
  317.                 break;
  318.  
  319.                 case GTYP_CLOSE:
  320.                 DB (printf ("Gadget Help for window close gadget\n"));
  321.                 break;
  322.  
  323.                 case 0:
  324.  
  325.                 /*
  326.                  * In this example, we only have one gadget, so
  327.                  * we know which one it is.  Normally, you'd
  328.                  * have to figure that out here, using the
  329.                  * usual techniques you already use for other
  330.                  * gadget messages.
  331.                  */
  332.                 DB (printf ("Gadget id %d, code %d\n",
  333.                     ((struct Gadget *)imsg->IAddress)->GadgetID, imsg->Code));
  334.                 qhelp = region = (LONG) ((struct Gadget *)imsg->IAddress)->GadgetID;
  335.                 break;
  336.  
  337.                 default:
  338.                 DB (printf ("Gadget Help on some other system gadget\n"));
  339.                 break;
  340.             }
  341.             }
  342.  
  343.             /* Remember the region */
  344.             ai->ai_Region = region;
  345.  
  346.             /* Range check the region */
  347.             label = NULL;
  348.             if ((qhelp >= 0) && (qhelp < MAX_REGION))
  349.             label = quickhelp[qhelp];
  350.  
  351.             /* Update the quick-help information */
  352.             GT_SetGadgetAttrs (ai->ai_GStatus, ai->ai_Window, NULL, GTTX_Text, label, TAG_DONE);
  353.  
  354.             /* Send the command immediately if we are continuous */
  355.             if ((ai->ai_Region >= 0) && (ai->ai_NHFlags & AGHF_CONTINUOUS))
  356.             {
  357.             /* Display the node */
  358.             SendAmigaGuideCmd (ai->ai_AmigaGuide, NULL,
  359.                        AGA_Context, ai->ai_Region,
  360.                        TAG_DONE);
  361.             }
  362.             break;
  363.  
  364.         case IDCMP_RAWKEY:
  365.             /* Help key pressed */
  366.             if (imsg->Code == 95)
  367.             {
  368.             /* Display the node */
  369.             SendAmigaGuideCmd (ai->ai_AmigaGuide, NULL,
  370.                        AGA_Context, ai->ai_Region,
  371.                        TAG_DONE);
  372.             }
  373.             break;
  374.         }
  375.  
  376.         /* Reply to the message */
  377.         GT_ReplyIMsg (imsg);
  378.     }
  379.  
  380.     /* Process AmigaGuide messages */
  381.     if (sigr & sigb)
  382.     {
  383.         /* process amigaguide messages */
  384.         while (agm = GetAmigaGuideMsg (ai->ai_AmigaGuide))
  385.         {
  386.         /* check message types */
  387.         switch (agm->agm_Type)
  388.         {
  389.             /* AmigaGuide is ready for us */
  390.             case ActiveToolID:
  391.             break;
  392.  
  393.             /* This is a reply to our cmd */
  394.             case ToolCmdReplyID:
  395.             if (agm->agm_Pri_Ret)
  396.                 DisplayError (agm->agm_Sec_Ret);
  397.             break;
  398.  
  399.             /* This is a status message */
  400.             case ToolStatusID:
  401.             if (agm->agm_Pri_Ret)
  402.                 DisplayError (agm->agm_Sec_Ret);
  403.             break;
  404.  
  405.             /* Shutdown message */
  406.             case ShutdownMsgID:
  407.             if (agm->agm_Pri_Ret)
  408.                 DisplayError (agm->agm_Sec_Ret);
  409.             break;
  410.  
  411.             default:
  412.             break;
  413.         }
  414.  
  415.         /* Reply to the message */
  416.         ReplyAmigaGuideMsg (agm);
  417.         }
  418.     }
  419.     }
  420. }
  421.  
  422. /*****************************************************************************/
  423. /*****************************************************************************/
  424. /*****************************************************************************/
  425.  
  426. STRPTR nodeNames[] =
  427. {
  428.     "WINDOW",
  429.     "PROCESS",
  430.     NULL,
  431. };
  432.  
  433. STRPTR nodeTitles[] =
  434. {
  435.     "Project Window Information",
  436.     "Project Process Information",
  437. };
  438.  
  439. enum
  440. {
  441.     NM_WINDOW,
  442.     NM_PROCESS,
  443. };
  444.  
  445. LONG Tokenize (struct AppInfo *ai, STRPTR name)
  446. {
  447.     UBYTE buffer[32];
  448.     LONG i;
  449.  
  450.     /* Chop the prefix from the node name */
  451.     strcpy (buffer, &name[strlen(BASENAME)+1]);
  452.  
  453.     /* Find the token */
  454.     for (i = 0; nodeNames[i]; i++)
  455.     if (Stricmp (buffer, nodeNames[i]) == 0)
  456.         return i;
  457.     return -1;
  458. }
  459.  
  460. /*****************************************************************************/
  461.  
  462. ULONG ASM nodehost (REG (a0) struct Hook *h, REG (a2) STRPTR o, REG (a1) Msg msg)
  463. {
  464.     struct AppInfo *ai = (struct AppInfo *) h->h_Data;
  465.     struct opFindHost *ofh = (struct opFindHost *)msg;
  466.     struct opNodeIO *onm = (struct opNodeIO *)msg;
  467.     ULONG retval = FALSE;
  468.     LONG token;
  469.     ULONG id;
  470.  
  471.     switch (msg->MethodID)
  472.     {
  473.     case HM_FINDNODE:
  474.         /* Get the help group */
  475.         id = GetTagData (AGA_HelpGroup, 0L, ofh->ofh_Attrs);
  476.  
  477.         /* Request for the initial main node? */
  478.         if (id == 0)
  479.         {
  480.         /* We have to have a MAIN node, even if we never use it */
  481.         if (Stricmp (ofh->ofh_Node, "main") == 0)
  482.         {
  483.             /* Show that it is ours */
  484.             retval = TRUE;
  485.         }
  486.         }
  487.         /* Request for one of our true dynamic nodes? */
  488.         else if (id == ai->ai_NHID)
  489.         {
  490.         if ((Strnicmp (ofh->ofh_Node, BASENAME, BASENAME_LENGTH) == 0) &&
  491.             ((token = Tokenize (ai, ofh->ofh_Node)) >= 0))
  492.         {
  493.             /* Show that it is ours */
  494.             retval = TRUE;
  495.  
  496.             /* Set the node title */
  497.             ofh->ofh_Title = nodeTitles[token];
  498.         }
  499.         }
  500.         break;
  501.  
  502.     case HM_OPENNODE:
  503.         /* Allocate the document buffer */
  504.         if (onm->onm_DocBuffer = AllocVec (512, MEMF_CLEAR))
  505.         {
  506.         /* Build the document */
  507.         switch (token = Tokenize (ai, onm->onm_Node))
  508.         {
  509.             case NM_WINDOW:
  510.             sprintf (onm->onm_DocBuffer, "Window: %08lx\n  Size: %ld, %ld, %ld, %ld\n Group: %ld\n",
  511.                  ai->ai_Window,
  512.                  (LONG) ai->ai_Window->LeftEdge, (LONG) ai->ai_Window->TopEdge,
  513.                  (LONG) ai->ai_Window->Width, (LONG) ai->ai_Window->Height,
  514.                  ai->ai_NHID);
  515.             break;
  516.  
  517.             case NM_PROCESS:
  518.             sprintf (onm->onm_DocBuffer, "Process: %08lx\n",
  519.                  ai->ai_Process);
  520.             break;
  521.         }
  522.  
  523.         /* Set the buffer length */
  524.         onm->onm_BuffLen = strlen (onm->onm_DocBuffer);
  525.  
  526.         /* Remove the node from the database when done */
  527.         onm->onm_Flags |= HTNF_CLEAN;
  528.  
  529.         /* Show successful open */
  530.         retval = TRUE;
  531.         }
  532.         break;
  533.  
  534.     case HM_CLOSENODE:
  535.         /* Free the document buffer */
  536.         FreeVec (onm->onm_DocBuffer);
  537.         retval = TRUE;
  538.         break;
  539.  
  540.     case HM_EXPUNGE:
  541.         break;
  542.     }
  543.  
  544.     return retval;
  545. }
  546.  
  547. /*****************************************************************************/
  548. /*****************************************************************************/
  549. /*****************************************************************************/
  550.  
  551. void main (void)
  552. {
  553.     struct ExecBase *SysBase = (*((struct ExecBase **) 4));
  554.     struct Gadget *anchor = NULL;
  555.     struct NewGadget ng;
  556.     struct AppInfo *ai;
  557.     struct Gadget *gad;
  558.  
  559.     /* Make sure we are running with V39 or greater */
  560.     if (SysBase->LibNode.lib_Version < 39)
  561.     {
  562.     printf ("requires V39\n");
  563.     }
  564.     /* Allocate our global data */
  565.     else if (ai = AllocVec (sizeof (struct AppInfo), MEMF_CLEAR))
  566.     {
  567.     /* Our process */
  568.     ai->ai_Process = (struct Process *) FindTask (NULL);
  569.  
  570.     /* Initialize the node host hook */
  571.     ai->ai_NHHook.h_Entry = nodehost;
  572.     ai->ai_NHHook.h_Data  = ai;
  573.  
  574.     /* Open the ROM libraries */
  575.     if (IntuitionBase = OpenLibrary ("intuition.library", 39))
  576.     {
  577.         GadToolsBase = OpenLibrary ("gadtools.library", 39);
  578.         GfxBase      = OpenLibrary ("graphics.library", 39);
  579.         UtilityBase  = OpenLibrary ("utility.library", 39);
  580.  
  581.         /* Open AmigaGuide */
  582.         if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 39))
  583.         {
  584.         /* Build the unique name */
  585.         ai->ai_NHID = GetUniqueID ();
  586.         sprintf (ai->ai_NHName, "%s.%ld", BASENAME, ai->ai_NHID);
  587.  
  588.         /* Start the Dynamic Node Host */
  589.         ai->ai_NH = AddAmigaGuideHost (&ai->ai_NHHook, ai->ai_NHName, NULL);
  590.  
  591.         /* Lock the default public screen */
  592.         if (ai->ai_Screen = LockPubScreen (NULL))
  593.         {
  594.             /* Obtain the screen visual information for GadTools */
  595.             if (ai->ai_VI = GetVisualInfoA (ai->ai_Screen, NULL))
  596.             {
  597.             /* Initialize the global data */
  598.             ai->ai_Region = -1;
  599.  
  600.             anchor = NULL;
  601.             gad = CreateContext (&anchor);
  602.  
  603.             /* Set up the constant stuff */
  604.             ng.ng_TextAttr   = &topaz8;
  605.             ng.ng_VisualInfo = ai->ai_VI;
  606.  
  607.             /* Create a status window */
  608.             ng.ng_LeftEdge   = ai->ai_Screen->WBorLeft + 4;
  609.             ng.ng_TopEdge    = ai->ai_Screen->BarHeight + 1 + 2;
  610.             ng.ng_Width      = 312;
  611.             ng.ng_Height     = 12;
  612.             ng.ng_GadgetText = NULL;
  613.             ng.ng_GadgetID   = MCMD_STATUS;
  614.             ng.ng_Flags      = NULL;
  615.             ng.ng_UserData   = NULL;
  616.             gad = CreateGadget (TEXT_KIND, gad, &ng,
  617.                         GTTX_Justification,    GTJ_CENTER,
  618.                         GTTX_Border,    TRUE,
  619.                         TAG_DONE);
  620.             ai->ai_GStatus = gad;
  621.  
  622.             /* Create a list view */
  623.             ng.ng_LeftEdge   = ai->ai_Screen->WBorLeft + 4;
  624.             ng.ng_TopEdge   += ng.ng_Height + 4;
  625.             ng.ng_Height     = 64;
  626.             ng.ng_GadgetText = NULL;
  627.             ng.ng_GadgetID   = MCMD_LISTVIEW;
  628.             gad = CreateGadget (LISTVIEW_KIND, gad, &ng,
  629.                         GTLV_ReadOnly,    TRUE,
  630.                         GTLV_ScrollWidth,    18,
  631.                         TAG_DONE);
  632.  
  633.             /* Create an Accept button */
  634.             ng.ng_LeftEdge   = ai->ai_Screen->WBorLeft + 4;
  635.             ng.ng_TopEdge    = ai->ai_Screen->BarHeight + 1 + 84;
  636.             ng.ng_Width      = 87;
  637.             ng.ng_Height     = 12;
  638.             ng.ng_GadgetText = "Accept";
  639.             ng.ng_GadgetID   = MCMD_ACCEPT;
  640.             gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_DONE);
  641.  
  642.             /* Create a Cancel button */
  643.             ng.ng_LeftEdge   = ai->ai_Screen->WBorLeft + 229;
  644.             ng.ng_GadgetText = "Cancel";
  645.             ng.ng_GadgetID   = MCMD_CANCEL;
  646.             gad = CreateGadget (BUTTON_KIND, gad, &ng, TAG_DONE);
  647.  
  648.             /* Open the window */
  649.             if (ai->ai_Window = OpenWindowTags (NULL,
  650.                                 WA_InnerWidth,    320,
  651.                                 WA_InnerHeight,    100,
  652.                                 WA_Gadgets,        anchor,
  653.                                 WA_IDCMP,        IDCMP_FLAGS,
  654.                                 WA_Title,        (ULONG) "AmigaGuide Demo",
  655.                                 WA_PubScreen,    ai->ai_Screen,
  656.                                 WA_MenuHelp,    TRUE,
  657.                                 WA_AutoAdjust,    TRUE,
  658.                                 WA_DragBar,        TRUE,
  659.                                 WA_DepthGadget,    TRUE,
  660.                                 WA_CloseGadget,    TRUE,
  661.                                 WA_SmartRefresh,    TRUE,
  662.                                 WA_NewLookMenus,    TRUE,
  663.                                 WA_Activate,    TRUE,
  664.                                 WA_HelpGroup,    ai->ai_NHID,
  665.                                 TAG_DONE))
  666.             {
  667.                 /* Create the menus */
  668.                 if (ai->ai_Menu = CreateMenus (main_menu, TAG_DONE))
  669.                 if (LayoutMenus (ai->ai_Menu, ai->ai_VI,GTMN_NewLookMenus,TRUE,TAG_DONE))
  670.                     SetMenuStrip (ai->ai_Window, ai->ai_Menu);
  671.  
  672.                 /* Turn on gadget help */
  673.                 HelpControl (ai->ai_Window, HC_GADGETHELP);
  674.  
  675.                 /* Remember the AppInfo */
  676.                 ai->ai_Window->UserData = (APTR) ai;
  677.  
  678.                 /* We don't want the window to automatically activate */
  679.                 ai->ai_NAG.nag_Flags = HTF_NOACTIVATE;
  680.  
  681.                 /* Set the application base name */
  682.                 ai->ai_NAG.nag_BaseName = BASENAME;
  683.  
  684.                 /* Set the document name */
  685.                 ai->ai_NAG.nag_Name = "advaghelp.guide";
  686.  
  687.                 /* establish the base name to use for hypertext ARexx port */
  688.                 ai->ai_NAG.nag_ClientPort = "AGAPP_HELP";
  689.  
  690.                 /* Set up the context table */
  691.                 ai->ai_NAG.nag_Context = context;
  692.  
  693.                 /* Open the help system */
  694.                 ai->ai_AmigaGuide = OpenAmigaGuideAsync (&ai->ai_NAG,
  695.                                      AGA_HelpGroup, ai->ai_NHID,
  696.                                      TAG_DONE);
  697.  
  698.                 /* Take care of business */
  699.                 HandleEvents (ai);
  700.  
  701.                 /* Shutdown the help system */
  702.                 CloseAmigaGuide (ai->ai_AmigaGuide);
  703.  
  704.                 /* Clear the menu strip */
  705.                 ClearMenuStrip (ai->ai_Window);
  706.  
  707.                 /* Free the menus */
  708.                 FreeMenus (ai->ai_Menu);
  709.  
  710.                 /* Close the application window */
  711.                 CloseWindow (ai->ai_Window);
  712.             }
  713.  
  714.             /* Free the gadgets */
  715.             FreeGadgets (anchor);
  716.  
  717.             /* Free the GadTools visual info */
  718.             FreeVisualInfo (ai->ai_VI);
  719.             }
  720.  
  721.             /* Unlock the default public screen */
  722.             UnlockPubScreen (NULL, ai->ai_Screen);
  723.         }
  724.  
  725.         /* Remove the dynamic node host */
  726.         while (RemoveAmigaGuideHost (ai->ai_NH, NULL) > 0)
  727.             Delay (10);
  728.  
  729.         /* Close AmigaGuide */
  730.         CloseLibrary (AmigaGuideBase);
  731.         }
  732.  
  733.         /* Close the ROM libraries */
  734.         CloseLibrary (UtilityBase);
  735.         CloseLibrary (GfxBase);
  736.         CloseLibrary (GadToolsBase);
  737.         CloseLibrary (IntuitionBase);
  738.     }
  739.     FreeVec (ai);
  740.     }
  741. }
  742.