Jump to content

Work Place Shell Programming - Part 4: Difference between revisions

From EDM2
Ak120 (talk | contribs)
mNo edit summary
Ak120 (talk | contribs)
mNo edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
{{WPSProg}}
''Written by [[Chris Palchak]]''
''Written by [[Chris Palchak]]''
{| width="400" cellpadding="4"
| align="CENTER" valign="MIDDLE" |
[[Work Place Shell Programming - Part 1|Part 1]]
| align="CENTER" valign="MIDDLE" |
[[Work Place Shell Programming - Part 2|Part 2]]
| align="CENTER" valign="MIDDLE" |
[[Work Place Shell Programming - Part 3|Part 3]]
| align="CENTER" valign="MIDDLE" |
[[Work Place Shell Programming - Part 4|Part 4]]
|}


==The ChartFolder Class==
==The ChartFolder Class==
===Overview===
===Overview===
In this, the fourth article in this series, the ChartFolder class will be created. This class inherits from WPFolder and is used to hold ChartFile objects.
In this, the fourth article in this series, the ChartFolder class will be created. This class inherits from [[WPFolder]] and is used to hold ChartFile objects.


===The SOM IDL for ChartFolder===
===The SOM IDL for ChartFolder===
Line 27: Line 17:
===ChFoldr.idl listing===
===ChFoldr.idl listing===
<pre>
<pre>
  #ifndef CHFOLDR_IDL
#ifndef CHFOLDR_IDL
  #define CHFOLDR_IDL
#define CHFOLDR_IDL
  #include <wpfolder.idl>
#include <wpfolder.idl>
  interface M_ChartFolder;
interface M_ChartFolder;
   
   
  interface ChartFolder : WPFolder
interface ChartFolder : WPFolder
  {
{
      #ifdef __SOMIDL__
    #ifdef __SOMIDL__
   
   
  // Access methods for ChartFolder's data members
// Access methods for ChartFolder's data members
   
   
        float  getLowPriceCutoff();
      float  getLowPriceCutoff();
        float  getLowPriceChangePct();
      float  getLowPriceChangePct();
        float  getRegPriceChangePct();
      float  getRegPriceChangePct();
        short  getStartDD();
      short  getStartDD();
        short  getStartMM();
      short  getStartMM();
        short  getStartYYYY();
      short  getStartYYYY();
        short  getEndDD();
      short  getEndDD();
        short  getEndMM();
      short  getEndMM();
        short  getEndYYYY();
      short  getEndYYYY();
        string getErrorFolder();
      string getErrorFolder();
   
   
        void  setLowPriceCutoff(in float LowPrice);
      void  setLowPriceCutoff(in float LowPrice);
        void  setLowPriceChangePct(in float LowPricePct);
      void  setLowPriceChangePct(in float LowPricePct);
        void  setRegPriceChangePct(in float RegPricePct);
      void  setRegPriceChangePct(in float RegPricePct);
        void  setStartDD(in short dd);
      void  setStartDD(in short dd);
        void  setStartMM(in short mm);
      void  setStartMM(in short mm);
        void  setStartYYYY(in short yyyy);
      void  setStartYYYY(in short yyyy);
        void  setEndDD(in short dd);
      void  setEndDD(in short dd);
        void  setEndMM(in short mm);
      void  setEndMM(in short mm);
        void  setEndYYYY(in short yyyy);
      void  setEndYYYY(in short yyyy);
        void  setErrorFolder(in string ErrorFolder);
      void  setErrorFolder(in string ErrorFolder);
   
   
      //------------------------------------------------------
    //------------------------------------------------------
      // This method that reallocates memory for ChartFile's
    // This method that reallocates memory for ChartFile's
      // strings is necessary because string is defined as
    // strings is necessary because string is defined as
      // "char *" in \ibmcpp\include\som\somcorba.h.
    // "char *" in \ibmcpp\include\som\somcorba.h.
      //------------------------------------------------------
    //------------------------------------------------------
        string reallocateString(in string oldString,
      string reallocateString(in string oldString,
                                in string newValue);
                              in string newValue);
   
   
        implementation
      implementation
        {
      {
            externalstem = ChFolder;
          externalstem = ChFolder;
            local;
          local;
            externalprefix = ChFolderX_;
          externalprefix = ChFolderX_;
            majorversion = 1;
          majorversion = 1;
            minorversion = 1;
          minorversion = 1;
            filestem = ChFoldr;
          filestem = ChFoldr;
            metaclass = M_ChartFolder;
          metaclass = M_ChartFolder;
   
   
      //-----------------------------------------------------
    //-----------------------------------------------------
      // Class method (function) overrides
    // Class method (function) overrides
      //-----------------------------------------------------
    //-----------------------------------------------------
          // add my settings pages
        // add my settings pages
            wpAddSettingsPages: override;
          wpAddSettingsPages: override;
   
   
          // restore state when object is awaken
        // restore state when object is awaken
   
   
            wpRestoreState:    override;
          wpRestoreState:    override;
   
   
          // save state during shut down or idle times
        // save state during shut down or idle times
            wpSaveState:        override;
          wpSaveState:        override;
   
   
          // called when object is opened
        // called when object is opened
            wpOpen:            override;
          wpOpen:            override;
   
   
          // allocate memory for this object
        // allocate memory for this object
            wpInitData:        override;
          wpInitData:        override;
   
   
          // free allocated memory
        // free allocated memory
            wpUnInitData:      override;
          wpUnInitData:      override;
   
   
          // add my items to the pop-up menu
        // add my items to the pop-up menu
            wpModifyPopupMenu:  override;
          wpModifyPopupMenu:  override;
   
   
          // process user selection of my menu items
        // process user selection of my menu items
            wpMenuItemSelected: override;
          wpMenuItemSelected: override;
   
   
      //-----------------------------------------------------
    //-----------------------------------------------------
      // Instance data (Exists separately for each
    // Instance data (Exists separately for each
      // ChartFolder object). These are NOT declared with the
    // ChartFolder object). These are NOT declared with the
      // SOM IDL "attribute" statement so that the get
    // SOM IDL "attribute" statement so that the get
      // and set functions can be named manually.
    // and set functions can be named manually.
      //-----------------------------------------------------
    //-----------------------------------------------------
   
   
        // price changes that indicate an error or split
      // price changes that indicate an error or split
            float  lowPriceCutoff;
          float  lowPriceCutoff;
            float  lowPriceChangePct;
          float  lowPriceChangePct;
            float  regPriceChangePct;
          float  regPriceChangePct;
   
   
        // first date to check
      // first date to check
            short  startDD;
          short  startDD;
            short  startMM;
          short  startMM;
            short  startYYYY;
          short  startYYYY;
   
   
        // last date to check
      // last date to check
            short  endDD;
          short  endDD;
            short  endMM;
          short  endMM;
            short  endYYYY;
          short  endYYYY;
   
   
        // for future use
      // for future use
            string errorFolder;
          string errorFolder;
   
   
      //-----------------------------------------------------
    //-----------------------------------------------------
      // Passthru Statements:
    // Passthru Statements:
      // These statements are passed without change to the
    // These statements are passed without change to the
      // generated "chfoldr.xih" and "chfoldr.xh" files.
    // generated "chfoldr.xih" and "chfoldr.xh" files.
      //-----------------------------------------------------
    //-----------------------------------------------------
   
   
      // These statements get written to ChFoldr.xih.
    // These statements get written to ChFoldr.xih.
      // ChFoldr.xih is included in ChFoldr.cpp.
    // ChFoldr.xih is included in ChFoldr.cpp.
   
   
          passthru C_xih_before =  ""
        passthru C_xih_before =  ""
   
   
          " /* PM and OS2 include directives */"
        " /* PM and OS2 include directives */"
          "  #define INCL_WINWORKPLACE"
        "  #define INCL_WINWORKPLACE"
          "  #define INCL_WIN"
        "  #define INCL_WIN"
          "  #define INCL_DOS"
        "  #define INCL_DOS"
          "  #include <os2.h>"
        "  #include <os2.h>"
          ""
        ""
          " /* WPS include directives */"
        " /* WPS include directives */"
          "  #define INCL_WPCLASS"
        "  #define INCL_WPCLASS"
          "  #define INCL_WPFOLDER"
        "  #define INCL_WPFOLDER"
          "  #include <pmwp.h>"
        "  #include <pmwp.h>"
          ""
        ""
          " /* C include directives */"
        " /* C include directives */"
          "  #include <stdio.h>";
        "  #include <stdio.h>";
   
   
      // These statements get written to ChFoldr.xh.
    // These statements get written to ChFoldr.xh.
      // ChFoldr.xh is included in C++ programs that
    // ChFoldr.xh is included in C++ programs that
      // reference ChartFolder objects.
    // reference ChartFolder objects.
   
   
          passthru C_xh_before =  ""
        passthru C_xh_before =  ""
          " /* PM and OS2 include directives */"
        " /* PM and OS2 include directives */"
          "  #define INCL_WINWORKPLACE"
        "  #define INCL_WINWORKPLACE"
          "  #define INCL_WIN"
        "  #define INCL_WIN"
          "  #define INCL_DOS"
        "  #define INCL_DOS"
          "  #include <os2.h>"
        "  #include <os2.h>"
          ""
        ""
          " /* WPS include directives */"
        " /* WPS include directives */"
          "  #define INCL_WPCLASS"
        "  #define INCL_WPCLASS"
          "  #define INCL_WPFOLDER"
        "  #define INCL_WPFOLDER"
          "  #include <pmwp.h>"
        "  #include <pmwp.h>"
          ""
        ""
          " /* C include directives */"
        " /* C include directives */"
          "  #include <stdio.h>";
        "  #include <stdio.h>";
        };
      };
   
   
      #endif
    #endif
  };
};
   
   
  //---------------------------------------------------------
