═══ Launching Objects on the OS/2 Desktop ═══ Launching Objects on the OS/2 Desktop by: Bruce E. HФgman Electronic Data Systems Corporation Boca Raton, Florida May, 1994 ═══ 1. Abstract ═══ This article discusses different methods of launching applications by using the OS/2 2.1 Workplace Shell (WPS). Then, using these methods, the article offers different approaches to customizing the OS/2 2.1 desktop both during and after installation. It addresses using applications of all types, both on an individual workstation and across a LAN, showing how OS/2 desktop objects can be defined to easily access applications that reside on either OS/2 LAN or other LAN systems. Sections in this article address PM session window creation and message processing, as well as WPS API function calls. The section on Window function calls, WinCreateObject, contains information about setup strings for objects. The section on wpSetup contains detailed information about some setup-string keyword value pairs. I also discuss my public-domain program, PMSW, which is a support mechanism for launching objects of different session types, as well as a means of synchronizing execution of different sessions at a high level. PMSW uses the entries in the PM desktop's Window List (also known as the "switch list" in the PM programming documentation) to determine which sessions are running. This article is based on inquiries from several OS/2 customers who to install standardized desktops on all of the computers in their environments. Some of the REXX programs described in this article are actual software solutions to real problems. ═══ 1.1. Disclaimer ═══ References in this article to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent program that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program, or service. The information contained in this article has not been submitted to any formal IBM test and is distributed as-is. The use of this information or the implementation of any of these techniques is a customer responsibility and depends on the customer's ability to evaluate and integrate them into the customer's operational environment. While each item may have been reviewed by IBM for accuracy in a specific situation, there is no guarantee that the same or similar results will be obtained elsewhere. Customers attempting to adapt these techniques to their own environments do so at their own risk. ═══ Figure 1: Program Tab ═══ ═══ Figure 2: Default Command Processors ═══ Figure 2: Default Command Processors ┌───────────────┬────────────────────────────────────────┐ │Session │Default Command Processor │ ├───────────────┼────────────────────────────────────────┤ │OS/2, PM │\OS2\CMD.EXE │ ├───────────────┼────────────────────────────────────────┤ │Windows │\OS2\MDOS\WINOS2\WINOS2.COM │ ├───────────────┼────────────────────────────────────────┤ │DOS │\OS2\MDOS\COMMAND.COM │ └───────────────┴────────────────────────────────────────┘ Figure 2: Default Command Processors ═══ Figure 3: Special Parameter Strings ═══ Figure 3. Special String Components in Parameters Entry Field of WPProgram Object ┌──────────┬─────────────────────────────────────────────┐ │String │Description │ │Component │ │ ├──────────┼─────────────────────────────────────────────┤ │%* │Fully qualified path of the file │ ├──────────┼─────────────────────────────────────────────┤ │%**P │Path with last backslash (except at root) │ ├──────────┼─────────────────────────────────────────────┤ │%**D │Path with ':' or UNC name │ ├──────────┼─────────────────────────────────────────────┤ │%**N │Name without extension │ ├──────────┼─────────────────────────────────────────────┤ │%**F │Name with extension │ ├──────────┼─────────────────────────────────────────────┤ │%**E │Extension without period │ └──────────┴─────────────────────────────────────────────┘ Figure 3. Special String Components in Parameters Entry Field of WPProgram Object ═══ Figure 4: Filename Association ═══ ═══ Figure 5: Type Association ═══ ═══ Figure 6: Defining New Default Action ═══ ═══ Figure 7: File Name & Extension Association ═══ ═══ Figure 8: Adding a New Menu Item ═══ ═══ Figure 9: RUN Commands in CONFIG.SYS ═══ RUN=C:\OS2\XCOPY.EXE C:\OS2\OS2.INI C:\OS2\INSTALL RUN=C:\OS2\XCOPY.EXE C:\OS2\OS2SYS.INI C:\OS2\INSTALL RUN=C:\OS2\XCOPY.EXE C:\CONFIG.SYS C:\OS2\INSTALL rem Figure 9: RUN Commands for Backing Up Critical OS/2 Files ═══ Figure 10: Novell Entries in INI.RC ═══ "PM_InstallObject" "Novell;WPFolder;;UPDATE" "ICONPOS=25 87;OBJECTID=" "PM_InstallObject" "Netware Tools;WPProgram;;UPDATE" "STARTUPDIR=C:\NETWARE;EXENAME=C:\NETWARE\NWTOOLS.EXE;PROGTYPE=PM" "PM_InstallObject" "Network Printer;WPProgram;;UPDATE" "STARTUPDIR=C:\NETWARE;EXENAME=C:\NETWARE\NPRINTER.EXE;PROGTYPE=PM" "PM_InstallObject" "Install;WPProgram;;UPDATE" "STARTUPDIR=C:\NETWARE;EXENAME=C:\NETWARE\INSTALL.EXE;PROGTYPE=PM" Figure 10: .RC File Entries for Novell NetWare ═══ Figure 11: WPObject Keyname/Value Pairs ═══ Figure 11. Keyname/Value Pairs for the WPObject Class ┌────────────┬────────────────┬──────────────────────────────┐ │Keyname │Value │Description │ ├────────────┼────────────────┼──────────────────────────────┤ │TITLE │=title; │Object's displayed title │ │ │ │string. │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONFILE │=filespec; │Specifies the .ICO file │ │ │ │containing the icon bitmap to │ │ │ │display. │ ├────────────┼────────────────┼──────────────────────────────┤ │HELPPANEL │=id; │Default help panel. The id is│ │ │ │usually a resource in a .DLL. │ ├────────────┼────────────────┼──────────────────────────────┤ │HELPLIBRARY │=filespec; │Defines the help library. │ ├────────────┼────────────────┼──────────────────────────────┤ │TEMPLATE │=YES; │This object is a template that│ │ │ │can be used to create similar │ │ │ │objects. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object is not a template.│ ├────────────┼────────────────┼──────────────────────────────┤ │NODELETE │=YES; │This object cannot be deleted.│ │ │ │Setting this property for an │ │ │ │object restricts users from │ │ │ │dragging it to the shredder. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can be deleted. │ ├────────────┼────────────────┼──────────────────────────────┤ │NOCOPY │=YES; │This object cannot be copied. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can be copied. │ ├────────────┼────────────────┼──────────────────────────────┤ │NOMOVE │=YES; │This object cannot be moved. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can be moved. │ ├────────────┼────────────────┼──────────────────────────────┤ │NOLINK │=YES; │This object cannot be linked │ │ │ │(make a shadow from) │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can be linked. │ ├────────────┼────────────────┼──────────────────────────────┤ │NOTVISIBLE │=YES; │This object is invisible. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object is visible. │ ├────────────┼────────────────┼──────────────────────────────┤ │NOPRINT │=YES; │This object cannot be printed.│ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object is printable. │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONRESOURCE│=id,module; │This defines the id of the │ │ │ │icon resource in the module's │ │ │ │dynamic link library (DLL). │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONPOS │=x,y; │Places the object's icon on │ │ │ │the desktop or within a folder│ │ │ │or container when the object's│ │ │ │location is not the desktop. │ │ │ │x,y is relative to the lower │ │ │ │left-hand corner and │ │ │ │represents percentages of the │ │ │ │full width and height. │ ├────────────┼────────────────┼──────────────────────────────┤ │OBJECTID │=; │This is an identity unique │ │ │ │within the system that will │ │ │ │stay with the object even if │ │ │ │it is moved or renamed as to │ │ │ │file name or title. The angle│ │ │ │brackets are part of the id │ │ │ │string. │ ├────────────┼────────────────┼──────────────────────────────┤ │NORENAME │=YES; │This object cannot be renamed.│ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can be renamed. │ ├────────────┼────────────────┼──────────────────────────────┤ │NODRAG │=YES; │This object cannot be dragged.│ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can be dragged. │ ├────────────┼────────────────┼──────────────────────────────┤ │NODROP │=YES; │This object cannot accept │ │ │ │dropped objects. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │This object can accept dropped│ │ │ │objects. │ ├────────────┼────────────────┼──────────────────────────────┤ │HIDEBUTTON │=YES; │Views of this object will have│ │ │ │a hide button. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │Views of this object will have│ │ │ │a minimize button instead. │ ├────────────┼────────────────┼──────────────────────────────┤ │MINWIN │=HIDE; │Views of this object will hide│ │ │ │when the minimize button is │ │ │ │selected. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=VIEWER; │Views of this object will │ │ │ │minimize to the viewer. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=DESKTOP; │Views of this object will │ │ │ │minimize to the desktop. An │ │ │ │icon appears on the "landing │ │ │ │area" at the lower left of the│ │ │ │desktop. │ ├────────────┼────────────────┼──────────────────────────────┤ │CCVIEW │=YES; │Create a new view of this │ │ │ │object when the user selects │ │ │ │open, to provide concurrent │ │ │ │views. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │Switch focus to the open view │ │ │ │of this object when the user │ │ │ │selects open. │ ├────────────┼────────────────┼──────────────────────────────┤ │OPEN │=SETTINGS; │Open a settings view when │ │ │ │object is created. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=DEFAULT; │Open the default view when the│ │ │ │object is created. This can be│ │ │ │used to create and launch │ │ │ │WPProgram objects. │ └────────────┴────────────────┴──────────────────────────────┘ Figure 11. Keyname/Value Pairs for the WPObject Class ═══ Figure 12: WPFolder Keyname/Value pairs ═══ Figure 12. Keyname/Value Pairs for the WPFolder Class ┌────────────┬────────────────┬──────────────────────────────┐ │Keyname │Value │Description │ ├────────────┼────────────────┼──────────────────────────────┤ │OPEN │=ICON; │Open the icon view │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=TREE; │Open tree view │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=DETAILS; │Open details view │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONVIEW │=s1,[s2,...sn]; │Specify styles for icon view │ ├────────────┼────────────────┼──────────────────────────────┤ │TREEVIEW │=s1,[s2,...sn]; │Specify styles for tree view │ ├────────────┼────────────────┼──────────────────────────────┤ │DETAILSVIEW │=s1,[s2,...sn]; │Specify styles for details │ │ │ │view │ ├────────────┼────────────────┼──────────────────────────────┤ │*VIEW styles│=FLOWED │Display using regular columns │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NONFLOWED │Display using regular grid, │ │ │ │not flowed columns │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NONGRID │Display using no grid or │ │ │ │columns columns. Icons are │ │ │ │spaced irregularly. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NORMAL │Use normal-size icons │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=MINI │Use small icons │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=LINES │Lines in tree view │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NOLINES │No lines in tree view. │ ├────────────┼────────────────┼──────────────────────────────┤ │BACKGROUND │=filename; │Bitmap for folder background, │ │ │ │a filename in \OS2\BITMAP. │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONFONT │=size.name; │Font for icon names such as │ │ │ │10.Helvetica │ ├────────────┼────────────────┼──────────────────────────────┤ │TREEFONT │=size.name; │Font for tree icon names │ ├────────────┼────────────────┼──────────────────────────────┤ │DETAILSFONT │=size.name; │Font for Details view text │ │ │ │display │ ├────────────┼────────────────┼──────────────────────────────┤ │WORKAREA │=YES; │This folder is a workarea; if │ │ │ │is now open, it will be │ │ │ │reopened at the next boot. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │Folder is not a workarea. │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONVIEWPOS │=x1,y1,x2,y2; │Set the initial icon view │ │ │ │position and the size of this │ │ │ │folder on the desktop. │ │ │ │Coordinates are percentages of│ │ │ │offset of the whole screen │ │ │ │from the lower left hand │ │ │ │corner. x1 sets left side │ │ │ │position, x2 right, etc. │ ├────────────┼────────────────┼──────────────────────────────┤ │ICONPOS │=x1,y1; │Position this icon on the │ │ │ │desktop. │ └────────────┴────────────────┴──────────────────────────────┘ Figure 12. Keyname/Value Pairs for the WPFolder Class ═══ Figure 13: WPProgram Keyname/Value Pairs ═══ Figure 13. Keyname/Value Pairs for the WPProgram Class ┌────────────┬────────────────┬──────────────────────────────┐ │Keyname │Value (Note 1) │Description │ ├────────────┼────────────────┼──────────────────────────────┤ │ASSOCFILTER │=filterslist; │Sets the filename filter for │ │ │ │files associated with this │ │ │ │program. Multiple values are │ │ │ │separated by commas. │ ├────────────┼────────────────┼──────────────────────────────┤ │ASSOCTYPE │=typelist; │Sets the type of files │ │ │ │associated with this program. │ │ │ │Multiple values are separated │ │ │ │by commas. │ ├────────────┼────────────────┼──────────────────────────────┤ │EXENAME │=filespec; │Name of program file, or fully│ │ │ │qualified filespec. This may │ │ │ │be "*" for command processors │ │ │ │for OS/2, DOS, or WINOS2. │ │ │ │PROGTYPE is required when "*" │ │ │ │is used. │ ├────────────┼────────────────┼──────────────────────────────┤ │NOAUTOCLOSE │=YES; │Leaves the window open upon │ │ │ │program termination. │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=NO; │Closes the window upon program│ │ │ │termination. │ ├────────────┼────────────────┼──────────────────────────────┤ │PARAMETERS │=params; │Sets the parameters list, │ │ │ │which may include substitution│ │ │ │strings. The parameters are │ │ │ │included as the command line │ │ │ │passed to the target program. │ ├────────────┼────────────────┼──────────────────────────────┤ │PROGTYPE │=PM; │Presentation Manager session │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=FULLSCREEN; │OS/2 full-screen │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=WINDOWABLEVIO; │OS/2 window │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=VDM; │DOS full-screen │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=WINDOWEDVDM; │DOS window │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=WIN; │WINOS2 full-screen │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=WINDOWEDWIN; │WINOS2 window, common session │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=SEPARATEWIN; │WINOS2 window, separate │ │ │ │session │ ├────────────┼────────────────┼──────────────────────────────┤ │(OS/2 2.1) │=PROG_31_STD; │WINOS2 full screen, Win 3.1 │ │(See note) │ │standard mode │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=PROG_31_STD │WINOS2 window, separate VDM, │ │ │SEAMLESSVDM; │Win 3.1 standard mode │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=PROG_31_STD │WINOS2 window, common session,│ │ │SEAMLESSCOMMON; │Win 3.1 standard mode │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=PROG_31_ENH; │WINOS2 full screen, common │ │ │ │session, Win 3.1 enhanced mode│ ├────────────┼────────────────┼──────────────────────────────┤ │ │=PROG_31_ENH │WINOS2 window, separate VDM, │ │ │SEAMLESSVDM; │Win 3.1 enhanced mode │ ├────────────┼────────────────┼──────────────────────────────┤ │ │=PROG_31_ENH │WINOS2 window, common session,│ │ │SEAMLESSCOMMON; │Win 3.1 enhanced mode │ ├────────────┼────────────────┼──────────────────────────────┤ │SET (See │XXX=VVV; │Set environment variable XXX │ │note) │ │to a value. This is also used│ │ │ │to set DOS settings for DOS │ │ │ │and WINOS2 programs. │ ├────────────┼────────────────┼──────────────────────────────┤ │STARTUPDIR │=path; │Sets the working directory │ │(See note) │ │ │ └────────────┴────────────────┴──────────────────────────────┘ Figure 13. Keyname/Value Pairs for the WPProgram Class ═══ 2. Launching Mechanisms ═══ The OS/2 desktop provides a Graphical User Interface (GUI) way to launch applications. A user opens an application simply by double-clicking the mouse on an icon associated with an executable. (In this article, this method of launching applications is called icon selection.) What lies behind the desktop icon matters little to the user, who cares only that the application starts and runs correctly. In the Settings notebook for each program object of class WPProgram in the Workplace Shell, there is a Program tab page. On this page, the path and filespec entry-field value can be an executable file (with an .EXE extension) or batch file (.CMD or .BAT extension). The value for path and filespec may be just "*", denoting the default command processor for that type of session. The Settings notebook presents the object's definition as a number of pages with tabs. Each page contains a group of related parameters. The Settings notebook's Program page contains the path and filename of the program, any program parameters, and the directory to assign as the current directory. Internally, the path and filename string in a program object's Settings notebook is called an EXENAME setup string. Regardless of the EXENAME in the Settings notebook, the components of the launching mechanism can be tailored to present the same appearance to the user who does icon selection. Why tailor the launching mechanism? It is easier for everyone if the application designer sets up an icon on the desktop for the user to select, instead of telling the user to "Open a DOS command-prompt window by selecting ..." and then "Issue the command ...". If the application designer has done the packaging work well, then the user simply selects the icon, and the possibly complex processing mechanisms launch the application. The most common type of launching mechanism is the one in which the path and filename in the Settings notebook point to the executable that is launched. Let's call this a direct launch. In contrast, an indirect launch uses REXX programs and other methods. Later, this article shows how REXX can extend the functionality of a WPProgram object on the desktop. There is another way to start programs: invoke them from the command line in a DOS or OS/2 window. This article does not discuss the command-line method, except in situations where a command is issued as part of a launch mechanism that is based on icon selection. Whether the direct or indirect launch mechanism is used, the user who uses icon selection should see no functional difference in the way that the program is started. As long as the application starts in the same way, all methods of defining and launching the application are equivalent. This should satisfy the goal of most users, which is to define objects on the desktop in such a way that simple icon selection launches them and their processing appears similar. For example, opening folders or containers is clearly related to launching applications - the required association of data files with the executable has been defined, and the desktop user launches the application by selecting a data file, or by dragging-and-dropping a data file onto an application program's icon. ═══ 2.1. Direct Launch ═══ For objects of class WPProgram that have an EXENAME filename extension of .EXE, WPS starts the launch process by examining the type of executable - OS/2, DOS, or Windows. In addition, the session can be windowed, full-screen, or PM. Windows sessions, invoked through WINOS2, can also use different Windows run modes, either Standard or Enhanced 3.1. The launch process for an executable object consists of these general steps: o Start a process to control the executable o It sets up the executable environment o It loads the target executable o It passes control to the executable o Which runs within its execution environment o Which terminates after running o The control process cleans up the environment o The control process terminates These steps do not account for the technical details that differ for each type of executable environment, but rather they try to show the functions performed that are common to all types of executables. The steps outlined can be mapped onto several different operating systems, including IBM MVS for mainframe systems. The first and last steps above are accomplished by mechanisms in the operating system (OS), which is the overall control process for the computer system. The OS cleans up resources after the application control process terminates. The command processor that is the control process depends on which type of session is being started. You can start a Windows application from an OS/2 command prompt window or full-screen by issuing a command such as: winos2 appname where appname is the program name of the Windows application to be run when WINOS2 starts a Windows session. Figure 2 shows the default command processors used to control each type of session. ═══ 2.1.1. Program Parameters ═══ In the Settings notebook's Program tab page, the Parameters value for a WPProgram object can be set either to accept data input by the user in response to a prompt, or to accept data from a drag-and-drop operation in which a data file is dropped onto the icon of the WPProgram object. A Parameters value that has matched square brackets surrounding a prompt string will prompt the user for keyboard input. For example, if the string [Enter filespec] is in the Parameters entry field, the desktop displays a dialog box in which the prompt string appears, followed by a data-entry field into which the user types data. (Had the user instead launched a program from a command-line prompt, the user could also have supplied the data immediately after typing the program's name.) ═══ 2.1.2. Special Parameters ═══ Figure 3 shows some special string components that go into the Parameters entry field of the WPProgram object. These components are used to insert varying information (given in Figure 3) about the path, filename, and extension into the command line that invokes the target program. These string components are useful for drag-and-drop operations, because they provide the target program with values that have been prepared and parsed by the operating system. For example, consider this Parameters string: %* %**P %**N %**E This Parameters string, when used with a drag-and-drop operation, results in a command line that contains: o the fully qualified filespec (drive, path, filename, extension), from the %* string o the path with last backslash, from the %**P string o the filename with no extension, from the %**N string o the extension, from the %**E string This Parameters string makes the operating system do some of the work, breaking out the parts of a filespec before the application program looks at the command-line operands. Parsing a filespec can be complex when HPFS is used and the user constructs directory names or filenames that include spaces. A simple technique for handling HPFS names is to construct a Parameters string similar to the one shown above, along with additional special characters used as punctuation. Using such a Parameters string, the resulting command-line operands can be parsed successfully by REXX or by an application program. Here is an example of such a Parameters string: (%*) (%**P) (%**N) (%**E) Let's put this string into action. Consider what happens when a user drops a file named "A file name!.xtx" contained in a directory "A Dir Name" onto a program object that has the above Parameters string. The resulting command line contains: (c:\A Dir Name\A file name!.xtx) (c:\A Dir Name\) (A file name!) (xtx) An application program or REXX can parse this command line by using the punctuation added around the special strings. ═══ 2.2. Indirect Launch ═══ The indirect launch method can be described as using a "helper" mechanism to configure the execution environment before starting the target application. In cases where the target executable requires special handling or environment values that are not in effect for the OS/2 system as a whole, the required environment can be configured using .CMD files or REXX programs. The same is true for DOS applications, where a special .BAT file or AUTOEXEC.BAT that is tailored for the target DOS application can run first to configure its special environment. The indirect launch method using command files or REXX programs can run applications (programs, REXX programs, or command files) in either a sequential or parallel manner. If the batch file or REXX program running in an OS/2 session invokes the target program by specifying only its name on a command line, then the target application runs while the invoking batch file is blocked, awaiting termination of the target program. This is called sequential execution of the invoked application. If, however, the batch file invokes the target program using the START command, then the target program will run in parallel with the batch file. This important concept is covered later in the section "PMSW - PM Switch Desktop Focus". In OS/2 2.1, the DOS Settings notebook supports use of an AUTOEXEC.BAT file or another batch file in the DOS_AUTOEXEC session settings. Although the file can have any name, AUTOEXEC.BAT is used throughout this article. The indirect launch category includes the use of an AUTOEXEC.BAT file because a special AUTOEXEC.BAT is used to tailor the runtime environment. The command processor establishes the DOS session environment, and then launches either the batch file specified by DOS_AUTOEXEC or the default AUTOEXEC.BAT before launching the target DOS executable. The AUTOEXEC.BAT can also launch the target DOS application by invoking it as a command or via the CALL command to another .BAT file. In the case where AUTOEXEC.BAT invokes the target application, the Settings notebook's path and filename entry contains "*", meaning the DOS command processor. The AUTOEXEC.BAT file contains a command line that invokes the target application, and then the EXIT command for closing the command processor's window. Both the AUTOEXEC.BAT and the notebook's path and filename entry can invoke programs or batch files, which means that more than one process can be run, sequentially. Execution environment requirements for some applications can include: o Extending or changing the default PATH value o Changing the DPATH value (in OS/2 applications) o Running several command, REXX, or program files o Conditional execution of programs o Coordinated execution of applications The most sophisticated and powerful method of indirectly launching an application is to create a program object using System Object Model (SOM) methods, and to launch it during object creation by specifying OPEN=DEFAULT; in the WinCreateObject setup string. The current REXXUTIL function package in REXX provides the SysCreateObject function to create objects of all types for the desktop or for desktop folders. See the later section "Setup Strings for Programs" for details about the values in object setup strings. One of the advantages of creating an object for launching applications is that the object can be left visible on the desktop and can appear to be an ordinary application. The mechanisms used internally to launch and control the target application can be hidden from the user, who need not be concerned with those mechanisms (The internal mechanisms are discussed later in detail.) The object created for launching may also be hidden easily by using the location , which is the OBJECTID of the \NOWHERE folder, as shown in Figure 15. Figure 15 contains a REXX program that creates an object for immediate launch, and then hides that object by specifying the location . Note that you can also create any object as invisible by including the NOTVISIBLE=YES; string in the object's setup. See Figure 11 for details. When creating a program object to launch an application, the launch method can be either direct or indirect. An example of a REXX program that creates an object to launch an application is covered in the next section. Using REXX programs to create objects provides the ability to query the current operating system environment, attached LAN network resources, and so on. Some of the advantages in using REXX in this manner are: o Setup can be changed dynamically o Internal launch mechanisms can be changed o Objects can be hidden easily o Objects can start different types of sessions o Objects can be displayed on the desktop or in folders ═══ 2.2.1. Sample SysCreateObject Launch ═══ Figure 15 lists a REXX program for creating an invisible object and launching it upon creation. This program uses PMSW to switch focus to the session if it is already active. To make this object visible on the desktop, change the Location value in Figure 15 from to . The location also may be any folder for which you can identify the OBJECTID, or a path such as C:\DESKTOP. If you make the created object visible, then you don't need to run this REXX program to launch it. Instead, just select the icon (the visible object) to open an OS/2 command-prompt window, maximized. To open a new windowed command prompt each time you select an icon, change to CCVIEW=YES; in the setup. ═══ 2.2.2. Sample DOS Object Launch ═══ The REXX program in Figure 16 creates an object on the desktop that runs DOS QBASIC in a maximized DOS window. This REXX program creates a visible object that you can launch by icon selection. Using this approach, you can use the graphic mouse cursor to navigate within this DOS application. Once you run this REXX program, you don't need to run it again, although you can re-run it to recreate the object on the desktop if you previously dragged it to the shredder. You can use this REXX program to try new things, such as making the object undraggable. ═══ 2.3. Launch by Association ═══ An application can be defined to the OS/2 Workplace Shell by using the Settings notebook's Type and Association pages. These techniques require defining data in the Settings notebook for either the application program or for data files to be used with the program. When the association of data files with a program is done correctly, the user can invoke the target program to operate on a particular data file. To do this, the user selects the icon of the data file that is displayed in an open container view. There are three ways to set up a data-file object so that a program is started when the user selects the data file's icon. These methods require updates to the Settings notebook for either the application program or for individual data files. The updates can be done manually or by a program. These methods are: o Create a filename association in the application program's Settings notebook (as shown in Figure 4). o Create a type association in the data file's Settings notebook (Figure 5). o Make the program name the default setting in the "Open" cascade menu in the data file's Settings notebook (Figure 6). An association is a special link that can be assigned to a program object. This link allows the user to specify which program will be invoked when the user double-clicks on specified types of files, individual files, or files described by a global filename mask. ═══ 2.3.1. Filename Association in a Program ═══ Creating a filename association in a program's Settings notebook requires that parts of filenames remain constant, so that data files can be associated with the program. Most associations reserve a file's extension, although the part of a filename that must remain constant does not have to be its extension. This reservation of part of a filename is not very flexible, and associations can be destroyed accidentally by changing the data file's filename or extension. This method supports the use of HPFS long names. To create an association between a program and data files, open the Association page in the program object's Settings notebook. Enter the filename mask or filename extension in the New Name entry field, and select the Add pushbutton to define the association. The "?" and "*" characters can be used in the filename mask or in the extension. Figure 7 gives an example of setting an association based on part of a filename and also a file extension. A text editor may, for example, have associations for plain-text files (that is, a type of data file), the individual file CONFIG.SYS, and all files described with the global name READ*.*. Whenever a data-file object that meets these criteria is selected with a double-click, OS/2 starts the appropriate program object. The filename-association method is not very flexible. When a user using icon selection wants to use a different program with the data file, the existing association must be changed. This is usually too complicated for the average user, and it involves too much manual work to be efficient. ═══ 2.3.2. Type Association in a Data File ═══ Creating a type association in a data file's Settings notebook is a better approach. The advantage of this approach is that it is easy for a user to use a different program with the program object, simply by choosing a new type in the Settings view. The process for making a type association in a data file is simple: o Open the Settings view for the data-file object o Select the Type page o Select from the list of available types o Press the Add button o Close the Settings window Individual programs can be associated with a Type value, but support is limited, and usually only OS/2 programs support file-type association. Programs can also create new file types, and they can create the data-file associations during processing, to provide the GUI application launching for users. Type association in data files is described in more detail in Presentation Manager & Workplace Shell Application Development andWorkplace Shell Implementation in the references. ═══ 2.3.3. Adding a Default Program to a Data File's Menu ═══ Adding a default program to a data file's menu should be undertaken only by users who understand the workings of the Workplace Shell in some detail. Its main disadvantage is evident when many existing files must be set up to use a particular program: each one must be modified separately. If you are setting up a system for a new user, you can create a data file with a particular program identified as the default in "Open" in the context menu, then make that file a template so that all new files subsequently created from it will inherit this default attribute. To create new files from the template, drag the template with the mouse. Dropping the template creates the new instance of the data file, with all of its associations and context menu items intact. The PM and Workplace Shell Redbook contains detailed instructions for updating an object's context menu. This is the menu that you display when you click mouse button 2 (usually the button at the right) on the object's icon. You can add new menu actions, and you can define a new default action that is taken when you select the Open option in the menu. Figure 8 shows how to add a new menu item to the notebook menu page, and Figure 6 displays the pop-up menu that you see when you select Open, then Settings, to define the new default menu action. Note that, for folders such as the desktop, you can add program objects as menu items by following the procedure outlined below: 1. Open the settings notebook for a folder 2. Select the Menu tab 3. Drag-and-drop a program object onto the "Actions on Menu" entry box 4. Close the settings notebook You will now see the new menu action line on the folder's system menu. An easy way to get to an OS/2 command prompt window is to drag-and-drop the "OS/2 Window" icon from the "Command Prompts" folder onto the settings notebook Menu "Actions on Menu" entry field for the desktop. Now, when you open the desktop system menu, you can launch an OS/2 command prompt window by selecting that menu line, or by hitting the key defined as a hot key by the tilde prefix. ═══ Hot Key in Menu ═══ When you open the context menu for the desktop, you will see that menu items have underscores under some letters. Those letters are "hot keys" that can be pressed to select that menu action. You can add hot keys to menu actions that you add by following the procedure outlined below: 1. Open the context menu 2. Open the Settings notebook 3. Open the menu tab page 4. Highlight your added menu action in the "Actions on Menu" by one click of the primary mouse button (usually the left) 5. Open the settings for your menu action by clicking on the settings pushbutton 6. Insert a tilde (usually the key to the left of '1' (one) on the keyboard with the shift key pressed) immediately to the left of the character (letter, number or special character in the menu action name) you want to use as the hot key for your menu action. The letter you choose must be unique among the selections at that menu level. 7. Click on "OK" pushbutton to update the settings for your menu action. 8. Close the settings notebook. Now when you open the context menu, you'll see your added menu action with the character you've marked displayed with an underscore. You can select that menu action by pressing that key. Let's say you've added an OS/2 command prompt as a menu action. You could change the menu action name to "OS/~2" to use "2" as the hot key, or "OS~/2" to use the "/" as the hot key. The letters "O" and "S" are being used already by other menu actions. ═══ 3. Coordinating Applications ═══ The focus of this article thus far has been on methods of launching applications. It now switches focus to cover methods of coordinating processing among applications. The last part of the article covers methods of customizing the desktop. Gross Methods of Task Coordination A batch file running in a DOS session can invoke programs or other batch files sequentially only. A batch file or REXX program running in an OS/2 session can invoke other sessions either sequentially or in parallel, depending on the command used to launch the invoked sessions. If an OS/2 CALL command is used to invoke a program, the invoked program will execute while the OS/2 session that invoked it is blocked waiting for completion of the program. The abilities of the CALL method are limited, however, and the invoked program runs with the global default processing environment. It is often useful, and sometimes required, to use more powerful methods of invoking programs. These methods usually require use of the START command or other launch mechanisms. In turn, this introduces new problems of managing events among the tasks that are now running in parallel. You can design a REXX program or a batch command file to launch other tasks such as other REXX programs and to communicate in gross (rough) ways among the tasks. As an example, let's take a REXX program that starts other REXX programs, and then waits (by looping) until all the programs have completed before doing follow-on processing. We could use REXX queues, but instead, let's use the file system and existence of files as semaphores as a gross means of communicating information. The REXX control program sets up the runtime environment by deleting a fixed list of files from a fixed directory. Next, it issues the START command for several other REXX programs or DOS or OS/2 sessions. Then it waits for a while by using the SysSleep function in the REXXUTIL package. After it awakens, the REXX control program can use SysFileTree to build a list of filenames to see whether the started sessions have completed yet. As each of the started sessions begins, it creates a file, whose name is fixed, which indicates that the session is active now. As each session ends, it deletes the file it first created, then creates another file that indicates it has completed. The REXX control program looks for these files, and can thus tell when each session terminates normally. However, if one of the sessions terminates abnormally, that situation may not be apparent to the REXX control program. The above example is gross in its design, its interprocess communication, and its exploitation of system services. Proper use of REXX features can make this simple example much finer. If you want to create a task environment in which parallel processes communicate quicker and more cleanly, you can use REXX queues and named-pipe support. Using the operating system's file services, the LAN network namespace features, or a mainframe system catalog to provide gross semaphores by simple existence of files or other objects is a concept that is so general that it can be used over a wide variety of operating systems. The generalization is called the Loosely Interconnected Networked Data Applications (LINDA) concept. In LINDA systems, each application periodically looks within a namespace for objects that it will work with, and each application places objects into a namespace. Other applications periodically do similar operations, and the applications thus communicate data among themselves in a loose network with no direct communication. We use this namespace concept daily when we look up someone in the phone book - a common namespace for people in a locality - or call directory assistance to retrieve information from that namespace. Detailed information with sample REXX programs is given in the section "PMSW Function & Command Line Syntax". ═══ 3.1. PMSW - PM SWitch Desktop Focus ═══ The PMSW program, used in REXX programs to communicate the existence of active tasks by name, can be thought of as a type of LINDA application. The task that was launched by icon selection or by START command is listed in the desktop's Window List. PMSW is told to look in that list for a particular name, and it then either switches desktop focus to that task or it returns a code indicating whether the task is or is not active. This PMSW.EXE program or its REXX external function (PMSW2.DLL) can be used in batch files or REXX programs that launch a target application in parallel execution mode. To do this, the REXX program that uses PMSW.EXE or PMSW2.DLL should either use the START command or launch a program object by creating or updating it with the OPEN=DEFAULT; setup string. In this article, only REXX programs are discussed, because only REXX has the needed functionality to exploit the PMSW program. When a batch file or REXX program issues a START command , the START command starts another session that runs in parallel with the batch file or REXX program that issued the START. The launching REXX program continues to run, and can do other processing after having launched the parallel process. The launched session appears in the desktop's Window List when it becomes active and can receive the focus. PMSW gives a REXX program the ability to launch a session and then switch active focus to that launched session, regardless of the current focus, and regardless of whether the launching REXX program is in the foreground or background. PMSW can be invoked from batch files or REXX programs running in foreground, background, and minimized sessions, or in sessions launched by the START command . PMSW can be invoked via the DETACH command to switch desktop focus to another task even though it is a PM application. A process started by DETACH cannot acquire the focus due to its lack of PM resources, since, by definition, DETACH starts a process that does not use keyboard or screen resources. PMSW provides the mechanism by which a "parent" REXX program can track the independent "child" process through the presence or absence of the child's task name in the desktop's Window List. To be able to do this, the REXX program must know, in advance, the name of the child process. A name can be given to the child task by using the START command . The started session can be named by coding the optional first operand within double-quotes. PM programs started in this way may change their Window-List names by making an appropriate API function call. Using PMSW, a REXX program can check to see if a given task is active in the Window List and, if so, the program will wait by using the REXX SysSleep function, then check again after SysSleep. The watching REXX program can then delay further processing until the watched task terminates, or do other processing in parallel while the watched task is still active. A REXX program that uses PMSW to watch active tasks can do a list of tasks sequentially by starting a task, watching it until it completes, and then start the next task in a list. Similarly, a REXX program that uses PMSW can launch a number of tasks in parallel, watch for the last one to complete, and then do something else, such as cleaning up anything left by any of the tasks. ═══ 4. Desktop Customization ═══ The previous sections provide the framework for launching applications and for coordinating tasks that are launched. Those preceding topics have laid the foundation for understanding all the different methods of desktop customization. The following sections deal with desktop customization techniques and assume that you are now familiar with methods of launching applications and of coordinating tasks. The standard OS/2 2.1 installation processing creates an initial desktop during the last step of the installation process, when the system is booted. A starter set of desktop folders and icons is constructed by the Workplace Shell during the first boot process. The user sees these standard objects, as well as the OS/2 Tutorial, which is presented automatically. Users want icons on their desktop for the applications that they use the most. They can manipulate the desktop using the mouse to drag-and-drop, create shadows, etc. If a company wants to distribute OS/2 2.1 and to create objects on the desktop or in folders for all users, it is usually convenient to do so during installation of OS/2 2.1. The objects that a company creates during customization can either augment or replace the standard objects. Indeed, this is a topic of interest across the industry - how to mass-produce a desktop that has a set of applications already defined for users without going to a lot of trouble. There are several ways to do this: o Use REXX SysCreateObject o Change the contents of the file \OS2\INSTALL\DATABASE.DAT o Use MAKEINI to update the base OS2.INI file, the user file that contains definitions of objects. Each of these ways is discussed in sections that follow, with some recommendations as to when each method would be best. This article does not address issues of OS/2 installation such as changes to the CID response file to select OS/2 components or alter the installation process. ═══ 4.1. Saving the Desktop Customization ═══ Another hot topic for all users is how to save the desktop in anticipation of the day when the OS2.INI file gets destroyed. Users can press keys Alt+F1 at boot time to cause OS/2 to copy the files from \OS2\INSTALL to the \OS2 directory and to the root directory. These files are CONFIG.SYS, OS2.INI, and OS2SYS.INI. If you don't want to use the Alt+F1 restore process, you can also boot from the installation disks, or from bootable OS/2 diskettes, to manually create backups of the critical files. One method of creating a backup copy of the critical files that can be restored easily is to include RUN commands in the CONFIG.SYS file. These RUN commands copy the OS2.INI and OS2SYS.INI files, and CONFIG.SYS itself, to the \OS2\INSTALL directory. Figure 9 illustrates this concept. In Figure 9, the boot drive is assumed to be C:. This simple copying may cause problems. If an error exists in the CONFIG.SYS file that causes failure of the Workplace Shell, the RUN command processing has already copied the bad CONFIG.SYS file into the backup directory, so you won't be able to recover using Alt+F1. A better way would be to copy the files during boot to another directory, say \OS2\BACKUP, and then periodically to manually copy the critical files from \OS2\BACKUP to \OS2\INSTALL. This staging of the backup files avoids overlaying the files in the \OS2\INSTALL directory each time you boot. If you have sufficient hard-disk space, you can copy the critical files to the \OS2\BACKUP directory and then run a batch file from STARTUP.CMD to do the following process: 1. Erase file xxx.003 2. Rename file xxx.002 to xxx.003 3. Rename file xxx.001 to xxx.002 4. Rename file CONFIG.SYS to CONFIG.001 5. Rename file OS2.INI to OS2.001 6. Rename file OS2SYS.INI to OS2SYS.001 This process can be modified further to automate the copy of files to \OS2\INSTALL by copying the xxx.003 version (or whatever is highest, oldest-numbered version) to the \OS2\INSTALL directory with renaming: 7. COPY \OS2\BACKUP\CONFIG.003 \OS2\INSTALL\CONFIG.SYS 8. COPY \OS2\BACKUP\OS2.003 \OS2\INSTALL\OS2.INI 9. COPY \OS2\BACKUP\OS2SYS.003 \OS2\INSTALL\OS2SYS.INI This modification "buffers" the overlaying of the files that would be restored using Alt+F1 processing during boot. ═══ 4.2. Using REXX SysCreateObject ═══ Using REXX with SysCreateObject calls to define folders and program objects to produce desktop customization is a generally useful, easy process. This method consists of using REXX programs that call the SysCreateObject function to update the OS2.INI file. This method has only one prerequisite, the build of the initial desktop. It cannot be used prior to the build of the initial desktop; it is a post-installation method only. A REXX program that installs objects on the desktop can also create the required application directory and file structure. The REXX program can include code that lets the user choose the drive and path for installation of the application; or, the target can be selected automatically based on available disk space; or, the target can be constant. An alternative is to use a separate installation process, such as CID or NVDM/2, to install the directory structure and files, and then to define the desktop objects using REXX. See the section "SysCreateObject REXX Function" for the syntax and examples of this function. In the call to the function, you include the type of object, displayed title, location name, object setup string, and update or replace option. For desktop customization, most of the objects are folders of class WPFolder, or application programs of class WPProgram. Among the object setup-string values, you should include a specific, unique OBJECTID value so that you can refer to the object in other REXX programs. By giving a folder an OBJECTID name, you can open that folder automatically in a REXX program. OBJECTIDs can be used successfully to create and update objects only if the objects are not duplicated by using Workplace Shell functions. Consider the situation where you have created a folder with an OBJECTID, and program objects within that folder, with each program object having its own unique OBJECTID. Then, what happens when you COPY the folder? The program objects within the duplicate folder no longer have OBJECTIDs to which REXX programs can refer. Designers of desktop customization must be aware that the internal object "handle", assigned by the Workplace Shell when the object is created, is the only fixed, unique object identifier. Since a REXX program can refer to objects only by OBJECTID or by a fully qualified path and filename, the changing of an OBJECTID by WPS processing represents a limitation on the ability of REXX programs to handle objects. ═══ 4.3. Changing \OS2\INSTALL\DATABASE.DAT ═══ This method uses the MIGRATE.EXE application migration program in OS/2 to tailor the desktop during initial installation or at any later time when the user wants to manually run MIGRATE. This method updates the OS2.INI file after it asks the user to select the programs to include in the migration process. The disadvantages of this method include the following: o The need to edit \OS2\INSTALL\DATABASE.TXT o Possible need to edit \OS2\INSTALL\DBTAGS.DAT o Much hands-on dialog work with MIGRATE.EXE The prerequisite for this method is the existence of the directory and file structure required by the application. You must have already created the directories and files by using a command file or REXX program, or else the directories and files must be addressable on LAN resources. This method starts with examining the DATABASE.TXT file to see if it already contains the target application. If not, then you must copy an existing entry as a template for your new application. Unless a new application defines new session parameters in its Settings notebook, there is no need to edit the DBTAGS.DAT file. In fact, the file contains a warning not to edit it. In most cases, editing this file has little effect unless the associated CONFIG.SYS driver files have already been loaded; these driver files contain the required resource names for the settings parameters that will be added. After you have edited the DATABASE.TXT file, you must update the DATABASE.DAT file (which is used by MIGRATE.EXE) by running PARSEDB.EXE in the \OS2\INSTALL directory. After that, you must run MIGRATE.EXE to migrate any applications you want to install as Windows, DOS, or OS/2 applications. Running MIGRATE.EXE is an interactive process. The program identifies applications as candidates for migration by finding matches for the program names in the DATABASE.DAT file. It then presents you with a list of these applications, and you can select which ones to migrate from the list displayed. The visible result of the migration process is one or two folders on the desktop containing program objects for OS/2 and Windows applications. Because of the involved processing required, and because of the manual operations required, this approach to customization is not the easiest. From the viewpoint of the system administrator, it also presents problems in controlling the overall process. ═══ 4.4. Using MAKEINI to Update the Base OS2.INI File ═══ This method uses MAKEINI.EXE to update the OS2.INI file. In addition to creating new objects on the desktop, you can change system settings, such as date and time formats, to conform with local installation standards. This method of desktop customization can be done at both initial installation time and at any time thereafter. Prior to the first boot of the new OS/2 system, you can change the initial desktop by editing the INI.RC file, which is used to create the initial desktop. (For some examples of editing the .RC file to change objects or to add objects during installation, see the section "Setup Strings in the .RC File".) After the first desktop is constructed, you can change the desktop by running MAKEINI.EXE with a USERNAME.RC file. This merges the object definitions in the USERNAME.RC file with the existing OS2.INI file. There are sample .RC files in the \OS2 directory. Their format and content are described later in the next section, "OS/2 .RC File Format". Distributing customized desktops during initial installation of OS/2 2.1 is easier than adding customization afterward using MAKEINI.EXE. Doing CID, LCU, or NVDM/2 remote installation of OS/2 2.1, you can use a user exit, which is invoked prior to the first boot, to insert new desktop objects into the INI.RC file or to delete unwanted lines. When installing OS/2 2.1 using CID, LCU, or NVDM/2, you can simplify the updates to INI.RC by extracting INI.RC from the CID directory structure. Go to the \CID\IMG\OS2V21\DISK_9\REQUIRED bundle file, use the UNPACK program to extract the INI.RC file, edit INI.RC to add your desired customization, and then repack the updated INI.RC into the original bundle. Details of this procedure are addressed in the NVDM/2 product documentation. Using MAKEINI and a USERNAME.RC file after the first boot is more difficult. The steps outlined below are one method: 1. Boot using OS/2 installation diskettes or bootable OS/2 diskettes. 2. Copy the OS2.INI file from the \OS2 directory to another directory for backup and recovery use. 3. Run MAKEINI, specifying your USERNAME.RC file as the first operand and \OS2\OS2.INI as the second. 4. Reboot OS/2 from the hard disk. MAKEINI merges the results of the .RC file processing with the OS2.INI file. The next boot of the system then completes the creation of objects as specified in the USERNAME.RC file. Recovery from errors requires rebooting using diskettes and copying the backup copy of OS2.INI back to the \OS2 directory. Refer to the Presentation Manager Reference for information about API calls that affect the system and user profile files (usually, OS2SYS.INI and OS2.INI). MAKEINI is documented in the OS/2 2.1 Command Reference. ═══ 4.5. OS/2 .RC File Format ═══ Customizing the desktop using MAKEINI involves creating or changing a resource file such as the INI.RC file that creates the stock desktop. To make changes correctly to an .RC file, you need to understand the overall format of the .RC file, and how its individual entries are constructed. You can invoke the MAKEINI program manually (by running it at a command prompt), or you can code a program. Using a program with the appropriate API calls, you can: 1. Create a copy of the currently active OS2.INI file. 2. Invoke MAKEINI to merge the new file-object data in USERNAME.RC with the copy. 3. Call the PrfReset API to change the name of the active user profile file from OS2.INI to another name. This technique requires PM programming expertise. You can do similar processing by using a command prompt and issuing the commands yourself. The steps listed below assume you have included the commands to copy the .INI files at boot time to the \OS2\BACKUP directory. 1. COPY \OS2\INSTALL\OS2.INI \OS2\BACKUP\OS2.BAK 2. COPY \OS2\BACKUP\OS2.INI \OS2\BACKUP\UPDATE.INI 3. MAKEINI \OS2\BACKUP\USERNAME.RC \OS2\BACKUP\UPDATE.INI 4. COPY \OS2\BACKUP\UPDATE.INI \OS2\INSTALL\OS2.INI 5. reboot using Alt+F1 to activate the updated OS2.INI If you want to restore the last active OS2.INI file, reboot using the installation diskettes, then copy the backup copy from \OS2\BACKUP\OS2.BAK to \OS2\OS2.INI and reboot normally. When MAKEINI is run, it creates application names, keywords, and values in the target output .INI file. The entries created by MAKEINI are known as STRINGTABLE entries. When WPS initializes at the next system boot, it finds these STRINGTABLE entries of names and values, and completes the process of creating new objects by deleting the STRINGTABLE entries that were placed in the .INI file by MAKEINI. In editing the INI.RC file used to create the initial desktop, avoid changing the required parts of the file. All .RC files must begin with the CODEPAGE and STRINGTABLE statements. The list of blank values should remain as-is. To change the default values for system parameters such as PM_National iDate format, change the numeric value to correspond to the desired date format. The STRINGTABLE entries have the general format of: Application name, such as PM_ControlPanel Keyname, such as BorderWidth Value, such as 4 This particular entry would appear as: "PM_ControlPanel" "BorderWidth" "4" Adding new objects involves adding new STRINGTABLE lines with PM_InstallObject as the application name, and a keyname string that consists of the following parts separated by semi-colons: Title of object WPS class of object Location of object The title of the object is what appears on the desktop under the icon for the object. The class of object is one of the WPS classes such as WPFolder or WPProgram. Objects are created in the order in which the entries appear in the .RC file, so folders must be created before creating objects that go in those folders. The last part of each STRINGTABLE entry is the object setup string containing keywords that describe the object, such as EXENAME, PROGTYPE, OBJECTID, and so on. Object setup strings contained in STRINGTABLE entries that refer to paths for files or programs, and that contain a question mark in place of the boot-drive letter, will have the question mark replaced by WPS when it creates a new object. This means that a REXX program that creates STRINGTABLE entries for export to other systems can specify the boot drive for the target system as "?". This is one method of creating an absolute path, but only for objects on the boot drive. Here is an example of part of an object setup string: EXENAME=?:\MYAPPL\MYAPPL.EXE;STARTUPDIR=?:\MYAPPL; See the Presentation Manager Reference, in the topic "WorkPlace Object Class Hierarchy", for details about the keyword value pairs appropriate for WPFolder and WPProgram object classes. Some of these details are included in the sections "Setup Strings for Folders" and "Setup Strings for Programs". Figure 10 lists four entries that you can add to your .RC file to create a Novell NetWare folder on the desktop and to define OS/2 NetWare Requester programs in that folder. The folder's icon will be placed on the desktop 25 percent across and 87 percent up from the lower left corner of the desktop. Note that each entry in Figure 10 should be a single line in the .RC file. ═══ 4.6. REXX Program for MAKEINI Function ═══ The MAKEINI program is not the only way to alter the user or system .INI file for the purpose of creating objects. You can also update the current .INI file using a REXX program similar to the one in Figure 17. Note that this REXX program adds the new STRINGTABLE entry to the current OS2.INI file using the REXXUTIL SysIni function. This is a much easier way to accomplish the MAKEINI function than running the MAKEINI program itself. Using such a REXX program to create an object illustrates what MAKEINI does when it processes the .RC file STRINGTABLE entries. The next boot of WPS will process the new string entries in the .INI file to create the new objects. Figure 18 lists an example of locating the boot drive for OS/2 systems. ═══ 4.7. Setup Strings in the .RC File ═══ Whether MAKEINI or REXX is used to update the .INI file with STRINGTABLE entries, or whether REXX SysCreateObject function calls are made to create objects directly, all of these methods require knowledge and proper use of the object setup strings processed by WPS. To make the Tutorial not come up after installation or MAKEINI, remove the line shown below from INI.RC. This line is an example of a STRINGTABLE entry; it consists of three strings, delimited by double-quotes, that appear in one line in the .RC file. "PM_Workplace:InstallAutorun" "OS/2 Tutorial" "EXENAME=TUTORIAL.EXE,STARTUPDIR=\OS2\HELP" To make the Drive A: object not come up after installation or MAKEINI, remove the following line from INI.RC: "PM_Workplace:InstallDiskOnDesktop" "A" "ICONPOS=80 8" To change the desktop directory to something other than Desktop (for example, to 'My Desktop'), replace the Desktop entry in the following line with 'My Desktop': (Before) "PM_InstallObject" "Desktop;WPDesktop;?:\" "OBJECTID=" (After) "PM_InstallObject" "My Desktop;WPDesktop;?:\" "OBJECTID=" This line in INI.RC creates a directory called 'My Desktop' on the boot drive. Note that the space in the title of the folder will be replaced with an underscore if the file system for the desktop drive is FAT (File Allocation Table) instead of HPFS (High Performance File System). The process that creates Workplace Shell objects handles special characters and long names for FAT systems by truncating long names and substituting special characters. Consider the case of creating one folder with the title "My Applications for Work" and another folder whose title is "My Applications for Home". Each folder is represented by a directory name that follows the naming convention of the FAT file system. WPS creates a physical directory named \MY_APPLI for the former folder, and one named \MY_APPL1 for the latter. The title for each folder is the full name. On the other hand, with an HPFS file system in use, the physical names for the directories are the same as the folder titles. Note that this method is not good for installations of standardized desktops, and it may confuse users who expect to see \DESKTOP as the desktop folder. However, this method provides a good example and explanation of how the desktop is defined internally, and technical support staff should be aware of it in case they encounter it in dealing with adventurous users. To create a folder called 'My Folder' on the desktop, add the following one-line entry to the .RC file: "PM_InstallObject" "My Folder;WPFolder;" "BACKGROUND=?\OS2\BITMAP\LIGHTHOU.VGA;OPEN=DEFAULT;ICONRESOURCE=61 PMWP;ICONPOS=8 70;ICONVIEWPOS=18 60 75 22;OBJECTID=" This line creates a folder called 'My Folder' on the desktop. The class of this folder is WPFolder. The location of the folder is the desktop, which has an OBJECTID=. The background of the folder will have a lighthouse bitmap. The icon will look like the OS/2 System icon. When you include OBJECTID in the object setup string in the .RC file, that parameter must be the last one in the setup string. To add an application to 'My Folder', insert the following information all on one line: "PM_InstallObject" "OS/2 Window;WPProgram;" "EXENAME=?\OS2\CMD.EXE; PROGTYPE=WINDOWABLEVIO;HELPPANEL=8010;OBJECTID=" To add a shadow of Solitaire to 'My Folder': "PM_InstallObject" "Solitaire Shadow;WPShadow;;" "SHADOWID=;OBJECTID=" To add a shadow of an OS/2 window to the desktop: "PM_InstallObject" "OS/2 Window Shadow;WPShadow;;" "SHADOWID=;OBJECTID=" Documentation about the setup strings is contained in the Presentation Manager Reference. ═══ 5. SysCreateObject REXX Function ═══ To introduce this topic, the text about SysCreateObject from the REXX Reference is reprinted here. The syntax of the SysCreateObject function is: result=SysCreateObject(classname,title,location<,setup> <,option>) where classname is the name of the object class. title is the object's title. location is the object's location, which can be specified as either an object ID (for example, ) or a file system path (for example, C:\BIN\MYTOOLS). setup is a WinCreateObject setup string. option is the action taken if the object already exists. Allowed options are: "fail", "replace" (delete existing object and create new object), and "update" (update the settings of the existing object). Only the first letter of the option is needed; all others are ignored. result is the return code from WinCreateObject. The return code is 1 (true) if the object was created, and 0 (false) if the object was not created. When creating objects, you must create the containing object before attempting to create objects within the container. Make the folder first, then create the objects to store in the folder. Figure 19 lists an example of a program that creates a folder on the desktop and then creates a program object in that folder. ═══ 6. PMSW Function & Command Line Syntax ═══ The PMSW public-domain REXX function interface is available on CompuServe in the IBM OS/2 forums as PMSW.ZIP. The information in this section was extracted from the full PMSW.INF file contained in the PMSW.ZIP distributed version. That file also contains details about technical design, as well as the full C-language source for the PMSW application. The PMSW application comes in two executable forms when uncompressed: o PMSW.EXE, an OS/2 PM program o PMSW2.DLL, a REXX external function PMSW is invoked with two arguments: PMSW name_mask_string [/r] where name_mask_string is the name mask for the task name in the desktop Window List /r is an optional switch for suppressing the actual change of focus. If the string passed as the first argument matches a name in the Workplace Shell's Window List, then that named task is given the focus by calling the WinSwitchToProgram API function. The name mask may contain wildcard characters, the asterisk and question mark, which have their usual DOS command line meanings - the asterisk matches zero or more characters, while the question mark matches exactly one character. For example, the mask *ABC* matches a name containing the letters ABC, whereas the mask *A*B*C* matches a name containing the letters A, B, and C, but not necessarily next to each other. ═══ 6.1. PMSW Sample Application ═══ The PMSW application is used in OS/2 .CMD files that are batch command files or REXX programs. A .CMD file can invoke PMSW to test whether a named task is already active and to switch focus to that task, or it can launch a task and change focus to that task once the task is available. A REXX program can contain logic such that, if the target DOS application is already active when the REXX program begins, the DOS application receives the focus instead of the REXX program starting another DOS application window. LAN administrators who have LAN-resident applications of all types can use REXX programs to facilitate access to these applications. A REXX program can examine the current LAN environment, check to see if the resources required for a particular application are now connected, and acquire resources automatically if needed. This can be done for all types of applications. For example, say that at a customer site the cc:Mail application resides on the LAN. A Mail program folder can be defined on the desktop, and it can invoke the REXX program MAIL.CMD. This program tests to see whether the target cc:Mail application is now active, and switches focus to it if so. If the cc:Mail application is not active, then MAIL.CMD checks to see if the user is now logged onto the LAN (because a LOGON command has been done), and whether the cc:Mail LAN drive has been connected, before issuing a START command . for cc:Mail and switching focus to it. Figure 19 lists the MAIL.CMD program. Figure 20 lists the program that uses the PMSW2.DLL external REXX function instead of the PMSW.EXE program. Figure 21 lists the DOS batch file used as the indirect launching mechanism for the DOS application. ═══ 7. Object Setup Strings ═══ The following sections describe setup strings for the different types of objects on the desktop. Note that there are parameters within the setup strings that pertain to all objects, to folders, or to program objects. For objects, the System Object Model (SOM) class definition file is the file WPOBJECT.SC. The class hierarchy for the WPObject class is: SOMObject WPObject The classes for folders and programs are derived from the WPObject class. Figure 11 shows the keyname/value pairs for the WPObject class. ═══ 7.1. Setup Strings for Folders ═══ For folders, the System Object Model (SOM) class definition file is the file WPFOLDER.SC. The class hierarchy for the WPFolder class is: SOMObject WPObject WPFileSystem WPFolder Users can create folders by dragging a folder template from the Templates container onto the desktop or onto another folder, and then responding to the system prompts for title, etc. Users can also create folders using REXX SysCreateObject calls. The object setup-string values that can be used for folders are listed in Figure 12, which shows the keyname/value pairs added by the WPFolder class. See the section "Object Setup Strings" for object settings common to both WPFolder and WPProgram. ═══ 7.2. Setup Strings for Programs ═══ For programs, the System Object Model (SOM) class definition file is the file WPPGM.SC. The class hierarchy for the WPProgram class is: SOMObject WPObject WPAbstract WPProgram Figure 13 shows the keyname/value pairs added by the WPProgram class. The WPProgram class is the program-object class. It provides an object that points at executable programs, and allows the user to run that program by simply double-clicking on the program object. The program can also contain a variety of useful additional parameters, such as the environment for the program and the parameters that are passed to it. An instance of this class can be created as a Workplace object, and is created initially by the system in its template form. It has the title Program and resides in the Templates folder. Other instances of this class that are initially created by the system include: o DOS Full-Screen in the Command Prompts folder o DOS Window in the Command Prompts folder o OS/2 Full-Screen in the Command Prompts folder o OS/2 Window in the Command Prompts folder o Every object in the Games folder o Some objects in the Information folder o Every object in the Productivity folder See the section "Object Setup Strings" for object settings common to both WPFolder and WPProgram. ═══ 8. Sample REXX Programs ═══ This section lists all the REXX programs mentioned in this article: o REXX Sample: Load REXXUTIL (Figure 14) o REXX Sample: Hidden Object (Figure 15) o REXX Sample: DOS Desktop Object (Figure 16) o REXX Sample: MAKEINI Function (Figure 17) o REXX Sample: Get Boot Drive (Figure 18) o REXX Sample: SysCreateObject (Figure 19) o REXX Sample: MAIL.CMD for PMSW Program Call (Figure 20) o REXX Sample: MAIL.CMD for PMSW2 REXX Function (Figure 21) o DOS Sample: CCMAIL.BAT DOS Batch File (Figure 22) Figure 14 shows how to load the REXXUTIL function package that is used by all the sample programs. Once the REXXUTIL.DLL has been loaded, it remains available for other REXX programs until it is unloaded. Loading REXXUTIL.DLL is a prerequisite for all the other sample programs. One method of ensuring that REXXUTIL.DLL is loaded is to create a shadow object in the Startup folder of the REXXLOAD.CMD program, so that the DLL is loaded. Including code in each REXX program to check if the DLL has already been loaded adds a little overhead and avoids errors. In distributing REXX programs, you should include explicit code to test for and load REXXUTIL.DLL, because other users may not have the same initial environment. ═══ Figure 14: REXX Sample: Load REXXUTIL ═══ /* REXX program */ /* ============================================================== Check to see if all REXX utility functions have been loaded, and load the functions if needed. This needs to be done only once, because the functions remain loaded and accessible. NOTE: RxFuncQuery tests for REXX load. ============================================================== */ if 0 < RxFuncQuery('SysLoadFuncs') THEN DO; Call rxfuncadd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs'; Call SysLoadFuncs; END; /* Figure 14. REXX Sample: Load REXXUTIL */ ═══ Figure 15: REXX Sample: Hidden Object ═══ /* REXX program */ TESTSTR='"*OS/2 CMD*"' '@PMSW' TESTSTR '/r' if RC = 1 then do '@PMSW' TESTSTR;'@EXIT'; end; ClassName='WPProgram'; Location=''; BaseSetup='EXENAME=*;PROGTYPE=WINDOWABLEVIO;'||, 'MAXIMIZED=YES;CCVIEW=NO;OPEN=DEFAULT;' StartUpDir='C:\'; ObjName='OS2_Cmd'; Title='OS/2 Cmd'; Call BldObject; '@PMSW' TESTSTR EXIT; /* Leave the program here */ BldObject: /* procedure to build object */ SetupString=BaseSetup||StartUpDir||'OBJECTID=<'ObjName'>;' Call SysCreateObject ClassName, Title, Location, SetupString, 'UPDATE'; return; /* Figure 15. REXX Sample: Hidden Object */ ═══ Figure 16: DOS Desktop Object ═══ /* REXX */ ClassName='WPProgram'; Location=''; BaseSetup='EXENAME=\OS2\MDOS\qbasic.exe;PROGTYPE=DOS;'||, 'MAXIMIZED=YES;CCVIEW=NO;OPEN=DEFAULT;' StartUpDir='\OS2\mdos'; ObjName='DOS_Basic'; Title='QBASIC'; Call BldObject; EXIT; /* Leave the program here */ BldObject: /* procedure to build object */ SetupString=BaseSetup||StartUpDir||'OBJECTID=<'ObjName'>;' Call SysCreateObject ClassName, Title, Location, SetupString, 'UPDATE'; return; /* Figure 16. REXX Sample: DOS Desktop Object */ ═══ Figure 17: MAKEINI Function ═══ /* REXX program */ /* assumes REXXUTIL is loaded */ Call SysIni "USER",, "PM_InstallObject",, "New Object;WPProgram;",, "EXENAME=C:\RESULTS.CMD;PROGTYPE=WINDOWABLEVIO;"||, "OPEN=DEFAULT;MAXIMIZED=YES;" /* Figure 17. REXX Sample: MAKEINI Function */ ═══ Figure 18: Get Boot Drive ═══ /* REXX program to find the boot drive of the OS/2 system */ /* Assumes REXXUTIL is loaded */ irc=SysIni('BOTH','FolderWorkareaRunningObjects','ALL:','Objects'); BootDrive=left(Objects.1,2); say 'Boot drive is' BootDrive return; /* Figure 18. REXX Sample: Get Boot Drive */ ═══ Figure 19: REXX Sample: SysCreateObject ═══ /* Code */ If SysCreateObject("WPFolder","Mail Folder","") Say 'Mail Folder successfully created' /* Create a folder object, and then create a program object in that */ /* folder */ If SysCreateObject("WPFolder", "MyFolder", "C:\",, "OBJECTID=") Then Do If SysCreateObject("WPProgram", "MyProgram", "",, "EXENAME=C:\TOOLS\MYPRG.EXE") Then Say 'Folder "MyFolder" and Program "MyProgram" have been created' Else Say 'Could not create program "MyProgram"' End Else Say 'Could not create folder "MyFolder"' /* Figure 19. REXX Sample: SysCreateObject */ ═══ Figure 20: REXX Sample: MAIL.CMD with PMSW ═══ /* REXX MAIL.CMD uses PMSW.EXE program calls */ 'SETLOCAL' 'C:' 'CD \CCMAIL' if 0 < RxFuncQuery('SysLoadFuncs') THEN DO; Call rxfuncadd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs'; Call SysLoadFuncs; END; CCMAIL='CCMAIL'; FirstName=""; LastName=""; ProcOpts=""; UserPassWord=""; parse upper arg FirstName LastName UserPassWord; CCMAILServer='ccmail'; MDRIVE.0=0; RC.0='FOCUS:'; RC.1='READY:'; RC.2='ERROR:'; irc=SysFileTree('M:\CCMAIL\MAIL.*','MDRIVE','FSO'); if MDRIVE.0<1 then do; '@NET USE M: ' CCMAILServer; RRC=RC; end; else do; RRC=0; end; IF RRC=0 THEN DO; bREADY=0; 'PMSW' ccmail '/R'; Result=RC.RC if Result\='READY:' then do; 'START "CCMAIL" /C /MIN /WIN c:\CCMAIL\CCMAIL.BAT' } one FirstName LastName UserPassword; } line end; else do; 'PMSW' ccmail; Result=RC.RC; if Result='FOCUS:' then bREADY=1; end; do while (bREADY<1); 'PMSW' ccmail '/R' Result=RC.RC; if Result='READY:' then do; 'PMSW' ccmail Result=RC.RC; if Result='FOCUS:' then do; bREADY=1; end; end; else Call SysSleep(2); end; END; else do; if RRC=2 then do; 'net use m: /d'; end; say "UNABLE TO ACCESS CCMAIL" end; byby:; '@EXIT'; /* Figure 20. REXX Sample: MAIL.CMD for PMSW Program Call */ ═══ Figure 21 ═══ /* REXX MAIL.CMD */ 'SETLOCAL' 'C:' 'CD \CCMAIL' if 0 < RxFuncQuery('SysLoadFuncs') THEN DO; Call rxfuncadd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs'; Call SysLoadFuncs; END; CCMAIL='CCMAIL'; RC=RXFUNCADD('PMSW2','PMSW2','PMSW2'); FirstName=""; LastName=""; ProcOpts=""; UserPassWord=""; parse upper arg FirstName LastName UserPassWord; CCMAILServer='ccmail'; MDRIVE.0=0; irc=SysFileTree('M:\CCMAIL\MAIL.*','MDRIVE','FSO'); if MDRIVE.0<1 then do; '@NET USE M: ' CCMAILServer; RRC=RC; end; else do; RRC=0; end; IF RRC=0 THEN DO; bREADY=0; Result=PMSW2(ccmail,'/r'); if Result\='READY:' then do; 'START "CCMAIL" /C /MIN /WIN c:\CCMAIL\CCMAIL.BAT' } one FirstName LastName UserPassword; } line end; else do; Result=PMSW2(ccmail); if Result='FOCUS:' then bREADY=1; end; do while (bREADY<1); Result=PMSW2(ccmail,'/r'); if Result='READY:' then do; Result=PMSW2(ccmail); if Result='FOCUS:' then do; bREADY=1; end; end; else Call SysSleep(2); end; END; else do; if RRC=2 then do; 'net use m: /d'; end; say "UNABLE TO ACCESS CCMAIL" end; byby:; RC=RXFUNCDROP('PMSW2'); '@EXIT'; /* Figure 21. REXX Sample: MAIL.CMD for PMSW2 REXX Function */ ═══ Figure 22 ═══ @ECHO OFF C: CD \CCMAIL CD M:\CCMAIL SET CCCONFIG=C:\CCMAIL\CCMAIL.INI SET PATH=M:\CCMAIL;%PATH% SET TEMP=C:\ SET WP=/D-C:\WP51/PF-C:\WP51/M-VIEW IF X==X%1 GOTO NONAME IF X==X%3 GOTO NOPASS M:MAIL /N"%1 %2" /P"%3" GOTO EXIT :NOPASS M:MAIL /N"%1 %2" GOTO EXIT :NONAME M:MAIL :EXIT EXIT rem Figure 22. DOS Sample: CCMAIL.BAT DOS Batch File ═══ 9. Details of Parse Syntax ═══ This information supplements the REXX documentation contained in the REXX Information online softcopy in the Information folder on the OS/2 2.1 desktop. It covers the REXX PARSE keyword only, and provides some explanation of the proper use of templates. See PARSE keyword to access your online REXX Information manual for syntax of the PARSE keyword. The parse rules are fairly simple. o The template consists of alternate symbols and patterns. o Each symbol and pattern is used in parsing the string exactly once. o Blanks may be used between symbols and patterns to improve readability. o The value assigned to a variable in a template consists of the characters in the input value between the point within the input value that is matched by the pattern to the left of the variable in the template and the point within the input value that is matched by the pattern to the right of the variable in the template. o If no pattern precedes the first variable in a template, then the match point for that variable is the start of the input value. o All variables that appear in a template are assigned values. o If the template consists only of variables, then the input value is parsed using words delimited by blanks, and the resulting word values have no leading or trailing blanks. o The symbol that is a single period may be used in a template as a place-holder for a variable, and the data that would have been assigned to a variable in that position is discarded. ═══ 9.1. Parsing Words ═══ Consider the code: parse value "Today is a fine day" with v1 v2 v3 v1 would contain the string "Today", v2 "is", and v3 "a fine day" Note that leading blanks are removed from the values as they are parsed into each variable. The period may be used to skip words in parsing a value. parse value "Today is a fine day" with v1 . v3 v1 would contain "Today", and v3 "a fine day". The word "is" was discarded by the dummy variable represented by the period in the template. ═══ 9.2. Parsing Using Punctuation ═══ Use of punctuation in parsing changes the results of parsing. The punctuation, and only the punctuation, is removed from the original value. Any spaces that follow the punctuation and precede the value are retained. parse value 'Movies, ball-park' with v1 ',' v2 Variable v1 would contain the string "Movies" Variable v2 would contain the string " ball-park" and would have a leading space. ═══ 9.3. Parsing with Variables ═══ The pattern in a parse command may be specified as a variable if it is included within parentheses: comma=',' parse value 'Movies, ball-park' with v1 (comma) v2 This produces the same results as the preceding example. It uses the value of the variable 'comma' ═══ 9.4. Parse by Columns ═══ You may specify where to break a value using an absolute or relative column number. parse value 'ABCDEFGHIJKLMN' with v1 5 v2 Variable v1 will contain 'ABCDE', and v2 'FGHIJKLMN' parse value 'ABCDEFGHIJKLMN' with v1 5 v2 +5 v3 Here, v1 would be the same as before, but v2 would contain 'FGHIJ', and v3 'KLMN'. The '+5' is relative, not absolute, and is the number of characters to put into v2 in this case. String and numeric patterns can be mixed within a parse command. When using numbers in a template, the input value can be parsed into values more than once when the numeric value represents a column to the left of data that has been parsed into variables already, in effect "moving backwards" in the input value. ═══ 9.5. Parsing Multiple Strings ═══ The comma may be used in a template to indicate that PARSE is to process another string. The only time multiple strings are available to parse is for the ARG or PARSE ARG keywords, or when an internal function or subroutine is called using multiple strings as separate arguments. parse arg v1 v2, v3 v4 The preceding code will parse the first string value passed to the program or function using words, and the first word of the first string will be placed into v1, with the remainder of the first string into v2. Then, parse skips to the second string and parses the first word into v3, and the remainder of the string into v4. ═══ 10. Figures ═══ Figure 1: Program Tab Figure 2: Default Command Processors Figure 3: Special Parameter Strings Figure 4: Filename Association Figure 5: Type Association Figure 6: Defining New Default Action Figure 7: File Name & Extension Association Figure 8: Adding a New Menut Item Figure 9: RUN Commands in CONFIG.SYS Figure 10: Novell Entries in INI.RC Figure 11: WPObject Keyname/Value Pairs Figure 12: WPFolder Keyname/Value Pairs Figure 13: WPProgram Keyname/Values Pairs Figure 14: REXX Sample: Load REXXUTIL Figure 15: REXX Sample: Hidden Object Figure 16: REXX Sample: Desktop Object Figure 17: REXX Sample: MAKEINI Function Figure 18: REXX Sample: Get Boot Drive Figure 19: REXX Sample: SysCreateObject Figure 20: REXX Sample: MAIL.CMD, PMSW Figure 21: REXX Sample: MAIL.CMD, PMSW2 Figure 22: DOS Sample: CCMAIL.BAT ═══ 11. Reference Material ═══ The cited references are available in softcopy form as Information Presentation Facility (IPF) .INF files; some may also be available as harcopy manuals. The softcopy versions of manuals are usually newer and available sooner than printed versions. OS/2 2.x Developer's Toolkit. This toolkit contains softcopy information about the Application Programming Interface (API) functions for the OS/2 Control Program, Presentation Manager, DOS/Windows, and System Object Model (SOM). It also contains the Presentation Manager Reference. The toolkit is a component of C++ for OS/2, and is also available as a separate product. OS/2 Procedures Language/2 REXX. This hardcopy is available as a separate order item from IBM and contains additional detailed information on PARSE that is not in the online softcopy REXX Information that is part of the OS/2 2.1 installed components. Presentation Manager & Workplace Shell Redbook, order number GG24-3732, April 1992, IBM Corporation. This Redbook provides guidance and examples for developing applications for PM and WPS. It is Volume 3 in the Technical Compendium of five volumes, GBOF-2254. Application Development Redbook, GG24-3774, April 1992, IBM Corporation. This Redbook examines the Presentation Manager execution environment, describes the structure and implementation of PM applications, and illustrates PM's facilities for supporting object-oriented techniques. It also discusses the management of workstation-based application development projects. This is Volume 4 in the Technical Compendium of five volumes, GBOF-2254. REXX from Bark to Byte, GG24-4199, IBM Corporation. This Redbook provides valuable technical information on the use of REXX with OS/2, covering OS/2 2.1 and SysCreateObject functions. REXX programmers will find this book full of useful data and examples. ═══ 12. Biography ═══ Bruce E. HФgman is a senior systems engineer with 30 years of programming experience on IBM systems, an Air Force Vietnam veteran, and former US Air Force commissioned officer and technical instructor at the Computer Sciences School, Quantico, Virginia. He currently works for Electronic Data Systems Corp. at IBM Boca Raton in Customer Migration Support and can be reached electronically at CompuServe userid 72050,1327 or Internet userid bhogman@bcrvm1.vnet.ibm.com. ═══ Computer Sciences School ═══ The Computer Sciences School, Marine Corps Development & Education Command, Quantico VA 22134, serves the needs of all branches of the service to train enlisted and officer military members in compiler and assembler languages and all facets of computer science. ═══ Electronic Data Systems Corp. ═══ Electronic Data Systems Corporation 4800 North Federal Highway, Suite E100 Boca Raton FL 33431 (407) 362-8113 ═══ Migration Advocate Program ═══ For information on Customer Migration Support staffed from Boca Raton, Florida, under Ralph Sorrentino, please contact your local IBM representative. IBM vnet users can contact Gino Troy, Jr. (GTROY@AUSVM1) who handles marketing of personal systems support. ═══ 72050,1327 ═══ 72050,1327 is Bruce's personal id on Compuserve, where he visits the IBM OS/2 fora on a regular basis. Look for his public domain files in the IBM OS/2 User forum. ═══ ═══ A Universal Naming Convention (UNC) name is a name given to a device, server, or resource to give users and applications access to the resource across the network. An example is \\server\drive\file.ext ═══ ═══ "(OS/2 2.1)" in the Keyname column indicates the start of values for PROGTYPE that pertain only to OS/2 2.1. The PROGTYPE=prog_31_xxx values pertain only to OS/2 2.1 and later releases of the operating system. Values above the PROG_31_xxx values can be used for all releases OS/2 2.x. ═══ ═══ SET values require special escape-character handling when they contain special characters such as commas or semicolons. Use the caret (^) character (the upper-case 6 on US keyboards) as an escape immediately before the special character. A good example of this is the SET DOS_VERSION value, which has commas in it: SET DOS_VERSION=USERPGM.EXE^,10^,10^,4,OTHER.EXE^,2^,3^,4; In the case of DOS_VERSION, all the values will be replaced by the value you enter. ═══ ═══ STARTUPDIR for drag-and-drop launching of programs is the directory that contains the dropped data file when a value is not specified explicitly. ═══ ═══ The term Window List is used in the OS/2 Command Reference, and that is indeed the title of that window. However, programming references and internal code refers to it instead as the switch list. This article uses Window List. ═══ ═══ OBJECTIDs are strings that are used as identifiers of locations or of objects on the desktop. The desktop itself has an OBJECTID of , and you can use this identifier as a location when you want to define objects for the desktop. An alternative method of specifying the location is to use the physical file system name of the object. The desktop would be C:\DESKTOP if C: is the boot drive and the system is OS/2 2.1 or higher. If you specify OBJECTID in a setup string value in an .RC file or when duplicating the MAKEINI STRINGTABLE function (see explanation later), then the OBJECTID parameter must be last. ═══ ═══ The strings in the Value column may be displayed as two strings in order to reduce the size of this column. The values should be single strings with no spaces within the value. For example: =PROG_31_STDSEAMLESSCOMMON;