home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks96 / StockTalk.sit / StockTalk / Source / StockPlugIn.cp < prev    next >
Text File  |  1996-06-22  |  20KB  |  747 lines

  1. #include "ArrangeCallbacks.h"
  2. #include "PluginLibrary.h"
  3.  
  4. #include <Dialogs.h>
  5. #include <OSA.h>
  6. #include <Resources.h>
  7. #include <AERegistry.h>
  8.  
  9. #if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
  10.     #include "A4Stuff.h"
  11. #endif
  12.  
  13.  
  14. /* This file defines a "generic" plugin module for Arrange 2.0.  To
  15.  * use it, you should modify the Plugin class definition by adding
  16.  * new fields and private functions, and make corresponding changes in the
  17.  * "Plugin" section at the bottom of the file.  You should not have to
  18.  * look at or make any changes to the "Main entry point" section in the middle
  19.  * of the file.  This section contains code to create an instance of
  20.  * Plugin when the module is loaded, and forward hook calls from Arrange to
  21.  * the appropriate Plugin functions.
  22.  * 
  23.  * There is an associated Rez file, GenericPlugin.r, which defines the
  24.  * 'MDdf' resource needed for each Arrange plugin module.  To create a plugin
  25.  * module, compile GenericPlugin.r to produce an 'MDdf' resource, and
  26.  * compile and link this file to produce an 'MDcd' resource with the same ID.
  27.  * 
  28.  * This version of GenericPlugin.cp was written by Steve Newman on 12/24/93.
  29.  * Last updated 7/15/94.
  30.  */
  31.  
  32.  
  33. #define ModuleRsrcID -0x8000
  34.  
  35. #define OurModuleID  0x70000000  // Unique module ID; replace with a value
  36.                                            // obtained from CE Software.
  37. #define baseCmdCode  OurModuleID
  38.  
  39. #define pluginName    "Stock Quote Plugin" // controls our name in the About menu
  40. #define pluginAboutMenuText    "About Stock Quote Plugin"
  41.  
  42. #define aboutCmdCode (baseCmdCode + 0)
  43. #define updateQuoteCmdCode (baseCmdCode + 1)
  44.  
  45.  
  46. #if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
  47.     #define SetupA4            long    lOldA4 = SetCurrentA4 ();
  48.     #define TearDownA4         SetA4 (lOldA4);
  49.     #define UnloadSegs        UnloadSegsFunc ();
  50.  
  51.     static void UnloadSegsFunc ();
  52. #else
  53.     #define SetupA4
  54.     #define TearDownA4
  55.     #define UnloadSegs
  56. #endif    //__MWERKS__
  57.  
  58.  
  59. typedef struct {
  60.         Str255    cURLAddress;
  61.         Str255    cComment;
  62.         Str255    cTitle;
  63.         arDocumentPtr    whichDoc;
  64.         const ArrangeCallbackTbl* calls;
  65.         arNoteID    cTheTourNote;
  66.         short        whichNote;
  67.     } myprefs;
  68.  
  69. typedef struct {
  70.         arFieldID        lTitleField;
  71.         arFieldID        lValueField;
  72.         arFieldID        lIndexField;
  73.         arFieldID        lChangeField;
  74.     
  75.     } sIDList;
  76.  
  77. class Plugin
  78.     {
  79. public:
  80.     Plugin(const ArrangeCallbackTbl* theCalls);
  81.     ~Plugin();
  82.     
  83.     arHookResult ClickNotify( arClickLocation loc, Point where, Short modifiers,
  84.                                       Short clickCount, arNoteID note, arFieldID field,
  85.                                       arPathID path );
  86.     arHookResult KeyNotify  ( Short theChar, Short key, Short modifiers );
  87.     arHookResult MenuNotify ( Integer commandCode, Integer commandParam,
  88.                                       Short modifiers );
  89.     arHookResult FieldNotify( arNoteID note, arFieldID field, arFieldAction action,
  90.                                       const char* choiceText );
  91.     void         TopicNotify( arTopicID newTopic, arWindowID newWindow,
  92.                                       arTopicAction action );
  93.     void             TickNotify (  );
  94.     arHookResult FileNotify ( arFileAction action );
  95.     arHookResult QuitNotify (  );
  96.     void         ATMNotify  (  );
  97.     
  98. private:
  99.     const ArrangeCallbackTbl* calls; // callback table
  100.     short    mQuotes;
  101.     myprefs    theprefs;
  102.     ComponentInstance scriptingComponent;
  103.     
  104.     void    UpdateTheQuotes ();
  105.     void  UpdateNote(arNoteID);
  106.     OSErr  InitComponent();
  107.     OSErr    GetQuote(ConstStr255Param, StringPtr, StringPtr, StringPtr);
  108.     void  SetChange(arNoteID selNote, short index, StringPtr newValue);
  109.     }; // Plugin
  110.  
  111.  
  112. /*************************************************************************/
  113. /**************************** Main entry point ***************************/
  114. /*************************************************************************/
  115.  
  116. /* Root entry point for the module - must be the first function in the
  117.  * file, so that the linker will place it first in the code segment.
  118.  * This is the routine which Arrange calls at application startup time
  119.  * (and again at quit time).
  120.  * 
  121.  * Most plug-ins will not need to modify this routine or the Hook functions
  122.  * immediately following.  All customization can be done in the "Plugin"
  123.  * section (below).
  124.  */
  125. extern "C" Integer main( ModuleParamBlock *pb, pModuleRootAction action,
  126.                                             Integer /*p1*/ ENDP )
  127.     {
  128.     SetupA4;
  129.  
  130.     Integer    lResult = 0;
  131.  
  132.     /* Extract the callback table from our parameter block, and coerce it
  133.      * to the extended Arrange table.
  134.      */
  135.     ArrangeCallbackTbl* calls = (ArrangeCallbackTbl*)(pb->calls);
  136.     
  137.     Assert (sizeof (Byte) == 1);
  138.     Assert (sizeof (Short) == 2);
  139.     Assert (sizeof (Integer) == 4);
  140.     Assert (sizeof (Float) == 8);
  141.  
  142.     switch (action)
  143.         {
  144.         case mrLoad:
  145.             {
  146.             // Allocate memory and create a new Plugin object.
  147.             void* storage = calls->mem->AllocMem( sizeof(Plugin),
  148.                                                               amFreeStore | amErrIfNoMem );
  149.             pb->moduleRefcon = uInteger(new(storage) Plugin(calls));
  150.             lResult = 1;
  151.             }
  152.             break;
  153.         
  154.         case mrUnload:
  155.             {
  156.             /* Dispose of the Plugin object and release the memory
  157.              * it occupies.
  158.              */
  159.             delete (Plugin*)(pb->moduleRefcon);
  160.             calls->mem->DeallocMem((void*)(pb->moduleRefcon), amFreeStore);
  161.             lResult = 0;
  162.             }
  163.             break;
  164.         
  165.         case mrFindEntry:
  166.         default:
  167.             {
  168.             /* This module contains no extended entry points, so we always
  169.              * return 0 for the mrFindEntry message.  Most plug-ins will not
  170.              * use extended entry points.
  171.              */
  172.             lResult = 0;
  173.             }
  174.             break;
  175.         
  176.         } // switch (action)
  177.     
  178.     UnloadSegs;
  179.     TearDownA4;
  180.     return lResult;
  181.     } // main
  182.  
  183. #if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
  184. #pragma segment PluginLib
  185. static void PluginLibSeg (void)
  186. {
  187. }
  188.  
  189. #pragma segment Main
  190. static void UnloadSegsFunc ()
  191. {
  192.     // Put segment unloading code here.
  193.     // Do NOT use UnloadSeg!
  194.     UnloadA4Seg (PluginLibSeg);
  195. }
  196. #endif    //__MWERKS__ && PLUGIN_GLOBALS
  197.  
  198. /* These hook functions simply pass control to the appropriate function
  199.  * in the Plugin object.
  200.  */
  201. static arHookResult OurClickHook( ModuleParamBlock* pb, arClickLocation loc,
  202.                                              Point where, pShort modifiers, pShort clickCount,
  203.                                              arNoteID note, arFieldID field,
  204.                                              arPathID path ENDP )
  205.     {
  206.     SetupA4;
  207.     arHookResult    eResult = ((Plugin*)(pb->moduleRefcon))->ClickNotify( loc, where, modifiers,
  208.                                                                         clickCount, note, field,
  209.                                                                         path );
  210.     UnloadSegs;
  211.     TearDownA4;
  212.     return eResult;
  213.     }
  214.  
  215.  
  216. static arHookResult OurKeyHook( ModuleParamBlock* pb, pShort theChar, pShort key,
  217.                                           pShort modifiers ENDP )
  218.     {
  219.     SetupA4;
  220.     arHookResult    eResult = ((Plugin*)(pb->moduleRefcon))->KeyNotify(theChar, key, modifiers);
  221.     UnloadSegs;
  222.     TearDownA4;
  223.     return eResult;
  224.     }
  225.  
  226.  
  227. static arHookResult OurMenuHook( ModuleParamBlock* pb, Integer commandCode,
  228.                                             Integer commandParam, pShort modifiers ENDP )
  229.     {
  230.     SetupA4;
  231.     arHookResult    eResult = ((Plugin*)(pb->moduleRefcon))->MenuNotify( commandCode, commandParam,
  232.                                                                      modifiers );
  233.     UnloadSegs;
  234.     TearDownA4;
  235.     return eResult;
  236.     }
  237.  
  238.  
  239. static arHookResult OurFieldHook( ModuleParamBlock* pb, arNoteID note,
  240.                                              arFieldID field, arFieldAction action,
  241.                                              const char* choiceText ENDP )
  242.     {
  243.     SetupA4;
  244.     arHookResult    eResult = ((Plugin*)(pb->moduleRefcon))->FieldNotify( note, field, action,
  245.                                                                         choiceText );
  246.     UnloadSegs;
  247.     TearDownA4;
  248.     return eResult;
  249.     }
  250.  
  251.  
  252. static void OurTopicHook( ModuleParamBlock* pb, arTopicID newTopic,
  253.                                   arWindowID newWindow, arTopicAction action ENDP )
  254.     {
  255.     SetupA4;
  256.     ((Plugin*)(pb->moduleRefcon))->TopicNotify(newTopic, newWindow, action);
  257.     UnloadSegs;
  258.     TearDownA4;
  259.     }
  260.  
  261.  
  262. static void OurTickHook(ModuleParamBlock* pb ENDP)
  263.     {
  264.     SetupA4;
  265.     ((Plugin*)(pb->moduleRefcon))->TickNotify();
  266.     UnloadSegs;
  267.     TearDownA4;
  268.     }
  269.  
  270.  
  271. static arHookResult OurFileHook(ModuleParamBlock* pb, arFileAction action ENDP)
  272.     {
  273.     SetupA4;
  274.     arHookResult    eResult = ((Plugin*)(pb->moduleRefcon))->FileNotify(action);
  275.     UnloadSegs;
  276.     TearDownA4;
  277.     return eResult;
  278.     }
  279.  
  280.  
  281. static arHookResult OurQuitHook(ModuleParamBlock* pb ENDP)
  282.     {
  283.     SetupA4;
  284.     arHookResult    eResult = ((Plugin*)(pb->moduleRefcon))->QuitNotify();
  285.     UnloadSegs;
  286.     TearDownA4;
  287.     return eResult;
  288.     }
  289.  
  290.  
  291. static void OurATMHook(ModuleParamBlock* pb ENDP)
  292.     {
  293.     SetupA4;
  294.     ((Plugin*)(pb->moduleRefcon))->ATMNotify();
  295.     UnloadSegs;
  296.     TearDownA4;
  297.     }
  298.  
  299.  
  300. /*************************************************************************/
  301. /********************************* Plugin ********************************/
  302. /*************************************************************************/
  303.  
  304. /* Construct a Plugin object.  This is called once, from the OurModuleRoot
  305.  * function, when the module is initialized (i.e. at application startup time).
  306.  */
  307. Plugin::Plugin(const ArrangeCallbackTbl* theCalls)
  308.     {
  309.     // Record the callback table for future use.
  310.     calls = theCalls;
  311.     
  312.     /* These commands, if un-commented-out, register this plugin to be called
  313.      * by Arrange when various events occur.  For example, if you un-comment-out
  314.      * the call to SetClickHook, then Plugin::ClickNotify will be called
  315.      * whenever the user clicks in any of the locations described in the
  316.      * arClickLocation enum.
  317.      */
  318.     // calls->ui->SetClickHook(OurClickHook, 0, true);
  319.     // calls->ui->SetKeyHook  (OurKeyHook,   0, true, charFilter, keyFilter, modFilter);
  320.     // calls->ui->SetMenuHook (OurMenuHook,  0, true, whichCommand);
  321.     // calls->ui->SetFieldHook(OurFieldHook, 0, true, whichField);
  322.     // calls->ui->SetTopicHook(OurTopicHook, 0, true);
  323.     // calls->ui->SetTickHook (OurTickHook,  0, true);
  324.     // calls->ui->SetFileHook (OurFileHook,  0, true);
  325.     // calls->ui->SetQuitHook (OurQuitHook,  0, true);
  326.     // calls->ui->SetATMHook  (OurATMHook,   0, true);
  327.     
  328.     
  329.     // Add an item to the About Plugins menu for this plugin.
  330.     calls->ui->AddMenuItem(mPluginAbout, pluginAboutMenuText, 0, aboutCmdCode, 0);
  331.     calls->ui->AddMenuItem(mTools, "Update Quote",     0, updateQuoteCmdCode,2);    
  332.     
  333.     calls->ui->SetMenuHook(OurMenuHook, 1, true, aboutCmdCode);
  334.     calls->ui->SetMenuHook(OurMenuHook, 2, true, updateQuoteCmdCode);
  335.         
  336.     InitComponent();
  337.     } // Plugin constructor
  338.  
  339.  
  340. /* Dispose of a Plugin object.  This is called when Arrange terminates.  You
  341.  * should free up any data structures which you allocation in the Plugin
  342.  * constructor (above).
  343.  */
  344. Plugin::~Plugin()
  345.     {
  346.     } // ~Plugin
  347.  
  348.  
  349. /* This function is called whenever the user clicks in an "interesting place"
  350.  * in a document window.  It should return true if we handle the click, false
  351.  * (the normal case) when the click should be passed along to other plug-ins
  352.  * or to Arrange's normal event processing.  See the documentation for
  353.  * SetClickHook for more details.
  354.  */
  355. arHookResult Plugin::ClickNotify( arClickLocation loc, Point where,
  356.                                              Short modifiers, Short clickCount,
  357.                                              arNoteID note, arFieldID field,
  358.                                              arPathID path )
  359.     {
  360.     return false; // Let Arrange handle the event
  361.     } // ClickNotify
  362.  
  363.  
  364. /* This function is called whenever the user types a key which matches the
  365.  * filters we pass to SetKeyHook in Plugin's constructor.  It should return
  366.  * true if we handle the event, false (the normal case) when the event
  367.  * should be passed along to other plug-ins or to Arrange's normal event
  368.  * processing.  See the documentation for SetKeyHook for more details.
  369.  */
  370. arHookResult Plugin::KeyNotify(Short theChar, Short key, Short modifiers)
  371.     {
  372.     return false; // Let Arrange handle the event
  373.     } // KeyNotify
  374.  
  375.  
  376. /* This function is called whenever the user chooses a menu item for which
  377.  * we have registered (via the SetMenuHook function).  It should return true
  378.  * if we handle the command, false (the normal case) when the command should
  379.  * be passed along to other plug-ins or to Arrange's normal event processing.
  380.  * See the documentation for SetMenuHook for more details.
  381.  */
  382. arHookResult Plugin::MenuNotify( Integer commandCode, Integer commandParam,
  383.                                             Short modifiers )
  384.     {
  385.     /* If this is our About menu item, display our about-box dialog and return
  386.      * true to indicate we handled the command.
  387.      */
  388.     if (commandCode == aboutCmdCode)
  389.         {
  390.         Alert(ModuleRsrcID, nil);
  391.         return true;
  392.         }
  393.     else if (commandCode == updateQuoteCmdCode)
  394.         {
  395.         UpdateTheQuotes();
  396.         return true;
  397.         }
  398.     else
  399.         return false; // Let Arrange handle the event
  400.     
  401.     } // MenuNotify
  402.  
  403.  
  404. /* If we register to recieve events for a field by calling SetFieldHook, this
  405.  * function will be called for any events in that field.  It should return
  406.  * false in almost all cases.  See the documentation for SetFieldHook for
  407.  * more details.
  408.  */
  409. arHookResult Plugin::FieldNotify( arNoteID note, arFieldID field,
  410.                                              arFieldAction action, const char* choiceText )
  411.     {
  412.     return false;
  413.     } // FieldNotify
  414.  
  415.  
  416. /* This function is called whenever the user switches windows or changes
  417.  * the current folder/topic/view in the front window.  See the documentation
  418.  * for SetTopicHook for more details.
  419.  */
  420. void Plugin::TopicNotify( arTopicID newTopic, arWindowID newWindow,
  421.                                   arTopicAction action )
  422.     {
  423.     } // TopicNotify
  424.  
  425.  
  426. /* This function is called periodically, whenever Arrange recieves a null
  427.  * event from the Event Manager.
  428.  */
  429. void Plugin::TickNotify()
  430.     {
  431.     
  432.     } // TickNotify
  433.  
  434.  
  435. /* This function is called whenever various file-level events occur.  It
  436.  * should return true in almost all cases.  See the documentation for
  437.  * SetFileHook for more details.
  438.  */
  439. arHookResult Plugin::FileNotify(arFileAction action)
  440.     {
  441.     return true;
  442.     } // FileNotify
  443.  
  444.  
  445. /* This function is called if the user voluntarily quits Arrange.  It should
  446.  * return true to allow the user to quit, false to prevent it.  See the
  447.  * documentation for SetQuitHook for more details.
  448.  */
  449. arHookResult Plugin::QuitNotify()
  450.     {
  451.     return true;
  452.     } // QuitNotify
  453.  
  454.  
  455. /* This function is called whenever the user clicks in the menu bar or types
  456.  * a command key, just before processing the event.  It should do any fixing
  457.  * up of menus which might be necessary based on the current state of affairs.
  458.  * See the documentation for SetATMHook for more details.
  459.  */
  460. void Plugin::ATMNotify()
  461.     {
  462.     } // ATMNotify
  463.     
  464.     
  465. /*Boolean Plugin::GetMyIDs(sIDList *theIDs)
  466. {
  467.     char  topic[13] = "Stock Quotes";
  468.     
  469.     char    title[6] = "Title";
  470.     char    index[6] = "Index";
  471.     char  value[6] = "Value";
  472.     char  change[7] = "Change";
  473.         
  474.     theIDs->lTitleField = calls->sysObj->LookupObjectName ( arTopic,(char*) (&topic), true);
  475.     if(!theIDs->lTitleField)
  476.         return false;
  477.         
  478.     theIDs->lTopicContentsFieldID = calls->sysObj->GetBuiltInObject (boTopicContentsField);
  479.     if (!theIDs->lTopicContentsFieldID)
  480.     {
  481.         return false;
  482.     }
  483.     
  484.     theIDs->lTitleField = calls->sysObj->LookupObjectName ( arField,(char*) (&title), true);
  485.     if(!theIDs->lTitleField)
  486.         return false;
  487.     
  488.     theIDs->lIndexField = calls->sysObj->LookupObjectName ( arField,(char*) (&index), true);
  489.     if(!theIDs->lTitleField)
  490.         return false;
  491.  
  492.     theIDs->lValueField = calls->sysObj->LookupObjectName ( arField,(char*) (&value), true);
  493.     if(!theIDs->lTitleField)
  494.         return false;
  495.  
  496.     theIDs->lChangeField = calls->sysObj->LookupObjectName ( arField,(char*) (&change), true);
  497.     if(!theIDs->lTitleField)
  498.         return false;
  499.  
  500.  
  501.     return true;    
  502. }
  503. */
  504.  
  505. void    Plugin::UpdateTheQuotes (  )
  506. {
  507.     Integer        i;    
  508.     short    whichnote;
  509.     // Determine whether there is a selection and how many notes it contains.
  510.     Integer selCount;
  511.     
  512.     arNoteID  selNote;
  513.     arNoteID     parentNote;
  514.     arFieldID selField;
  515.     Integer   selStart;
  516.     Integer   selEnd;
  517.     
  518.     short        thecount;
  519.     arFieldID    theField;
  520.     arNoteInfo    thetopicinfo;
  521.     short    thelength;
  522.     Str255    tempstr;
  523.     Ptr        theptr;
  524.     char        TheName[32]="Reformatting";
  525.     Boolean    firstchange = true;
  526.     
  527.     Str31 promptstr = "\pRetrieving the quote...";
  528.     
  529.     
  530.     if (!calls->sel->FlushSelection(false))
  531.     {
  532.         return;
  533.     }
  534.  
  535.     switch (calls->sel->GetSelection(&selNote, &selField, &selStart, &selEnd))
  536.         {
  537.         case stNote:
  538.         case stFieldContents:
  539.         case stMultipleNotes:
  540.         case stMultipleFields:
  541.         case stField:
  542.         case stText:  // selected text is treated specially
  543.         default:
  544.             calls->dlg->DisplayNotify( (const char*)&promptstr[1], nfShowImmediately);
  545.             UpdateNote(selNote);
  546.             calls->dlg->ClearNotify();
  547.             return;
  548.         
  549.         } // switch (GetSelection result)
  550.     
  551.     return;
  552.     }
  553.  
  554.  
  555. void Plugin::UpdateNote(arNoteID selNote)
  556. {
  557.     arFieldID theField = calls->notes->GetNoteField(selNote, 1);
  558.     if(!theField)
  559.         DebugStr("\pno field");
  560.         
  561.     if (theField!=nil)
  562.     {
  563.         
  564.         arFieldInfo info;
  565.         info.versNum = 1;
  566.         calls->sysObj->GetFieldInfo(theField, &info);
  567.         
  568.         if(info.type!=arFTText)
  569.             DebugStr("\pnot a text");
  570.             
  571.         if (info.type==arFTText)
  572.         {
  573.             Str255 index;
  574.             
  575.             index[0] = calls->data->GetFieldTextLen(selNote, theField);
  576.             if (index[0])
  577.             {
  578.                 Str255 price = "\p", change = "\p", name = "\p";
  579.                 index[0] = calls->data->GetFieldText(selNote, theField, index[0]+1,  (char*)(index + 1));
  580.                 OSErr err = GetQuote(index, price, name, change);
  581.                 if(!err)
  582.                     {
  583.                     SetChange(selNote, 0, name);
  584.                     SetChange(selNote, 2, price);
  585.                     SetChange(selNote, 3, change);
  586.                     
  587.                     calls->sel->FlushSelection(false);
  588.                     }
  589.             }
  590.         }
  591.     }
  592. }
  593.  
  594. void Plugin::SetChange(arNoteID selNote,
  595.                                 short index,
  596.                                 StringPtr newValue)
  597.     {
  598.     arFieldID theField = calls->notes->GetNoteField(selNote, index);
  599.     if(theField)
  600.         calls->data->SetFieldText(    selNote,
  601.                                             theField,
  602.                                             (char *)(newValue + 1),
  603.                                             newValue[0],
  604.                                             0);
  605.     }
  606.  
  607. OSErr Plugin::GetQuote(ConstStr255Param index,
  608.                             StringPtr price, StringPtr name, StringPtr change)
  609.     {
  610.     AEDesc target = {typeNull, nil};
  611.     
  612.     AppleEvent theEvent;
  613.     OSErr err  = AECreateAppleEvent(    'core',
  614.                                         'clos',
  615.                                         &target,
  616.                                         kAutoGenerateReturnID,
  617.                                         0,
  618.                                         &theEvent);
  619.                                         
  620.     err = AEPutParamPtr(    &theEvent,
  621.                                 keyDirectObject,
  622.                                 typeChar,
  623.                                 index + 1,
  624.                                 index[0]);
  625.     
  626.     AEDesc scriptData =  {typeNull, 0};
  627.     
  628.     scriptData.dataHandle = GetResource('scpt', 128);
  629.     scriptData.descriptorType = 'scpt';
  630.     if(scriptData.dataHandle == 0)
  631.         DebugStr("\pNo data");
  632.     
  633.     OSAID scriptID;
  634.     err = OSALoad(    scriptingComponent,
  635.                         &scriptData,
  636.                         kOSAModePreventGetSource,
  637.                         &scriptID);
  638.     
  639.     if(err)
  640.         DebugStr("\pcould not load script");
  641.         
  642.     if(!err)
  643.         {
  644.         AppleEvent reply = { typeNull, 0};    
  645.         OSAID result;                         
  646.         err = OSAExecuteEvent(    scriptingComponent,
  647.                                         &theEvent,
  648.                                         scriptID,
  649.                                         kOSAModeNull,
  650.                                         &result);
  651.         
  652.         if(err)
  653.             DebugStr("\pcould not execute event");
  654.             
  655.         AEDescList resultList =     { typeNull, 0};
  656.         
  657.         if(!err)
  658.             {                    
  659.             /*err = AEGetParamDesc(&reply,
  660.                                         keyAEResult,
  661.                                         typeAEList,
  662.                                         &resultList);*/
  663.                                         
  664.             err = OSACoerceToDesc(    scriptingComponent,
  665.                                             result,
  666.                                             typeAEList,
  667.                                             kOSAModeNull,
  668.                                             &resultList);                                        
  669.             long size;
  670.             AEKeyword key;
  671.             DescType type;
  672.             if(!err)
  673.                 {
  674.                 err = AEGetNthPtr(    &resultList,
  675.                                             1,
  676.                                             typeChar,
  677.                                             &key,
  678.                                             &type,
  679.                                             name + 1,
  680.                                             255,
  681.                                             &size);
  682.                 name[0] = size;
  683.                                         
  684.                 err = AEGetNthPtr(    &resultList,
  685.                                             2,
  686.                                             typeChar,
  687.                                             &key,
  688.                                             &type,
  689.                                             price + 1,
  690.                                             255,
  691.                                             &size);
  692.                 price[0] = size;
  693.  
  694.                 err = AEGetNthPtr(    &resultList,
  695.                                             3,
  696.                                             typeChar,
  697.                                             &key,
  698.                                             &type,
  699.                                             change + 1,
  700.                                             255,
  701.                                             &size);
  702.                 change[0] = size;
  703.                 }
  704.             }
  705.         
  706.         }
  707.      return err;
  708.     }
  709.  
  710. OSErr Plugin::InitComponent()
  711.     {
  712.     OSAError                 err = 0;
  713.     ComponentDescription     descr;
  714.     Component                   aComponent;
  715.     ComponentInstance         aScriptingComponent;
  716.     
  717.  
  718.     descr.componentType         = kOSAComponentType;
  719.     descr.componentSubType      = (OSType) 0;
  720.     descr.componentManufacturer = (OSType) 0;
  721.     descr.componentFlags        = kOSASupportsCompiling + 
  722.                                   kOSASupportsGetSource + 
  723.                                   kOSASupportsConvenience + 
  724.                                   kOSASupportsEventHandling;
  725.     descr.componentFlagsMask    = descr.componentFlags;
  726.     
  727.     aComponent = FindNextComponent(nil, &descr);
  728.         
  729.     if (!aComponent)
  730.         err = paramErr;
  731.     else
  732.     {
  733.         aScriptingComponent = OpenComponent(aComponent);
  734.                                                                                                 
  735.         if (!aScriptingComponent)
  736.             err = paramErr;
  737.         else if (aScriptingComponent) 
  738.             err = OSASetActiveProc(aScriptingComponent, 0, 0);
  739.     }
  740.         
  741.     scriptingComponent = aScriptingComponent;
  742.     
  743.     if(err)
  744.         DebugStr("\pCould not init component");
  745.     return err;
  746. }
  747.