//---------------------------------------------------------
  // Metaclass section:
// Metaclass section:
  // ------------------
// ------------------
  // Describe the metaclass of ChartFolder. The Meta Class
// Describe the metaclass of ChartFolder. The Meta Class
  // defines data that is common (global) to all ChartFolder
// defines data that is common (global) to all ChartFolder
  // objects. It also defines functions that operate on Meta
// objects. It also defines functions that operate on Meta
  // Class Data.
// Class Data.
  //---------------------------------------------------------
//---------------------------------------------------------
   
   
  interface M_ChartFolder
interface M_ChartFolder
   
   
  // Comment for parent WPFolder:
// Comment for parent WPFolder:
   
   
  {
{
   
   
    //
  //
    // New class methods
  // New class methods
    //
  //
        unsigned long queryCommandProcessor();
      unsigned long queryCommandProcessor();
   
   
    //
  //
    // implementation
  // implementation
    //
  //
   
   
  #ifdef __SOMIDL__
#ifdef __SOMIDL__
      implementation
    implementation
      {
    {
      // Class Modifiers
    // Class Modifiers
   
   
          externalstem = ChFolder;
        externalstem = ChFolder;
          local;
        local;
          externalprefix = ChFolderX_;
        externalprefix = ChFolderX_;
          functionprefix = ChFolderC_;
        functionprefix = ChFolderC_;
          majorversion = 1;
        majorversion = 1;
          minorversion = 1;
        minorversion = 1;
          filestem = ChFoldr;
        filestem = ChFoldr;
   
   
      // non-instance (global) data
    // non-instance (global) data
   
   
          unsigned long  hChartFolderIcon;
        unsigned long  hChartFolderIcon;
          unsigned long  hChartFolderOpenIcon;
        unsigned long  hChartFolderOpenIcon;
          unsigned long  pCmdProc;
        unsigned long  pCmdProc;
   
   
      // Class method overrides
    // Class method overrides
   
   
          wpclsInitData:        override;
        wpclsInitData:        override;
          wpclsUnInitData:      override;
        wpclsUnInitData:      override;
          wpclsQueryIcon:        override;
        wpclsQueryIcon:        override;
          wpclsQueryIconN:      override;
        wpclsQueryIconN:      override;
      };
    };
   
   
  #endif /* __SOMIDL__ */
#endif /* __SOMIDL__ */
   
   
  };
};
  #endif  /* CHFOLDR_IDL */
#endif  /* CHFOLDR_IDL */
</pre>
</pre>


Line 243: Line 233:
===Completing ChFoldr.cpp===
===Completing ChFoldr.cpp===
<pre>
<pre>
  //--------------- Completing wpclsInitData -----------------
//--------------- Completing wpclsInitData -----------------
  //
//
  // In this function a new CommandProcessor object is
