//----- Completing the reallocateString function ------- // // The wpFreeMem and wpAllocMem functions are documented // in the WPS Programming Reference. //------------------------------------------------------ SOM_Scope string SOMLINK ChFileX_reallocateString( ChartFile *somSelf, Environment *ev, string oldString, string newValue) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_reallocateString"); // Only call wpFreeMem if string was previously allocated if (oldString) somSelf->wpFreeMem(oldString); // Figure out how much memory is needed for the new string unsigned long ulReturnCode = 0; unsigned long ulBytes = strlen(newValue) + 1; // Allocate and populate the new string string newString = somSelf->wpAllocMem(ulBytes, &ulReturnCode); strcpy(newString, newValue); newString[ulBytes - 1] = 0; return newString; } //------ Completing the setStockSymbol function ---------- // // This is a typical set function for a string member // element. There is no need to include all string set // functions because they are so similar. //-------------------------------------------------------- SOM_Scope void SOMLINK ChFileX_setStockSymbol(ChartFile *somSelf, Environment *ev, string s) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_setStockSymbol"); // manually added code somThis->stockSymbol = somSelf->reallocateString(ev, somThis->stockSymbol, s); return; } //------ Completing the setLastYYYY function ----------- // // This is a typical set function for a non-string data // element. Again, because they are so similar, no other // set functions for non-string attributes will be // documented in this article. //------------------------------------------------------ SOM_Scope void SOMLINK ChFileX_setLastYYYY(ChartFile *somSelf, Environment *ev, short yyyy) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile","ChFileX_setLastYYYY"); somThis->lastYYYY = yyyy; // manually added return; } //------ Completing the getStockSymbol function ---------- // // This is a typical get function. There is no special // coding required in "get" functions for data members // that are of the type "string." //-------------------------------------------------------- SOM_Scope string SOMLINK ChFileX_getStockSymbol(ChartFile *somSelf, Environment *ev) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_getStockSymbol"); // Warning: returning a pointer. Other programs could // possibly modify the data at this address! return somThis->stockSymbol; } //---------------------------------------------------------- // Before adding settings pages, the window procedure // functions must be declared. //---------------------------------------------------------- MRESULT EXPENTRY ChFileWindowProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2); MRESULT EXPENTRY ChFileBarWindowProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2); MRESULT EXPENTRY ChFilePfWindowProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2); //---------------wpAddSettingsPages------------------------- // // This function adds the settings pages. Notes: // // 1. The resources for this class are bound to the object // class' dll. Therefore, the handle for this class' dll // can be used for the resource dll handle. // // 2. Refer to the PM reference for information on the // pageinfo structure. //---------------------------------------------------------- SOM_Scope BOOL SOMLINK ChFileX_wpAddSettingsPages(ChartFile *somSelf, HWND hwndNotebook) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_wpAddSettingsPages"); unsigned long hDll = IDynamicLinkLibrary("chfile").handle(); PAGEINFO pageinfo; // DID_STOCK_SETTINGS_DLG memset((PCH)&pageinfo,0,sizeof(PAGEINFO)); pageinfo.cb = sizeof(PAGEINFO); pageinfo.hwndPage = NULLHANDLE; pageinfo.usPageStyleFlags = BKA_MAJOR; pageinfo.usPageInsertFlags = BKA_FIRST; pageinfo.pfnwp = ChFileWindowProc; pageinfo.resid = hDll; pageinfo.dlgid = DID_STOCK_SETTINGS_DLG; pageinfo.pszName = "Stock"; pageinfo.pCreateParams = somSelf; pageinfo.idDefaultHelpPanel = 0; pageinfo.pszHelpLibraryName = 0; somSelf->wpInsertSettingsPage(hwndNotebook, &pageinfo); // DID_BAR_DLG memset((PCH)&pageinfo,0,sizeof(PAGEINFO)); pageinfo.cb = sizeof(PAGEINFO); pageinfo.hwndPage = NULLHANDLE; pageinfo.usPageStyleFlags = BKA_MINOR; pageinfo.usPageInsertFlags = BKA_LAST; pageinfo.pfnwp = ChFileBarWindowProc; pageinfo.resid = hDll; pageinfo.dlgid = DID_BAR_DLG; pageinfo.pszName = "Bar Chart"; pageinfo.pCreateParams = somSelf; pageinfo.idDefaultHelpPanel = 0; pageinfo.pszHelpLibraryName = 0; somSelf->wpInsertSettingsPage(hwndNotebook, &pageinfo); // DID_PF_DLG memset((PCH)&pageinfo,0,sizeof(PAGEINFO)); pageinfo.cb = sizeof(PAGEINFO); pageinfo.hwndPage = NULLHANDLE; pageinfo.usPageStyleFlags = BKA_MINOR; pageinfo.usPageInsertFlags = BKA_LAST; pageinfo.pfnwp = ChFilePfWindowProc; pageinfo.resid = hDll; pageinfo.dlgid = DID_PF_DLG; pageinfo.pszName = "P&F Chart"; pageinfo.pCreateParams = somSelf; pageinfo.idDefaultHelpPanel = 0; pageinfo.pszHelpLibraryName = 0; somSelf->wpInsertSettingsPage(hwndNotebook, &pageinfo); return (ChartFile_parent_WPDataFile_wpAddSettingsPages(somSelf, hwndNotebook)); } //--------Sample Window Procedure----------------------- // // Now, let's take a look at the window procedures for the // new settings pages. Its unfortunate that these are even // necessary but since they are needed, let's make them as // painless as possible. Only one of these procedures will // be documented here as they all look the same. // // Notes: // // 1. The only message that needs to be processed in this // procedure is WM_INITDLG. This message allows the // programmer to instantiate the dialog class. // // 2. The class definition for StockDlg (StockDlg.hpp) can // be directly included in ChFile.cpp. There is no reason // to use a passthru statement in the IDL file to include // a settings page header file. // // 3. The window handle is passed to the dialog class so // that the dialog class can construct an IFrameWindow // wrapper for the underlying PM Frame Window. The dialog // class is covered later in this article. //------------------------------------------------------ MRESULT EXPENTRY ChFileWindowProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2) { ChartFile *somSelf = (ChartFile *)mp2; // Who am I? if (msg == WM_INITDLG) { try { StockDlg *pDlg = new StockDlg(somSelf, hwndDlg); pDlg->setAutoDeleteObject(); } catch (IException& e) { IMessageBox msgBox(IWindow::desktopWindow()); msgBox.setTitle("StockDlg Exception"); msgBox.show(e); } return (MRESULT) TRUE; } else return WinDefDlgProc(hwndDlg, msg, mp1, mp2); } //------------ Completing wpInitData ----------------------- // // Allocate and initialize memory for this object. // Note that no memory is allocated for strings in this // function. The pointers are set to zero so the object // knows that no memory has been allocated. The reason for // this is that at this point, the program does not know // whether or not data exists for these elements. This is // determined in the wpRestoreState function (see below). //---------------------------------------------------------- SOM_Scope void SOMLINK ChFileX_wpInitData(ChartFile *somSelf) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile","ChFileX_wpInitData"); somThis->stockSymbol = 0; // initialize pointers to 0 somThis->exchange = 0; somThis->lastDD = 1; // set a default values for somThis->lastMM = 1; // all non-pointer fields. somThis->lastYYYY = 1997; somThis->reversalBoxes = 3; somThis->boxSize = 1.0; somThis->daysInLongAvg = 150; somThis->daysInShortAvg = 50; somThis->barDataSaved = 0; // 0 = not saved somThis->pfDataSaved = 0; // 1 = saved somThis->stockDataSaved = 0; ChartFile_parent_WPDataFile_wpInitData(somSelf); } //------------ Completing wpUnInitData --------------------- // // This function is called to free allocated memory. // Note that this function checks to see if memory was // allocated before freeing it. wpFreeMem doesn't // care for null pointers. //---------------------------------------------------------- SOM_Scope void SOMLINK ChFileX_wpUnInitData(ChartFile *somSelf) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_wpUnInitData"); if (somThis->stockSymbol) somSelf->wpFreeMem(somThis->stockSymbol); if (somThis->exchange) somSelf->wpFreeMem(somThis->exchange); ChartFile_parent_WPDataFile_wpUnInitData(somSelf); } //------------ Completing wpRestoreState ------------------- // // This function restores state when object is awaken. // Note that for WPDataFile objects and their descendants, // object data are stored as extended attributes. // wpRestoreString must be called to retrieve string data // from the file's extended attributes. wpRestoreLong must // be called to retrieve integer data from the file's // extended attributes. To avoid multiple sets of ids, the // dialog ids are used as keys when storing this data. // Notice how easily extended attributes are handled by WPS // programs. //---------------------------------------------------------- SOM_Scope BOOL SOMLINK ChFileX_wpRestoreState(ChartFile *somSelf, ULONG ulReserved) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_wpRestoreState"); char restoredData[40]; unsigned long maxLength, anyLong; int rcOk(0); // Get the environment pointer needed to call this class' // set functions. Environment *pSomEnv = somGetGlobalEnvironment(); // Now retrieve the data for this class' data members // and populate the data members. memset(restoredData,0,sizeof(restoredData)); maxLength = sizeof(restoredData) - 1; // Arguments are: Class Name, Id or Key, Buffer, Length // See the WPS Reference for more information. rcOk = somSelf->wpRestoreString("ChartFile", DID_TICKER_SYMBOL, restoredData, &maxLength); if (rcOk) somSelf->setStockSymbol(pSomEnv, restoredData); else somSelf->setStockSymbol(pSomEnv, ""); memset(restoredData,0,sizeof(restoredData)); maxLength = sizeof(restoredData) - 1; rcOk = somSelf->wpRestoreString("ChartFile", DID_EXCHANGE, restoredData, &maxLength); if (rcOk) somSelf->setExchange(pSomEnv, restoredData); else somSelf->setExchange(pSomEnv, ""); // Arguments are: Class Name, Id or Key, Buffer // See the WPS Reference for more information. rcOk = somSelf->wpRestoreLong("ChartFile", DID_MM, &anyLong); if (rcOk) somThis->lastMM = anyLong; else somThis->lastMM = 1; rcOk = somSelf->wpRestoreLong("ChartFile", DID_DD, &anyLong); if (rcOk) somThis->lastDD = anyLong; else somThis->lastDD = 1; rcOk = somSelf->wpRestoreLong("ChartFile", DID_YYYY, &anyLong); if (rcOk) somThis->lastYYYY = anyLong; else somThis->lastYYYY = 1997; memset(restoredData,0,sizeof(restoredData)); maxLength = sizeof(restoredData) - 1; rcOk = somSelf->wpRestoreString("ChartFile", DID_PF_BOX_SIZE, restoredData, &maxLength); // Doubles and floats seem best stored as strings. if (rcOk) somThis->boxSize = IString(restoredData).asDouble(); else somThis->boxSize = 1.0; rcOk = somSelf->wpRestoreLong("ChartFile", DID_PF_REVERSAL_BOXES, &anyLong); if (rcOk) somThis->reversalBoxes = anyLong; else somThis->reversalBoxes = 3; rcOk = somSelf->wpRestoreLong("ChartFile", DID_BAR_LONG_DAYS, &anyLong); if (rcOk) somThis->daysInLongAvg = anyLong; else somThis->daysInLongAvg = 150; rcOk = somSelf->wpRestoreLong("ChartFile", DID_BAR_SHORT_DAYS, &anyLong); if (rcOk) somThis->daysInShortAvg = anyLong; else somThis->daysInShortAvg = 50; return (ChartFile_parent_WPDataFile_wpRestoreState(somSelf, ulReserved)); } //------------ Completing wpSaveState ---------------------- // // This function saves an object's state during shut down or // idle times. Note that to save this object's data, // wpSaveString and wpSaveLong are invoked. Again, the // dialog id's are used as the key with which this data is // saved. //---------------------------------------------------------- SOM_Scope BOOL SOMLINK ChFileX_wpSaveState(ChartFile *somSelf) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile","ChFileX_wpSaveState"); Environment *pSomEnv = somGetGlobalEnvironment(); int rcOk(0); if (somThis->stockDataSaved) { rcOk = somSelf->wpSaveString("ChartFile", DID_TICKER_SYMBOL, somThis->stockSymbol); rcOk = somSelf->wpSaveString("ChartFile", DID_EXCHANGE, somThis->exchange); rcOk = somSelf->wpSaveLong("ChartFile", DID_MM, somThis->lastMM); rcOk = somSelf->wpSaveLong("ChartFile", DID_DD, somThis->lastDD); rcOk = somSelf->wpSaveLong("ChartFile", DID_YYYY, somThis->lastYYYY); somThis->stockDataSaved = 0; } if (somThis->pfDataSaved) { // Here, a float is stored as a string IString strBoxSize(somThis->boxSize); rcOk = somSelf->wpSaveString("ChartFile", DID_PF_BOX_SIZE, strBoxSize); rcOk = somSelf->wpSaveLong("ChartFile", DID_PF_REVERSAL_BOXES, somThis->reversalBoxes); somThis->pfDataSaved = 0; } if (somThis->barDataSaved) { rcOk = somSelf->wpSaveLong("ChartFile", DID_BAR_LONG_DAYS, somThis->daysInLongAvg); rcOk = somSelf->wpSaveLong("ChartFile", DID_BAR_SHORT_DAYS, somThis->daysInShortAvg); somThis->barDataSaved = 0; } return (ChartFile_parent_WPDataFile_wpSaveState(somSelf)); } //------------ Completing wpModifyPopupMenu ---------------- // // This function allows items to be added to object's the // pop-up menu. Recall that the resources are bound to this // class' dll. //---------------------------------------------------------- SOM_Scope BOOL SOMLINK ChFileX_wpModifyPopupMenu(ChartFile *somSelf, HWND hwndMenu, HWND hwndCnr, ULONG iPosition) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_wpModifyPopupMenu"); HMODULE hmod = IDynamicLinkLibrary("chfile").handle(); if (hmod) { somSelf->wpInsertPopupMenuItems(hwndMenu, 0, hmod, WPMENUID_CHFILE, 0); } return (ChartFile_parent_WPDataFile_wpModifyPopupMenu(somSelf, hwndMenu, hwndCnr, iPosition)); } //------------ Completing wpMenuItemSelected --------------- // // This function is called when the user selects an item // from the objects pop-up menu. The classes that use the // pointer to this object (e.g., BarChart) will be covered // in the next article in this series. If you want to build // this dll, comment out the references to BarChart and // PfChart. //---------------------------------------------------------- SOM_Scope BOOL SOMLINK ChFileX_wpMenuItemSelected(ChartFile *somSelf, HWND hwndFrame, ULONG ulMenuId) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile", "ChFileX_wpMenuItemSelected"); if (ulMenuId == WPMENUID_CHFILE_BARCHART) { try { BarChart *bc = new BarChart(somSelf); bc->setAutoDeleteObject(); } catch (IException& e) { IMessageBox msgBox(IWindow::desktopWindow()); msgBox.setTitle("BarChart Exception"); msgBox.show(e); } } else if (ulMenuId == WPMENUID_CHFILE_PFCHART) { try { PfChart *pf = new PfChart(somSelf); pf->setAutoDeleteObject(); } catch (IException& e) { IMessageBox msgBox(IWindow::desktopWindow()); msgBox.setTitle("PfChart Exception"); msgBox.show(e); } } else ; return (ChartFile_parent_WPDataFile_wpMenuItemSelected(somSelf, hwndFrame, ulMenuId)); } //------------------ Completing wpOpen --------------------- // // This function must be overridden to process class // specific views. In this case, the bar chart view is // established as the default view. Therefore, this // function is called with the BarChart menu id when the // user double clicks on a ChartFile object. (See // wpclsQueryDefaultView in a later section.) //---------------------------------------------------------- SOM_Scope HWND SOMLINK ChFileX_wpOpen(ChartFile *somSelf, HWND hwndCnr, ULONG ulView, ULONG param) { ChartFileData *somThis = ChartFileGetData(somSelf); ChartFileMethodDebug("ChartFile","ChFileX_wpOpen"); if (ulView == WPOPEN_BARCHART) { try { BarChart *bc = new BarChart(somSelf); bc->setAutoDeleteObject(); } catch (IException& e) { IMessageBox msgBox(IWindow::desktopWindow()); msgBox.setTitle("BarChart Exception"); msgBox.show(e); } } return (ChartFile_parent_WPDataFile_wpOpen(somSelf, hwndCnr, ulView, param)); }