═══ 1. Introduction ═══ VisPro/REXX provides access to the SOM class hierarchy to allow extending the set of objects. This allows you to: o Add your own icons to the VisPro/REXX tool bar. o Define events for your object. o Define a Style page for your object's Settings notebook. o Specify methods that will appear in the Create Link window. o Specify help panel IDs for your object and object Style page. Extending VisPro/REXX requires knowledge in the following areas: o 'C' language programming o SOM programming o OS/2 Presentation Manager programming o Creating REXX extensions ═══ 1.1. OS/2 Presentation Manager Custom Controls ═══ The behavior for your object should be defined within an OS/2 PM custom control. This allows many existing OS/2 PM objects to be easily integrated into VisPro/REXX, while minimizing your reliance on a proprietary class library and, ultimately, protecting your investment. Since PM controls are supported, when an object is used within a form, VisPro/REXX stores the size, position, text, color, font, and attributes for instances of your objects within a standard OS/2 Presentation Manager Dialog Resource file. Presentation Manager Custom Controls Your PM control should support the following: o Instantiation using WinCreateWindow() o Handling of text using WinSetWindowText() and WinQueryWindowText() if text is displayed in your window. This allows users to change the text of your object from within the VisPro/REXX views. (See WM_SETWINDOWPARAMS in the OS/2 Programmer's Reference for more information) o Presentation Parameters - PP_FONTNAMESIZE for fonts - PP_FOREGROUNDCOLOR for foreground colors - PP_BACKGROUNDCOLOR for background colors If your PM control has attributes that can be set, define a Style page that allows these attributes to be set from within the VisPro/REXX views. To allow VisPro/REXX to save and restore these attributes, store the attributes in the following standard ways: o Window Style Word - This is a PM defined word used for specifying style bits for your control. WS_VISIBLE, WS_DISABLED, and WS_GROUP, and WS_TABSTOP are reserved, but the other bits are available to you. (See WinSetWindowUShort(,,QWS_STYLE) in the OS/2 Programmer's Reference for more information) o Control Data - If the style bits are insufficient for storing the attributes that can be set for your control, you can make your control respond to WM_QUERYWINDOWPARAMS and WM_SETWINDOWPARAMS with the WPM_CTLDATA option. This allows you to allocate a block of memory to hold information about your control. For an example, see the ENTRYFDATA structure description for the WC_ENTRYFIELD in the OS/2 PM Programmer's Reference. Finally, define your events as WM_CONTROL messages. WM_CONTROL messages are PM messages that are sent to the owner window of a control when a user interaction occurs. ═══ 1.2. Extending VisPro/REXX by Subclassing VPOBJ ═══ An abstract object class, VPOBJ, is made available for extending VisPro/REXX. You must subclass this object to define information about your new object class. Certain class methods must be overridden to integrate your object into the VisPro/REXX environment. Upon completion, your object will be contained in a DLL file. The DLL file includes the following: o SOM method definitions o Window Procedure for your PM Control o Dialog Procedure for your Style page (optional) o Dialog Resource for your Style page (optional) o POINTER Resources for your object's icon as well as the icons for any events Note: The name of your object class must be identical to the name of the .DLL file. ═══ 2. Sample Objects ═══ Two samples are included with the VisPro/REXX SOM Toolkit. o VPDIAL - MMPM/2 Circular Slider o VPTEXT - Rotatable Text Object This examples are described in the following sections. ═══ 2.1. The Circular Slider Example ═══ This sample provides a good example for extending an existing PM custom control. This object is virtually identical to the cirucular slider object shipped with VisPro/REXX Gold Edition. Three events are supported: o Entered o Changed o Tracking Several VpDial methods are defined, all of which will appear in the VisPro/REXX 'Create Link...' window. These methods allow you to set the range and appearance of the circular slider. There is also a dialog defined to be used as a Style page for the object Settings View. This allows the program to visually select attributes for the circular slider. ═══ 2.2. The Rotated Text Example ═══ This sample show you how to define your own PM custom control and tie it into VisPro/REXX SOM object hierarchy. It is a static object that has no events defined for it. It is a piece of text which can appear drawn at selected angles. The highlites of this example are: o Defining a custom control o Supporting a PM 'text' attribute o Supporting a control data block You can support text for your control by implementing a handler for the WM_QUERYWINDOWPARAMS and WM_SETWINDOWPARAMS in the controls window procedure. This allows your control to respond to WinSetWindowText, WinQueryWindowText, and WinQueryWindowTextLength. From a VisPro/REXX context, programmers will be able to direct edit the object as well as change the objects text for the General page or the List View. Also, VpSetItemValue, and VpGetItemValue can be used to set and query the text for the object. You can support a control block for your control by implementing a handler for the WM_QUERYWINDOWPARAMS and WM_SETWINDOWPARAMS in the window procedure as well as properly handling the WM_CREATE message. This allows you to extend the information stored for your object. In this example, the information is a Gradient structure that allows you to define the angle for the baseline for the drawn text. This gradient can be changed using the objects Styles page on the Settings View. The gradient will be stored by VisPro/REXX in a form's resource file. ═══ 3. What You Need ═══ The following files are included with the VisPro/REXX SOM Toolkit and are required for creating your SOM object: o VPOBJ.H - Include file o VPOBJ.SC - Class Definition File o VPOBJ.LIB - VPOBJ lib export file You also need IBM's CSET/2 compiler and the OS/2 2.0 Developer's Toolkit. ═══ 4. The Abstract Class VPOBJ ═══ The VPOBJ object class is an abstract class to be subclassed to add objects to the VisPro/REXX environment. ═══ 4.1. Class Methods ═══ These Class methods should be overridden within your SOM object. ═══ 4.1.1. _somInitClass ═══ Override: Yes SOM_Scope void SOMLINK vpdiac_somInitClass(M_VPDial *somSelf, IN zString className, IN SOMAny *parentClass, IN integer4 instanceSize, IN int maxStaticMethods, IN integer4 majorVersion, IN integer4 minorVersion) Called by: SOM when your object class is being initialized Use: Overriding this method allows you to perform initialization for your object class. Within your method implementation you should do the following: o Load your resources with DosLoadModule() o Register your control using WinRegisterClass() o Register your REXX extensions using RexxRegisterFunctionDll() ═══ 4.1.2. _InitHelpInstance ═══ Override: Yes SOM_Scope HWND SOMLINK vpdiac_InitHelpInstance(M_VPDial *somSelf) Called by: VisPro/REXX when a user requests help for your object. Use: Overriding this method allows you to initialize the IPF help instance for your object's help panels. ═══ 4.1.3. _QueryClassInfo ═══ Override: Yes SOM_Scope VOID SOMLINK vpdiac_QueryClassInfo(M_VPDial *somSelf, PVPCLASSINFO pVpClassInfo) Called by: VisPro/REXX when your object class is initialized. Use: Overriding this method allows you to populate the members of the VPCLASSINFO structure. This structure is described below: typedef struct _VPCLASSINFO { ULONG cbSize; PSZ pszDescName; /* descriptive name of object */ PSZ pszAbbrevName; /* abbreviated name for the object, ie. PB */ BOOL bHasText; /* does the object support direct editing */ PSZ pszDefaultText; /* default text for controls that have it */ BOOL bHasCtrlData; /* does the object have create data */ PSZ pszWindowClass; /* WC_* or the registered class name */ LONG lDefaultWidth; /* default width for a new object */ LONG lDefaultHeight; /* default height for a new object */ ULONG ulDefaultStyle; /* default window style for a new object */ PVOID pDefaultCtrlData; /* pointer to default control data */ HMODULE hModResource; /* module handle for resource file */ LONG lIconResID; /* pointer resource id for the object */ LONG lStyleDlgID; /* style dialog id for the styles page */ PFNWP pfnwpStyleDlgProc; /* address of the dialog style dialog proc */ LONG lToolHelpID; /* id for the tool help */ LONG lStylesPageHelpID; /* id for the styles notebook help */ HWND hwndHelpInstance; /* handle for the help instance */ LONG lNumEvents; /* number of events defined for this class */ VPEVENTITEM Events[MAXNUMEVENTS]; /* event table for custom events */ ULONG usTranslate[MAXNUMEVENTS]; //notification ids for each event wm_control //unused entries hold 0 PVPLOGICITEM Logic; /* logic models for linking */ HPOINTER hptrIcon; /* reserved */ HPOINTER hptrMouse; /* reserved */ ULONG ulReserved; /* reserved */ ULONG ulReserved2; /* reserved */ } VPCLASSINFO; The Events array is a list of VPEVENTITEM structures for your object. The maximum number of events is 32. typedef struct _VPEVENTITEM { PSZ pszDescName; /* Descriptive name for the event */ PSZ pszAbbrevName; /* abbrev name for the object, ie. 1CLK */ PSZ pszModel; /* reserved must be zero */ ULONG useFlags; /* reserved must be zero */ LONG lIconResID; /* pointer resource id for the event */ LONG lHelpID; /* reserved */ HPOINTER hptrIcon; /* reserved */ } VPEVENTITEM; typedef VPEVENTITEM *PVPEVENTITEM; The Logic pointer is a pointer to a block of VPLOGICITEM structures. These structures allow you to define items that will appear in the Create Link window for your object. typedef struct _VPLOGICITEM { LONG lHelpID; /* help panel id for the Create Link... item */ PSZ pszDescName; /* descriptive name for the REXX extension */ PSZ pszModel; /* function call prototype */ ULONG menuUseFlags; /* reserved */ ULONG useFlags; /* reserved */ } VPLOGICITEM; typedef VPLOGICITEM *PVPLOGICITEM; ═══ 4.1.4. _QueryHelpInstance ═══ Override: Not recommended SOM_Scope HWND SOMLINK vprc_QueryHelpInstance(M_VPObj *somSelf) Called by: WM_HELP message handler for a Style page dialog procedure. Use: Allows you to get the handle to the help instance so that the help panel can be displayed. ═══ 4.2. Instance Methods ═══ These instance methods are provided for implementing a Style page for your object. They must not be overridden. ═══ 4.2.1. _GetHwnd ═══ Override: Not recommended SOM_Scope HWND SOMLINK vpr_GetHwnd(VPObj *somSelf) Called by: Your object's Style page dialog procedure. Use: Gets the PM handle for your object, which is displayed on the canvas of a VisPro/REXX Layout View. ═══ 4.2.2. _IndicateChanged ═══ Override: Not recommended SOM_Scope VOID SOMLINK vpr_IndicateChanged(VPObj *somSelf) Called by: Your object's Style page dialog procedure. Use: Flags that the objects attributes have changed and VisPro/REXX should save them to disk. ═══ 4.2.3. _RedrawObject ═══ Override: Not recommended SOM_Scope VOID SOMLINK vpr_RedrawObject(VPObj *somSelf) Called by: Your object's Style page dialog procedure. Use: Redraws the object on the canvas of a VisPro/REXX Layout View. This is used when an attribute has changed via user interaction with the Style page dialog. ═══ 4.2.4. _RecreateObject ═══ Override: Not recommended SOM_Scope VOID SOMLINK vpr_RecreateObject(VPObj *somSelf) Called by: Your object's Style page dialog procedure. Use: Redraws the object on the canvas of a VisPro/REXX Layout View. This is used when an attribute has changed via user interaction with the Style page dialog. Some attributes require that the object be recreated rather than just redrawn. For example, the LS_HORZSCROLL style bit for a listbox requires the object to be recreated in order for the scroll bar to appear. ═══ 5. The Circular Slider Example ═══ The circular slider example shows how an object was created to add the VisPro/REXX tool bar. The example consists of the following files: o VPDIAL.C - 'C' source file The 'C' Source file has several sections - Create Link... REXX extension definitions - Styles page dialog procedure - Rexx Extension entry point - Miscelleneous instance methods - Overridden Class methods o VPDIAL.CSC - SOM object definition file o VPDIAL.DEF - module definition file o VPDIAL.MAK - make file o VPDIAL.PTR - pointer for your object o VPDIAL.RC - resource file o VPDIALDG H - include file for the styles page dialog o VPDIALDG DLG - resource file for the styles page dialog o ENTER.PTR - pointer for When Entered event o CHANGED.PTR - pointer for When Changed event o TIMER.PTR - pointer for When Tracking event ═══ 6. Installation and Distribution of Your Object ═══ Your object will be contained within a .DLL file. In order to allow VisPro/REXX programmers to access your object, you must do these two things: 1. Place the .DLL in a directory contained in the LIBPATH statement of the CONFIG.SYS file. 2. Append the DLL/Object name to the VPRCLASS file. The VPRCLASS file is an ASCII text file, which is contained within the directory specified by the VISPRORX environment variable. (See DosGetEnv() in the OS/2 Programmer's Reference). If this environment variable has not been defined, you can assume that the VPRCLASS file exists within the C:\VISPRORX directory. When VisPro/REXX programmers distribute .EXE files created with VisPro/REXX, your object .DLL must be distributed with the .EXE file only if that object was used within that specific project. ═══ 7. Suggested Reading ═══ o IBM OS/2 2.0 Technical Library - System Object Model Guide and Reference - Presentation Manager Programmer's Reference - Presentation Manager Programmer's Guide - Presentation Manager REXX Programmer's Reference o OS/2 Developer Magazine, Winter 1993, "Demystifying Custom Controls", p. 120, Mark Benge, et. al.