// In this function a new CommandProcessor object is
  // created. This is a custom class that processes commands
// created. This is a custom class that processes commands
  // (via DosStartSession) and captures the command's output.
// (via DosStartSession) and captures the command's output.
  // Any C++ object could be created here with "new." This
// Any C++ object could be created here with "new." This
  // object is created in a MetaClass function because only
// object is created in a MetaClass function because only
  // one CommandProcessor object is needed, regardless of how
// one CommandProcessor object is needed, regardless of how
  // many ChartFolder objects exist. The same is true for the
// many ChartFolder objects exist. The same is true for the
  // icon handles.
// icon handles.
  //----------------------------------------------------------
//----------------------------------------------------------
   
   
  SOM_Scope void  SOMLINK
SOM_Scope void  SOMLINK
              ChFolderX_wpclsInitData(M_ChartFolder *somSelf)
            ChFolderX_wpclsInitData(M_ChartFolder *somSelf)
  {
{
      M_ChartFolderData *somThis =
    M_ChartFolderData *somThis =
                          M_ChartFolderGetData(somSelf);
                        M_ChartFolderGetData(somSelf);
      M_ChartFolderMethodDebug("M_ChartFolder",
    M_ChartFolderMethodDebug("M_ChartFolder",
                                "ChFolderX_wpclsInitData");
                              "ChFolderX_wpclsInitData");
   
   
      IDynamicLinkLibrary dll("chfoldr");
    IDynamicLinkLibrary dll("chfoldr");
   
   
    // load regular icon handle
  // load regular icon handle
   
   
      somThis->hChartFolderIcon =
    somThis->hChartFolderIcon =
                      dll.loadIcon(WPICONID_CHFOLDR, false);
                    dll.loadIcon(WPICONID_CHFOLDR, false);
   
   
    // load the animated icon handle
  // load the animated icon handle
   
   
      somThis->hChartFolderOpenIcon =
    somThis->hChartFolderOpenIcon =
                    dll.loadIcon(WPICONID_CHFOLDR_OPEN, false);
                  dll.loadIcon(WPICONID_CHFOLDR_OPEN, false);
   
   
    // instantiate the command processor
  // instantiate the command processor
   
   
      try {
    try {
            CommandProcessor *p = new CommandProcessor;
          CommandProcessor *p = new CommandProcessor;
            somThis->pCmdProc = (unsigned long)p;
          somThis->pCmdProc = (unsigned long)p;
          }
        }
      catch(IException& e)
    catch(IException& e)
          {
        {
            IMessageBox msgBox(IWindow::desktopWindow());
          IMessageBox msgBox(IWindow::desktopWindow());
            msgBox.setTitle(
          msgBox.setTitle(
                          "ChFolderX_wpclsInitData Exception");
                        "ChFolderX_wpclsInitData Exception");
            msgBox.show(e);
          msgBox.show(e);
          }
        }
   
   
      M_ChartFolder_parent_M_WPFolder_wpclsInitData(somSelf);
    M_ChartFolder_parent_M_WPFolder_wpclsInitData(somSelf);
  }
}
   
   
  //-------------- Completing wpclsUnInitData ----------------
//-------------- Completing wpclsUnInitData ----------------
  //
//
  // In this function the CommandProcessor object created in
// In this function the CommandProcessor object created in
  // wpclsInitData is deleted. Recall that the pointer to the
// wpclsInitData is deleted. Recall that the pointer to the
  // CommandProcessor object is stored as an unsigned long.
// CommandProcessor object is stored as an unsigned long.
  //----------------------------------------------------------
//----------------------------------------------------------
   
   
  SOM_Scope void  SOMLINK
SOM_Scope void  SOMLINK
              ChFolderX_wpclsUnInitData(M_ChartFolder *somSelf)
            ChFolderX_wpclsUnInitData(M_ChartFolder *somSelf)
  {
{
      M_ChartFolderData *somThis =
    M_ChartFolderData *somThis =
                              M_ChartFolderGetData(somSelf);
                            M_ChartFolderGetData(somSelf);
      M_ChartFolderMethodDebug("M_ChartFolder",
    M_ChartFolderMethodDebug("M_ChartFolder",
                                "ChFolderX_wpclsUnInitData");
                              "ChFolderX_wpclsUnInitData");
   
   
    // delete the command processor created in wpclsInitData
  // delete the command processor created in wpclsInitData
   
   
      CommandProcessor *p =
    CommandProcessor *p =
                        (CommandProcessor *)somThis->pCmdProc;
                      (CommandProcessor *)somThis->pCmdProc;
      delete p;
    delete p;
   
   
      M_ChartFolder_parent_M_WPFolder_wpclsUnInitData(somSelf);
    M_ChartFolder_parent_M_WPFolder_wpclsUnInitData(somSelf);
  }
}
</pre>
</pre>


Line 322: Line 312:
Please Note: It is not the intent of this writer to provide full listings of working programs in this article. The purpose of this article is to show the reader how to write C++ code that references WPS objects.
Please Note: It is not the intent of this writer to provide full listings of working programs in this article. The purpose of this article is to show the reader how to write C++ code that references WPS objects.
<pre>
<pre>
  //------------------ MicroData::MicroData ------------------
//------------------ MicroData::MicroData ------------------
  //
//
  // Note that the class dll includes the resources for this
// Note that the class dll includes the resources for this
  // frame window.
// frame window.
  //----------------------------------------------------------
//----------------------------------------------------------
   
   
  MicroData::MicroData(ChartFolder *PChartFolder)
