Work Place Shell Programming - Part 3

From EDM2
Revision as of 17:11, 27 December 2016 by Ak120 (Talk | contribs)

Jump to: navigation, search
Work Place Shell Programming
Part: 1 / 2 / 3 / 4

Written by Chris Palchak

Referencing WPS Objects from a C++ Program

Overview

This is the third article in a series of articles on WPS programming. In this article, the following topics will be covered:

  • Referencing WPS objects from a C++ program,
  • Referencing the extended attributes attached to a WPDataFile child object, and,
  • Saving extended attributes when a file is overwritten.

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.

The BarChart Class

In previous article in this series, the wpOpen function was overridden to create a BarChart object. The BarChart object was constructed from somSelf. How does the BarChart class get information about the ChartFile object?

The first part of the constructor for BarChart appears as follows:

//----------------------------------------------------------
// Construct a BarChart Window from a ChartFile object.
//
// Notes:
//
// 1. wpQueryTitle() is called to get the description for
//    ChartFile object. The result is then used to set the
//    the title for this window. (ChartFile inherits the
//    wpQueryTitle() function from WPObject.)
//
// 2. The BarChart class and its resources are NOT found in
//    the DLL for this WPS class but exist in a separate
//    DLL (cmsdll).
//
// 3. The QuoteTable object is constructed from the
//    ChartFile pointer. More information on QuoteTable
//    appears later in this article.
//----------------------------------------------------------
BarChart::BarChart(ChartFile *PChartFile)
        : IFrameWindow(PChartFile->wpQueryTitle(),
                       IResourceId(WND_BARCHART,
                       IDynamicLinkLibrary("cmsdll")),
                       IFrameWindow::defaultStyle() |
                       IFrameWindow::minimizedIcon |
                       IFrameWindow::menuBar |
                       IFrameWindow::accelerator |
                       IFrameWindow::horizontalScroll)
        , pChartFile(PChartFile)
{
...
    qTable = new QuoteTable(pChartFile);
...
}

Reading the ChartFile

ChartFile objects store stock quotes. The quotes are loaded into memory from the file specified by WPS object. Recall that the ChartFile class inherits from WPDataFile. On the C++ side, QuoteTable uses another class QuoteFile, to handle the I/O for the ChartFile. QuoteFile inherits from the standard C++ fstream class.

//------------------QuoteFile declarations------------------
//
//----------------------------------------------------------
class QuoteFile : public fstream
{
  public:
   QuoteFile(ChartFile *PChartFile, int ioMode); // open a quote file
   QuoteFile(ChartFile *PChartFile);             // set filename only
   ~QuoteFile();

   int  operator>>(QuoteRec& qr);
   void operator<<(QuoteRec& qr);

  private:
   IString qualifiedQuoteFileName, quoteFileName;
   ChartFile *pChartFile;
};

QuoteFile Implementation

The only QuoteFile functions that are relevant to the WPS are the constructor and the destructor. In addition, a QuoteTable function, ReplaceTable, will be covered.

//------------------QuoteFile Constructor-------------------
//
// In this function, wpQueryRealName is used to get both the
// qualified and unqualified names for the specified
// ChartFile object. ChartFile inherits this function from
// WPDataFile. To get the qualified name (the name including
// the drive and directory) for the underlying file, set the
// third argument to true. To get the unqualified name for
// the underlying file, set the third argument to false.
//----------------------------------------------------------

QuoteFile::QuoteFile(ChartFile *PChartFile, int ioMode)
         : pChartFile(PChartFile)
{
    char fName[255];
    unsigned long fNameSize(0);
    IMessageBox msgBox(IWindow::desktopWindow());
    IMessageBox::Response msgResp = IMessageBox::cancel;

    do {
        fNameSize = sizeof(fName);
        memset(fName,0,sizeof(fName));

  // ChartFile inherits wpQueryRealName from WPFileSystem.

        int rcOk = pChartFile->wpQueryRealName(fName,
                                              &fNameSize,
                                               true);

        if (rcOk)
           {
            qualifiedQuoteFileName = fName;

   // open(...) and fail() are inherited from fstream

            open(qualifiedQuoteFileName,ioMode);

            if (fail())
               {
                IString oStr("Could not open ");
                oStr += qualifiedQuoteFileName;
                msgResp = msgBox.show(oStr,
                   IMessageBox::errorIcon |
                   IMessageBox::retryCancelButton);
               }
            else
               {
                fNameSize = sizeof(fName);
                memset(fName,0,sizeof(fName));
                rcOk =
                  pChartFile->wpQueryRealName(fName,
                                             &fNameSize,
                                              false);

                if (rcOk)
                    quoteFileName = fName;  // unqualified
                else
                    msgResp = msgBox.show(
                     "wpQueryRealName failed (unqualified)",
                      IMessageBox::errorIcon |
                      IMessageBox::retryCancelButton);
               }
           }
        else
            msgResp = msgBox.show(
                       "wpQueryRealName failed (qualified)",
                        IMessageBox::errorIcon |
                        IMessageBox::retryCancelButton);


       } while (msgResp == IMessageBox::retry);

    return;
}

