Work Place Shell Programming - Part 1/4Written by Chris Palchak |
PurposeThe purpose of this series of articles is to teach the reader how to integrate an application with the OS/2 Work Place Shell. As this writer always looks for ways to avoid using API calls, the settings pages are written in C++ using the IBM Visual Age for C++ compiler and Open Class Library. Hopefully, those readers who are unfamiliar with C++ will be inspired to learn the language once they see the brevity of the settings page programs. OverviewThere are two parts to a Work Place Shell (WPS) program. The first is a System Object Model (SOM) Interface Definition Language (IDL) source file. The second part, is the code you write in C, C++, or some other supported language. This first article will show the reader how to:
The third article in this series will show the reader how to access this class from another C++ program. The fourth article in this series will cover a second WPS class. SOM IDLIBM's SOM is the basis for all WPS objects. To create custom WPS objects, you must use the SOM IDL. This may seem intimidating at first, but note that there are only two categories of statements in the SOM IDL:
sc.exe -s"xc;xh;xih;def" -S128000 chfile.idl.In this case, chfile.idl is the SOM IDL file. The class described in this file is ChartFile. This is a class that inherits from WPDataFile and contains stock quotes. This is the first of two WPS classes that will be developed over the course of these articles. The other class that will be developed is ChartFolder. ChartFolder inherits from WPFolder and is used to store ChartFile objects. ChFile.idl listing: #ifndef CHFILE_IDL #define CHFILE_IDL #include <wpdataf.idl> interface M_ChartFile; interface ChartFile : WPDataFile { #ifdef __SOMIDL__ // Access methods for ChartFile's data void setStockSymbol(in string s); void setExchange(in string s); void setLastDD(in short dd); void setLastMM(in short mm); void setLastYYYY(in short yyyy); void setReversalBoxes(in short boxes); void setBoxSize(in float bSize); void setDaysInLongAvg(in short nDays); void setDaysInShortAvg(in short nDays); void setBarDataSaved(in short trueFalse); void setPfDataSaved(in short trueFalse); void setStockDataSaved(in short trueFalse); string getStockSymbol(); string getExchange(); short getLastDD(); short getLastMM(); short getLastYYYY(); short getReversalBoxes(); float getBoxSize(); short getDaysInLongAvg(); short getDaysInShortAvg(); // indicators: 0 = not saved, 1 = saved short getBarDataSaved(); short getPfDataSaved(); short getStockDataSaved(); //------------------------------------------------------ // 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 = ChFile; local; externalprefix = ChFileX_; majorversion = 1; minorversion = 1; filestem = ChFile; metaclass = M_ChartFile; //----------------------------------------------------- // 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 created wpSetup: 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 // ChartFile object). These are NOT declared with the // SOM IDL "attribute" statement so that the get // and set functions can be named manually. //----------------------------------------------------- // Stock Settings Page string stockSymbol; string exchange; short lastDD; short lastMM; short lastYYYY; // Point & Figure settings short reversalBoxes; float boxSize; // Bar Chart settings page short daysInLongAvg; short daysInShortAvg; // State Indicators 0 = not saved, 1 = saved short barDataSaved; short pfDataSaved; short stockDataSaved; //----------------------------------------------------- // Passthru Statements: // These statements are passed without change to the // generated "chfile.xih" and "chfile.xh" files. //----------------------------------------------------- // These statements get written to ChFile.xih. // ChFile.xih is included in ChFile.cpp. passthru C_xih_before = "" " /* PM and OS2 include directives */" " #define INCL_WINWORKPLACE" " #define INCL_WIN" " #include <os2.h>" "" " /* WPS include directives */" " #define INCL_WPCLASS" " #define INCL_WPObject" " #include <pmwp.h>" "" " /* C include directives */" " #include <stdio.h>" ""; // These statements get written to ChFile.xh. // ChFile.xh is included in C++ programs that // reference ChartFile objects. passthru C_xh_before = "" " /* PM and OS2 include directives */" " #define INCL_WINWORKPLACE" " #define INCL_WIN" " #include <os2.h>" "" " /* WPS include directives */" " #define INCL_WPCLASS" " #define INCL_WPObject" " #include <pmwp.h>" "" " /* C include directives */" " #include <stdio.h>" ""; }; #endif }; //--------------------------------------------------------- // Metaclass section: // ------------------ // Describe the metaclass of ChartFile. The Meta Class // defines data that is common (global) to all ChartFile // objects. It also defines functions that operate on Meta // Class Data. //--------------------------------------------------------- interface M_ChartFile // Comment for parent WPDataFile: { // // No new class methods // #ifdef __SOMIDL__ implementation { // Class Modifiers externalstem = ChFile; local; externalprefix = ChFileX_; functionprefix = ChFileC_; majorversion = 1; minorversion = 1; filestem = ChFile; // non-instance (global) data unsigned long hChartFileIcon; // Object's icon handle // Class method Modifiers // allocate required memory wpclsInitData: override; // free allocated memory wpclsUnInitData: override; // must override to make icon stick wpclsQueryIcon: override; // define the double-click view wpclsQueryDefaultView: override; }; #endif /* __SOMIDL__ */ }; #endif Building the DLLThe Module Definition FileThe following file is generated by the SOM compiler. This file must be modified to include the custom functions declared for setting and getting ChartFile's data. ChFile.def Listing ; This file was generated by the SOM Compiler. ; FileName: ChFile.def. ; Generated using: ; SOM Precompiler somipc: 2.29.1.7 ; SOM Emitter emitdef: 2.42 LIBRARY ChFile INITINSTANCE DESCRIPTION 'ChartFile Class Library' PROTMODE DATA MULTIPLE NONSHARED LOADONCALL EXPORTS ChartFileCClassData ChartFileClassData ChartFileNewClass M_ChartFileCClassData M_ChartFileClassData M_ChartFileNewClassThis is the modified module definition file. Note that there is no need to use mangled function names for this DLL because the exported functions are not really C++ class members. This file has been named Export.def so that it does not get overlaid when a new ChFile.def gets generated. Export.def Listing LIBRARY ChFile INITINSTANCE DESCRIPTION 'ChartFile Class Library' PROTMODE DATA MULTIPLE NONSHARED LOADONCALL EXPORTS ChartFileCClassData @1 ChartFileClassData @2 ChartFileNewClass @3 M_ChartFileCClassData @4 M_ChartFileClassData @5 M_ChartFileNewClass @6 ChFileX_setBoxSize @7 ChFileX_getBoxSize @8 ChFileX_getLastYYYY @9 ChFileX_setStockSymbol @10 ChFileX_setLastYYYY @11 ChFileX_setLastMM @12 ChFileX_setDaysInShortAvg @13 ChFileX_getReversalBoxes @14 ChFileX_setReversalBoxes @15 ChFileX_setExchange @16 ChFileX_setDaysInLongAvg @17 ChFileX_getLastDD @18 ChFileX_getExchange @19 ChFileX_getDaysInLongAvg @20 ChFileX_getLastMM @21 ChFileX_getStockSymbol @22 ChFileX_getDaysInShortAvg @23 ChFileX_setLastDD @24ChFile.mak Listing # ChFile.mak # Created by IBM WorkFrame/2 MakeMake at 21:59:45 on # 13 May 1997 # # The actions included in this make file are: # Compile::SOM Compiler # Compile::C++ Compiler # Lib::Import Lib (from def) # Link::Linker # .SUFFIXES: .IDL .cpp .obj .rc .res .def .all: \ .\ChFile.LIB \ .\ChFile.dll .IDL.cpp: @echo " Compile::SOM Compiler " sc.exe -s"xc;xh;xih;def" -S128000 %s .cpp.obj: @echo " Compile::C++ Compiler " icc.exe /Ti /Gm /Gd /Ge- /C %s .\ChFile.LIB: \ .\Export.def @echo " Lib::Import Lib (from def) " implib.exe ChFile.LIB export.def .\ChFile.dll: \ .\ChFile.obj \ .\Export.def \ {$(LIB)}somtk.lib @echo " Link::Linker " icc.exe @<< /B" /de /noe" /FeChFile.dll ChFile.obj somtk.lib Export.def << .\ChFile.cpp: \ d:\som\ChFile\ChFile.IDL .\ChFile.obj: \ .\ChFile.cpp \ {D:\som\ChFile;$(INCLUDE);}ChFile.xih \ Registering ChartFileThe following REXX program will register the ChartFile class: /* REXX: Register */ Call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'; Call SysLoadFuncs; rc=SysRegisterObjectClass('ChartFile','chfile'); If rc <> 1 Then Do; Say "ChartFile: could not register ChartFile, rc="rc "."; Exit; End; Exit; Creating instances ChartFileEven though the SOM compiler creates a C++ class, you can NOT use the "new" operator to create WPS objects. The following REXX program will create a ChartFile object in the Charts directory on drive d:. Alternatively, WinCreateObject can be used to create new ChartFile objects. /* REXX: Create */ Call RxFuncAdd'SysLoadFuncs','REXXUTIL','SysLoadFuncs'; Call SysLoadFuncs; rc=SysCreateObject('ChartFile','Mitchell Energy&Dev Cl A', 'D:\Charts','','replace'); Exit; Deregistering ChartFileThe following REXX program will deregister the ChartFile class: /* REXX: Deregister */ Call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'; Call SysLoadFuncs; rc=SysDeregisterObjectClass('ChartFile'); If rc <> 1 Then Do; Say "ChartFile: could not deregister"; End; Exit; Debugging a WPS DLLBe sure to read the following section in the Workplace Shell Programming Guide that comes with the OS/2 toolkit: Using Workplace Shell Debugging TechniquesThis is a subsection of the main section: Debugging Workplace Shell ApplicationsThis information is VERY useful. It shows how to bring up OS/2 with an OS/2 window instead of the WPS. It also shows how to start, stop, and, debug the WPS. Since a DLL can not be debugged directly, the programmer must debug PMSHELL.EXE (the WPS) and set a "Load" break point for the DLL in question. |