MicroData::MicroData(ChartFolder *PChartFolder)
            : IFrameWindow(IResourceId(WND_MICRODATA,
          : IFrameWindow(IResourceId(WND_MICRODATA,
                              IDynamicLinkLibrary("chfoldr")),
                            IDynamicLinkLibrary("chfoldr")),
                          IFrameWindow::defaultStyle() |
                        IFrameWindow::defaultStyle() |
                          IFrameWindow::menuBar        |
                        IFrameWindow::menuBar        |
                          IFrameWindow::minimizedIcon)
                        IFrameWindow::minimizedIcon)
            , menuBar(IResourceId(WND_MICRODATA,
          , menuBar(IResourceId(WND_MICRODATA,
                      IDynamicLinkLibrary("chfoldr")),this)
                    IDynamicLinkLibrary("chfoldr")),this)
            , myTitle(this)
          , myTitle(this)
            , pChartFolder(PChartFolder)
          , pChartFolder(PChartFolder)
            , appName("MICRODATA")
          , appName("MICRODATA")
            , pOpenDialog(0)
          , pOpenDialog(0)
            , pQuoteSeq(0)
          , pQuoteSeq(0)
  {
{
    // First, get the required SOM Environment pointer
  // First, get the required SOM Environment pointer
   
   
      pSomEnv = somGetGlobalEnvironment();
    pSomEnv = somGetGlobalEnvironment();
   
   
    // Now, get the pointer to the Meta Class, then
  // Now, get the pointer to the Meta Class, then
    // use the pointer to the Meta Class to get the pointer
  // use the pointer to the Meta Class to get the pointer
    // to the global command processor object.
  // to the global command processor object.
   
   
      M_ChartFolder *pMetaClass = pChartFolder->somGetClass();
    M_ChartFolder *pMetaClass = pChartFolder->somGetClass();
      pCmdProc = (CommandProcessor *)
    pCmdProc = (CommandProcessor *)
                  (pMetaClass->queryCommandProcessor(pSomEnv));
                (pMetaClass->queryCommandProcessor(pSomEnv));
   
   
    // IString baseTitle is a member of this class
  // IString baseTitle is a member of this class
    //
  //
    // Use the wpQueryTitle function to get the name of the
  // Use the wpQueryTitle function to get the name of the
    // folder being updated
  // folder being updated
    //
  //
    // Change the title bar to include the name of the folder
  // Change the title bar to include the name of the folder
   
   
      baseTitle = "Update quotes in ";
    baseTitle = "Update quotes in ";
      baseTitle += pChartFolder->wpQueryTitle();
    baseTitle += pChartFolder->wpQueryTitle();
      myTitle.setText(baseTitle);
    myTitle.setText(baseTitle);
   
   
      ... // non WPS code is excluded to shorten this article
    ... // non WPS code is excluded to shorten this article
   
   
   
   
      return;
    return;
  }
}
   
   
   
   
  //---------------MicroData::processSelectedFile-------------
//---------------MicroData::processSelectedFile-------------
  //
//
  // This function is executed after a file is downloaded, or
// This function is executed after a file is downloaded, or
  // the user selects a previously downloaded file. Only part
// the user selects a previously downloaded file. Only part
  // of this function will be included here to show how the
// of this function will be included here to show how the
  // next function, updateStocksInFolder, is started.
// next function, updateStocksInFolder, is started.
  //----------------------------------------------------------
//----------------------------------------------------------
  void MicroData::processSelectedFile()
void MicroData::processSelectedFile()
  {
{
      ...
    ...
   
   
      char szFilename[CCHMAXPATH];
    char szFilename[CCHMAXPATH];
      unsigned long ulLength = sizeof(szFilename);
    unsigned long ulLength = sizeof(szFilename);
   
   
    // Call wpQueryRealName with the third argument set to
  // Call wpQueryRealName with the third argument set to
    // true to get the fully qualified name of this folder.
  // true to get the fully qualified name of this folder.
    // What we really need here is the name of the underlying
  // What we really need here is the name of the underlying
    // directory.
  // directory.
   
   
      pChartFolder->wpQueryRealName(szFilename,
    pChartFolder->wpQueryRealName(szFilename,
                                    &ulLength, true);
                                  &ulLength, true);
   
   
      IString sChartPath = szFilename;
    IString sChartPath = szFilename;
   
   
    // Now, update all the ChartFile objects in this directory
  // Now, update all the ChartFile objects in this directory
   
   
      updateStocksInFolder(sChartPath);
    updateStocksInFolder(sChartPath);
   
   
      ...
    ...
   
   
      return;
    return;
  }
}
   
   
   
   
  //---------------MicroData::updateStocksInFolder------------
//---------------MicroData::updateStocksInFolder------------
  //
//
  // In this function, each object in the folder is checked
// In this function, each object in the folder is checked
  // for type. If the object is a ChartFile, the ChartFile
// for type. If the object is a ChartFile, the ChartFile
  // is checked to see if it needs to be updated.
// is checked to see if it needs to be updated.
  //----------------------------------------------------------
//----------------------------------------------------------
  void MicroData::updateStocksInFolder(IString& ChartPath)