Updating extended attributes from C++

One of the features of the BarChart class is that it allows the user to modify data from the chart. By right-clicking on a day's bar, a pop-up menu is displayed that provides the user with a variety of choices. When the BarChart is closed, the user has the option to save their changes. This means that the data in the ChartFile object must be replaced. This also means that the last date for which a quote exists may have been changed and this change must be made to the ChartFile object. The QuoteTable class contains the following function that replaces the QuoteFile.

//---------------QuoteTable::replaceTable-------------------
//
// This function uses the custom coded functions setLastDD,
// setLastMM, and, setLastYYYY functions to set the last
// date variables in the ChartFile object. If all quotes are
// deleted from the file, this date is set to a default
// value.
//----------------------------------------------------------

long QuoteTable::replaceTable()
{
    long lastDate;
    QuoteFile *pQf;
    char fName[255];
    unsigned long fNameSize = sizeof(fName);
    memset(fName,0,sizeof(fName));

    pQf = new QuoteFile(pChartFile,
                      ios::out | ios::binary | ios::trunc);

   // dump the table to the file

    for (int i = 0;i<=lastEntry;i++)
         *pQf << quote_table[i];

    if (lastEntry >= 0)
        lastDate = quote_table[lastEntry].qDate;
    else
        lastDate = 0;

    if (pChartFile)
       {

   // get the required pointer to the SOM environment

        Environment *pSomEnv = somGetGlobalEnvironment();

        if (lastDate > 0)
           {
   // Create a custom Date object

            Date qDate(lastDate);

   // Update the ChartFile attributes

            pChartFile->setLastDD(pSomEnv, qDate.getDD());
            pChartFile->setLastMM(pSomEnv, qDate.getMM());
            pChartFile->setLastYYYY(pSomEnv,
                                         qDate.getYYYY());
           }
        else
           {
   // Set to default date if no quotes are left in the file

            pChartFile->setLastDD(pSomEnv, 1);
            pChartFile->setLastMM(pSomEnv, 1);
            pChartFile->setLastYYYY(pSomEnv, 1997);
           }
       }

    delete pQf;   // see QuoteFile Destructor below

    return lastDate;
}

//------------------QuoteFile Destructor--------------------
//
// In the destructor, the file is closed and the arguments
// declared in ChFile.idl are rewritten. Since WPDataFile
// objects (and their descendants) store their attributes as
// extended attributes, and since the user could be
// replacing this file, it is necessary to replace
// (or re-create) the extended attributes as well as the
// data in this file.
//
// To do this, tell the ChartFile object that its
// attributes have changed by calling setStockDataSaved,
// setBarDataSaved, and, setPfDataSaved. These are custom
// functions that tell the object that it needs to save the
// related subset of attributes. Then call wpSaveDeferred
// which calls ChartFile's wpSaveState function during
// system shut down or idle time.
//----------------------------------------------------------

QuoteFile::~QuoteFile()
{
    if (pChartFile)
       {
        close();   // inherited from fstream

  // The environment pointer is required for WPS API calls

        Environment *pSomEnv = somGetGlobalEnvironment();

  // Make the ChartFile Object think this data was changed

        pChartFile->setStockDataSaved(pSomEnv, 1);
        pChartFile->setBarDataSaved(pSomEnv, 1);
        pChartFile->setPfDataSaved(pSomEnv, 1);

  // Now tell the chart file object to save its attributes.

        pChartFile->wpSaveDeferred();
       }
}