Work Place Shell Programming - Part 3
Part: | 1 / 2 / 3 / 4 |
---|
Written by Chris Palchak
Contents
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(); } }