void MicroData::updateStocksInFolder(IString& ChartPath)
  {
{
      IString    qSymbol, qTitle, inStr, tStr, tName,
    IString    qSymbol, qTitle, inStr, tStr, tName,
                  qExchange;
                qExchange;
      float      qHigh, qLow, qClose;
    float      qHigh, qLow, qClose;
      long      qVolume;
    long      qVolume;
      Date      qDate, sDate;
    Date      qDate, sDate;
      int        mm, dd, yyyy;
    int        mm, dd, yyyy;
      QuotePtr  pQuote;
    QuotePtr  pQuote;
      IString    fileName;
    IString    fileName;
      IString    sChartPath = ChartPath;
    IString    sChartPath = ChartPath;
   
   
      ChartFile      *pChart      = 0;
    ChartFile      *pChart      = 0;
      ChartFolder    *pNextFolder = 0;
    ChartFolder    *pNextFolder = 0;
   
   
    // Get a pointer to the WPFileSystem Meta Class. This is
  // Get a pointer to the WPFileSystem Meta Class. This is
    // used below to get a WPS object pointer from a fully
  // used below to get a WPS object pointer from a fully
    // qualified file name.
  // qualified file name.
   
   
      M_WPFileSystem *pClass = pChartFolder->somGetClass();
    M_WPFileSystem *pClass = pChartFolder->somGetClass();
   
   
    // FileDirectory is a custom class that uses DosFindFirst
  // FileDirectory is a custom class that uses DosFindFirst
    // and DosFindNext to retrieve the files in a given
  // and DosFindNext to retrieve the files in a given
    // directory.
  // directory.
   
   
      FileDirectory chartDirectory(sChartPath);
    FileDirectory chartDirectory(sChartPath);
   
   
      fileName = chartDirectory.getNext();
    fileName = chartDirectory.getNext();
   
   
      while (fileName.length() > 0)
    while (fileName.length() > 0)
            {
           {
          // If a subdirectory is found, call this function
          // (recursively) to process the subdirectory.
           // Then continue processing.
              if (chartDirectory.foundSubdirectory())
                {
                IString nextPath(sChartPath + "\\" + fileName);
                updateStocksInFolder(nextPath);
                }
            else
                {
   
   
              // Build a fully qualified file name and use it
        // If a subdirectory is found, call this function
              // to get a generic WPS Object pointer.
        // (recursively) to process the subdirectory.
        // Then continue processing.
   
   
                IString tFile(sChartPath + "\\" + fileName);
            if (chartDirectory.foundSubdirectory())
                WPObject *pObj =
              {
                      pClass->wpclsQueryObjectFromPath(tFile);
              IString nextPath(sChartPath + "\\" + fileName);
              updateStocksInFolder(nextPath);
              }
          else
              {
   
   
            // Build a fully qualified file name and use it
            // to get a generic WPS Object pointer.
   
   
              // Now, see if the object is a ChartFile object.
              IString tFile(sChartPath + "\\" + fileName);
              // If it is, see if it needs to be updated.
              WPObject *pObj =
              // Otherwise, go on to the next file in this
                    pClass->wpclsQueryObjectFromPath(tFile);
              // directory.
 
            // Now, see if the object is a ChartFile object.
            // If it is, see if it needs to be updated.
            // Otherwise, go on to the next file in this
            // directory.
   
   
                tName = pObj->somGetClassName();
              tName = pObj->somGetClassName();
   
   
                if (tName == "ChartFile")
              if (tName == "ChartFile")
                    {
                  {
   
   
                // This conversion is safe because we know
              // This conversion is safe because we know
                // this is a ChartFile object.
              // this is a ChartFile object.
   
   
                    pChart  = (ChartFile *)pObj;
                  pChart  = (ChartFile *)pObj;
   
   
                // Two files are downloaded. One with Stock
              // Two files are downloaded. One with Stock
                // quotes and one with Index Quotes.
              // quotes and one with Index Quotes.
                //
              //
                // When processing a file with Index quotes,
              // When processing a file with Index quotes,
                // use the ChartFile member function,
              // use the ChartFile member function,
                // getExchange, to make sure the ChartFile
              // getExchange, to make sure the ChartFile
                // represents an Index.
              // represents an Index.
   
   
                    if (selectedIndexFile())
                  if (selectedIndexFile())
                        {
                      {
                        qExchange =
                      qExchange =
                                  pChart->getExchange(pSomEnv);
                                pChart->getExchange(pSomEnv);
                        if (qExchange == "INDEX")
                      if (qExchange == "INDEX")
                            ;
                          ;
                        else
                      else
                            {
                          {
                            fileName =
                          fileName =
                                  chartDirectory.getNext();
                                chartDirectory.getNext();
                            continue;
                          continue;
                            }
                          }
                        }
                      }
   
   
                // All functions prefixed with pChart-> are
              // All functions prefixed with pChart-> are
                // ChartFile member functions. Refer to the
              // ChartFile member functions. Refer to the
                // first article in this series for more
              // first article in this series for more
                // information on these functions.
              // information on these functions.
   
   
                    qSymbol = pChart->getStockSymbol(pSomEnv);
                  qSymbol = pChart->getStockSymbol(pSomEnv);
                    qTitle  = pChart->wpQueryTitle();
                  qTitle  = pChart->wpQueryTitle();
                    try {
                  try {
   
   
                      // pQuoteSeq is a pointer to a custom
                    // pQuoteSeq is a pointer to a custom
                      // class derived from IKeyedSortedSet.
                    // class derived from IKeyedSortedSet.
   
   
                          pQuote =
                        pQuote =
                            pQuoteSeq->elementWithKey(qSymbol);
                          pQuoteSeq->elementWithKey(qSymbol);
   
   
                          qDate = pQuote->getQuoteDate();
                        qDate = pQuote->getQuoteDate();
   
   
                      // Date is a custom date class
                    // Date is a custom date class
                      // Compare the ChartFile's date to the
                    // Compare the ChartFile's date to the
                      // quote's date to see if the ChartFile
                    // quote's date to see if the ChartFile
                      // needs to be updated.
                    // needs to be updated.
   
   
                          Date
                        Date
                          sDate(pChart->getLastMM(pSomEnv),
                        sDate(pChart->getLastMM(pSomEnv),
                                pChart->getLastDD(pSomEnv),
                              pChart->getLastDD(pSomEnv),
                                pChart->getLastYYYY(pSomEnv));
                              pChart->getLastYYYY(pSomEnv));
   
   
                          if (sDate < qDate)
                        if (sDate < qDate)
                            {
                          {
                              tStr = IString("Updating: ")
                            tStr = IString("Updating: ")
                                  + qTitle;
                                + qTitle;
                              pStatusLine->setText(tStr);
                            pStatusLine->setText(tStr);
   
   
                              qHigh  = pQuote->getHigh();
                            qHigh  = pQuote->getHigh();
                              qLow    = pQuote->getLow();
                            qLow    = pQuote->getLow();
                              qClose  = pQuote->getClose();
                            qClose  = pQuote->getClose();
                              qVolume = pQuote->getVolume();
                            qVolume = pQuote->getVolume();
   
   
                          // QuoteRec and QuoteFile are also
                        // QuoteRec and QuoteFile are also
                          // custom classes. The previous
                        // custom classes. The previous
                          // article in this series covers
                        // article in this series covers
                          // the QuoteFile class as it relates
                        // the QuoteFile class as it relates
                          // to the WPS.
                        // to the WPS.
   
   
                              QuoteRec qr(qDate.getLong(),
                            QuoteRec qr(qDate.getLong(),
                                          qVolume,
                                        qVolume,
                                          qHigh, qLow, qClose);
                                        qHigh, qLow, qClose);
                              QuoteFile qf(pChart,ios::out |
                            QuoteFile qf(pChart,ios::out |
                                                  ios::app |
                                                ios::app |
                                                  ios::binary);
                                                ios::binary);
                              qf << qr;
                            qf << qr;
   
   
                              pChart->setLastDD(pSomEnv,
                            pChart->setLastDD(pSomEnv,
                                                qDate.getDD());
                                              qDate.getDD());
                              pChart->setLastMM(pSomEnv,
                            pChart->setLastMM(pSomEnv,
                                                qDate.getMM());
                                              qDate.getMM());
                              pChart->setLastYYYY(pSomEnv,
                            pChart->setLastYYYY(pSomEnv,
                                              qDate.getYYYY());
                                            qDate.getYYYY());
   
   
                          //  pChart->setLastPrice();
                        //  pChart->setLastPrice();
   
   
                              symbolsUpdated++;
                            symbolsUpdated++;
                            }
                          }
                          else
                        else
                            {
                          {
                              tStr = IString("Skipping: ")
                            tStr = IString("Skipping: ")
                                  + qTitle;
                                + qTitle;
                              pStatusLine->setText(tStr);
                            pStatusLine->setText(tStr);
                            }
                          }
                        }
                      }
                    catch (IException& e)
                  catch (IException& e)
                        {
                      {
                          tStr = IString("Skipping: ")
                        tStr = IString("Skipping: ")
                              + qTitle;
                            + qTitle;
                          pStatusLine->setText(tStr);
                        pStatusLine->setText(tStr);
                        }
                      }
                    }
                  }
                else    //  tName != "ChartFile"
              else    //  tName != "ChartFile"
                    ;
                  ;
                }        //  end if file (not directory)
              }        //  end if file (not directory)
   
   
              fileName = chartDirectory.getNext();
            fileName = chartDirectory.getNext();
            }  // end while
          }  // end while
   
   
      return;
    return;
  }
}
</pre>
</pre>


[[Category:SOM Articles]]
[[Category:SOM Articles]]

Latest revision as of 17:42, 6 January 2023

Work Place Shell Programming
Part: 1 / 2 / 3 / 4

Written by Chris Palchak

The ChartFolder Class

Overview

In this, the fourth article in this series, the ChartFolder class will be created. This class inherits from WPFolder and is used to hold ChartFile objects.

The SOM IDL for ChartFolder

The contents of ChFoldr.idl are listed below. For a description of the WPS functions that are overridden by ChartFolder, refer to the first article in this series. The only function that ChartFolder overrides that ChartFile doesn't override is wpclsQueryIconN. This function is the same as wpclsQueryIcon except that it returns the handle of the animated icon. (This is the icon that is displayed when the folder is open.)

The main difference between this class and the ChartFile class is that users of this class want to process the ChartFile objects contained by this ChartFolder object and not the ChartFolder object itself. This means that the user must be able to determine the drive and path of this folder and process its contents. The user must also be able to determine the types of the objects in a ChartFolder.

Note also that data member, pCommandProcessor, in the listing for ChFoldr.idl is declared as an unsigned long. This variable holds a pointer returned by "new CommandProcessor". Pointers to any type of object can be stored in unsigned long variables and typecast as needed.

In order to keep the length of this article reasonably short, only functions that are notably different from ChFile functions will be discussed.

ChFoldr.idl listing

 #ifndef CHFOLDR_IDL
 #define CHFOLDR_IDL
 #include <wpfolder.idl>
 interface M_ChartFolder;
 
 interface ChartFolder : WPFolder
 {
    #ifdef __SOMIDL__
 
 // Access methods for ChartFolder's data members
 
       float  getLowPriceCutoff();
       float  getLowPriceChangePct();
       float  getRegPriceChangePct();
       short  getStartDD();
       short  getStartMM();
       short  getStartYYYY();
       short  getEndDD();
       short  getEndMM();
       short  getEndYYYY();
       string getErrorFolder();
 
       void   setLowPriceCutoff(in float LowPrice);
       void   setLowPriceChangePct(in float LowPricePct);
       void   setRegPriceChangePct(in float RegPricePct);
       void   setStartDD(in short dd);
       void   setStartMM(in short mm);
       void   setStartYYYY(in short yyyy);
       void   setEndDD(in short dd);
       void   setEndMM(in short mm);
       void   setEndYYYY(in short yyyy);
       void   setErrorFolder(in string ErrorFolder);
 
    //------------------------------------------------------
    // This method that reallocates memory for ChartFile's
    // strings is necessary because string is defined as
    // "char *" in \ibmcpp\include\som\somcorba.h.
    //------------------------------------------------------
       string reallocateString(in string oldString,
                               in string newValue);
 
       implementation
       {
           externalstem = ChFolder;
           local;
           externalprefix = ChFolderX_;
           majorversion = 1;
           minorversion = 1;
           filestem = ChFoldr;
           metaclass = M_ChartFolder;
 
     //-----------------------------------------------------
     // Class method (function) overrides
     //-----------------------------------------------------
        // add my settings pages
           wpAddSettingsPages: override;
 
        // restore state when object is awaken
 
           wpRestoreState:     override;
 
        // save state during shut down or idle times
           wpSaveState:        override;
 
        // called when object is opened
           wpOpen:             override;
 
        // allocate memory for this object
           wpInitData:         override;
 
        // free allocated memory
           wpUnInitData:       override;
 
        // add my items to the pop-up menu
           wpModifyPopupMenu:  override;
 
        // process user selection of my menu items
           wpMenuItemSelected: override;
 
     //-----------------------------------------------------
     // Instance data (Exists separately for each
     // ChartFolder object). These are NOT declared with the
     // SOM IDL "attribute" statement so that the get
     // and set functions can be named manually.
     //-----------------------------------------------------
 
       // price changes that indicate an error or split
           float  lowPriceCutoff;
           float  lowPriceChangePct;
           float  regPriceChangePct;
 
       // first date to check
           short  startDD;
           short  startMM;
           short  startYYYY;
 
       // last date to check
           short  endDD;
           short  endMM;
           short  endYYYY;
 
       // for future use
           string errorFolder;
 
     //-----------------------------------------------------
     // Passthru Statements:
     // These statements are passed without change to the
     // generated "chfoldr.xih" and "chfoldr.xh" files.
     //-----------------------------------------------------
 
     // These statements get written to ChFoldr.xih.
     // ChFoldr.xih is included in ChFoldr.cpp.
 
         passthru C_xih_before =  ""
 
        " /* PM and OS2 include directives */"
        "   #define INCL_WINWORKPLACE"
        "   #define INCL_WIN"
        "   #define INCL_DOS"
        "   #include <os2.h>"
        ""
        " /* WPS include directives */"
        "   #define INCL_WPCLASS"
        "   #define INCL_WPFOLDER"
        "   #include <pmwp.h>"
        ""
        " /* C include directives */"
        "   #include <stdio.h>";
 
     // These statements get written to ChFoldr.xh.
     // ChFoldr.xh is included in C++ programs that
     // reference ChartFolder objects.
 
         passthru C_xh_before =  ""
        " /* PM and OS2 include directives */"
        "   #define INCL_WINWORKPLACE"
        "   #define INCL_WIN"
        "   #define INCL_DOS"
        "   #include <os2.h>"
        ""
        " /* WPS include directives */"
        "   #define INCL_WPCLASS"
        "   #define INCL_WPFOLDER"
        "   #include <pmwp.h>"
        ""
        " /* C include directives */"
        "   #include <stdio.h>";
       };
 
    #endif
 };
 
 //---------------------------------------------------------
 // Metaclass section:
 // ------------------
 // Describe the metaclass of ChartFolder. The Meta Class
 // defines data that is common (global) to all ChartFolder
 // objects. It also defines functions that operate on Meta
 // Class Data.
 //---------------------------------------------------------
 
 interface M_ChartFolder
 
 // Comment for parent WPFolder:
 
 {
 
   //
   // New class methods
   //
       unsigned long queryCommandProcessor();
 
   //
   // implementation
   //
 
 #ifdef __SOMIDL__
     implementation
     {
     // Class Modifiers
 
        externalstem = ChFolder;
        local;
        externalprefix = ChFolderX_;
        functionprefix = ChFolderC_;
        majorversion = 1;
        minorversion = 1;
        filestem = ChFoldr;
 
     // non-instance (global) data
 
        unsigned long  hChartFolderIcon;
        unsigned long  hChartFolderOpenIcon;
        unsigned long  pCmdProc;
 
     // Class method overrides
 
        wpclsInitData:         override;
        wpclsUnInitData:       override;
        wpclsQueryIcon:        override;
        wpclsQueryIconN:       override;
     };
 
 #endif /* __SOMIDL__ */
 
 };
 #endif   /* CHFOLDR_IDL */

Compiling ChFolder.idl

This file can be compiled with the following command:

sc.exe -s"xc;xh;xih;def" -S128000 chfoldr.idl.

The output from this command will be the C++ stub file, ChFoldr.cpp.

Completing ChFoldr.cpp

 //--------------- Completing wpclsInitData -----------------
 //
 // In this function a new CommandProcessor object is
 // created. This is a custom class that processes commands
 // (via DosStartSession) and captures the command's output.
 // Any C++ object could be created here with "new." This
 // object is created in a MetaClass function because only
 // one CommandProcessor object is needed, regardless of how
 // many ChartFolder objects exist. The same is true for the
 // icon handles.
 //----------------------------------------------------------
 
 SOM_Scope void  SOMLINK
             ChFolderX_wpclsInitData(M_ChartFolder *somSelf)
 {
     M_ChartFolderData *somThis =
                        M_ChartFolderGetData(somSelf);
     M_ChartFolderMethodDebug("M_ChartFolder",
                              "ChFolderX_wpclsInitData");
 
     IDynamicLinkLibrary dll("chfoldr");
 
  // load regular icon handle
 
     somThis->hChartFolderIcon =
                    dll.loadIcon(WPICONID_CHFOLDR, false);
 
  // load the animated icon handle
 
     somThis->hChartFolderOpenIcon =
                  dll.loadIcon(WPICONID_CHFOLDR_OPEN, false);
 
  // instantiate the command processor
 
     try {
          CommandProcessor *p = new CommandProcessor;
          somThis->pCmdProc = (unsigned long)p;
         }
     catch(IException& e)
         {
          IMessageBox msgBox(IWindow::desktopWindow());
          msgBox.setTitle(
                        "ChFolderX_wpclsInitData Exception");
          msgBox.show(e);
         }
 
     M_ChartFolder_parent_M_WPFolder_wpclsInitData(somSelf);
 }
 
 //-------------- Completing wpclsUnInitData ----------------
 //
 // In this function the CommandProcessor object created in
 // wpclsInitData is deleted. Recall that the pointer to the
 // CommandProcessor object is stored as an unsigned long.
 //----------------------------------------------------------
 
 SOM_Scope void  SOMLINK
            ChFolderX_wpclsUnInitData(M_ChartFolder *somSelf)
 {
     M_ChartFolderData *somThis =
                             M_ChartFolderGetData(somSelf);
     M_ChartFolderMethodDebug("M_ChartFolder",
                              "ChFolderX_wpclsUnInitData");
 
  // delete the command processor created in wpclsInitData
 
     CommandProcessor *p =
                      (CommandProcessor *)somThis->pCmdProc;
     delete p;
 
     M_ChartFolder_parent_M_WPFolder_wpclsUnInitData(somSelf);
 }

Processing the Contents of a ChartFolder

One of the items added to the pop-up menu for this class is "Update Quotes." This function FTPs a file containing a day's stock quotes (from Micro Data) and checks each ChartFile object within the ChartFolder to determine whether or not the ChartFile needs to be updated. The class that performs this function is called MicroData and is constructed from a pointer to the ChartFolder whose pop-up menu was used to begin the process.

Please Note: It is not the intent of this writer to provide full listings of working programs in this article. The purpose of this article is to show the reader how to write C++ code that references WPS objects.

 //------------------ MicroData::MicroData ------------------
 //
 // Note that the class dll includes the resources for this
 // frame window.
 //----------------------------------------------------------
 
 MicroData::MicroData(ChartFolder *PChartFolder)
          : IFrameWindow(IResourceId(WND_MICRODATA,
                             IDynamicLinkLibrary("chfoldr")),
                         IFrameWindow::defaultStyle() |
                         IFrameWindow::menuBar        |
                         IFrameWindow::minimizedIcon)
          , menuBar(IResourceId(WND_MICRODATA,
                    IDynamicLinkLibrary("chfoldr")),this)
          , myTitle(this)
          , pChartFolder(PChartFolder)
          , appName("MICRODATA")
          , pOpenDialog(0)
          , pQuoteSeq(0)
 {
  // First, get the required SOM Environment pointer
 
     pSomEnv = somGetGlobalEnvironment();
 
  // Now, get the pointer to the Meta Class, then
  // use the pointer to the Meta Class to get the pointer
  // to the global command processor object.
 
     M_ChartFolder *pMetaClass = pChartFolder->somGetClass();
     pCmdProc = (CommandProcessor *)
                (pMetaClass->queryCommandProcessor(pSomEnv));
 
  // IString baseTitle is a member of this class
  //
  // Use the wpQueryTitle function to get the name of the
  // folder being updated
  //
  // Change the title bar to include the name of the folder
 
     baseTitle = "Update quotes in ";
     baseTitle += pChartFolder->wpQueryTitle();
     myTitle.setText(baseTitle);
 
     ... // non WPS code is excluded to shorten this article
 
 
     return;
 }
 
 
 //---------------MicroData::processSelectedFile-------------
 //
 // This function is executed after a file is downloaded, or
 // the user selects a previously downloaded file. Only part
 // of this function will be included here to show how the
 // next function, updateStocksInFolder, is started.
 //----------------------------------------------------------
 void MicroData::processSelectedFile()
 {
     ...
 
     char szFilename[CCHMAXPATH];
     unsigned long ulLength = sizeof(szFilename);
 
  // Call wpQueryRealName with the third argument set to
  // true to get the fully qualified name of this folder.
  // What we really need here is the name of the underlying
  // directory.
 
     pChartFolder->wpQueryRealName(szFilename,
                                   &ulLength, true);
 
     IString sChartPath = szFilename;
 
  // Now, update all the ChartFile objects in this directory
 
     updateStocksInFolder(sChartPath);
 
     ...
 
     return;
 }
 
 
 //---------------MicroData::updateStocksInFolder------------
 //
 // In this function, each object in the folder is checked
 // for type. If the object is a ChartFile, the ChartFile
 // is checked to see if it needs to be updated.
 //----------------------------------------------------------
 void MicroData::updateStocksInFolder(IString& ChartPath)
 {
     IString    qSymbol, qTitle, inStr, tStr, tName,
                qExchange;
     float      qHigh, qLow, qClose;
     long       qVolume;
     Date       qDate, sDate;
     int        mm, dd, yyyy;
     QuotePtr   pQuote;
     IString    fileName;
     IString    sChartPath = ChartPath;
 
     ChartFile      *pChart      = 0;
     ChartFolder    *pNextFolder = 0;
 
  // Get a pointer to the WPFileSystem Meta Class. This is
  // used below to get a WPS object pointer from a fully
  // qualified file name.
 
     M_WPFileSystem *pClass = pChartFolder->somGetClass();
 
  // FileDirectory is a custom class that uses DosFindFirst
  // and DosFindNext to retrieve the files in a given
  // directory.
 
     FileDirectory chartDirectory(sChartPath);
 
     fileName = chartDirectory.getNext();
 
     while (fileName.length() > 0)
           {
 
         // If a subdirectory is found, call this function
         // (recursively) to process the subdirectory.
         // Then continue processing.
 
            if (chartDirectory.foundSubdirectory())
              {
               IString nextPath(sChartPath + "\\" + fileName);
               updateStocksInFolder(nextPath);
              }
           else
              {
 
            // Build a fully qualified file name and use it
            // to get a generic WPS Object pointer.
 
               IString tFile(sChartPath + "\\" + fileName);
               WPObject *pObj =
                     pClass->wpclsQueryObjectFromPath(tFile);
  
            // Now, see if the object is a ChartFile object.
            // If it is, see if it needs to be updated.
            // Otherwise, go on to the next file in this
            // directory.
 
               tName = pObj->somGetClassName();
 
               if (tName == "ChartFile")
                  {
 
               // This conversion is safe because we know
               // this is a ChartFile object.
 
                   pChart  = (ChartFile *)pObj;
 
               // Two files are downloaded. One with Stock
               // quotes and one with Index Quotes.
               //
               // When processing a file with Index quotes,
               // use the ChartFile member function,
               // getExchange, to make sure the ChartFile
               // represents an Index.
 
                   if (selectedIndexFile())
                      {
                       qExchange =
                                pChart->getExchange(pSomEnv);
                       if (qExchange == "INDEX")
                           ;
                       else
                          {
                           fileName =
                                chartDirectory.getNext();
                           continue;
                          }
                      }
 
               // All functions prefixed with pChart-> are
               // ChartFile member functions. Refer to the
               // first article in this series for more
               // information on these functions.
 
                   qSymbol = pChart->getStockSymbol(pSomEnv);
                   qTitle  = pChart->wpQueryTitle();
                   try {
 
                     // pQuoteSeq is a pointer to a custom
                     // class derived from IKeyedSortedSet.
 
                        pQuote =
                          pQuoteSeq->elementWithKey(qSymbol);
 
                        qDate = pQuote->getQuoteDate();
 
                     // Date is a custom date class
                     // Compare the ChartFile's date to the
                     // quote's date to see if the ChartFile
                     // needs to be updated.
 
                        Date
                         sDate(pChart->getLastMM(pSomEnv),
                               pChart->getLastDD(pSomEnv),
                               pChart->getLastYYYY(pSomEnv));
 
                        if (sDate < qDate)
                           {
                            tStr = IString("Updating: ")
                                 + qTitle;
                            pStatusLine->setText(tStr);
 
                            qHigh   = pQuote->getHigh();
                            qLow    = pQuote->getLow();
                            qClose  = pQuote->getClose();
                            qVolume = pQuote->getVolume();
 
                        // QuoteRec and QuoteFile are also
                        // custom classes. The previous
                        // article in this series covers
                        // the QuoteFile class as it relates
                        // to the WPS.
 
                            QuoteRec qr(qDate.getLong(),
                                        qVolume,
                                        qHigh, qLow, qClose);
                            QuoteFile qf(pChart,ios::out |
                                                ios::app |
                                                ios::binary);
                            qf << qr;
 
                            pChart->setLastDD(pSomEnv,
                                              qDate.getDD());
                            pChart->setLastMM(pSomEnv,
                                              qDate.getMM());
                            pChart->setLastYYYY(pSomEnv,
                                            qDate.getYYYY());
 
                        //  pChart->setLastPrice();
 
                            symbolsUpdated++;
                           }
                        else
                           {
                            tStr = IString("Skipping: ")
                                 + qTitle;
                            pStatusLine->setText(tStr);
                           }
                       }
                   catch (IException& e)
                       {
                        tStr = IString("Skipping: ")
                             + qTitle;
                        pStatusLine->setText(tStr);
                       }
                  }
               else     //  tName != "ChartFile"
                   ;
              }         //  end if file (not directory)
 
            fileName = chartDirectory.getNext();
           }   // end while
 
     return;
 }