OS/2 eZine - http://www.os2ezine.com
January 16, 2003
Luc Van Bogaert has been using OS/2 since 1994 with Warp 3 and over the years he has become a true OS/2 advocate. However, as a pharmaceutical production supervisor, he has never had any professional need for OS/2 (although his company does have some OS/2 machines in use), but that hasn't kept him from investing a lot of his own time and money in it. He has been closely involved with the organization of the US Warpstock events since 1998 and he was Event Team member for Warpstock Europe 2001. He also is one of the driving forces behind the Belgian OS/2 Users Group.

If you have a comment about the content of this article, please feel free to vent in the OS/2 eZine discussion forums.

There is also a Printer Friendly version of this page.

Previous Article
Next Article

Do you have an OS/2 product or service you'd like to advertise?

REXX for beginners

I have been using OS/2 for more then 8 years now, and during that period I have learned to appreciate the capabilities of the REXX programming language and how it can be used to "hook" into OS/2's WorkPlace Shell and add functionality to it or change its behavior. Applications like XWorkPlace or WPS Wizard contain some impressive examples of what can be accomplished with REXX on OS/2, provided one has the required (advanced) programming skills, a thorough knowledge of REXX and at least some understanding of the inner mechanisms of the WorkPlace Shell. Fortunately, REXX is not a very complicated language and one really doesn't have to be a programming expert to learn the basics. What's more, with just a little perseverance even a beginner (like myself) quickly learns enough REXX to put it to good use, adding new features to OS/2 or the WPS.

This article is aimed at novices or beginning programmers who want to learn how they can improve the infamous OS/2 Desktop with a little REXX of their own. If you think this description suits you, keep close attention and read on...


Before we dive into REXX, you will need some documentation to help you pass the stage of the "Hello World" example most programming tutorials for beginners start with. Here's what I have used :

  • OS/2 Command Reference (cmdref.inf), included with OS/2 and eComStation
  • REXX Information (rexx.inf), included with OS/2 and eComStation
  • REXX Tips & Tricks version 3.30

The first and the second document will certainly get you started with REXX. The third one is no less than a "must-have" reference for every REXX programmer. I also recommend you get the documentation that comes as part of the XWorkPlace package, as it contains useful information about the 'RexxUtil' functions and setup strings for WPS objects.

Creating four new OS/2 features

The four functions to be discussed in this article are missing in standard OS/2, but as you will see, they can easily be added with just a little REXX (one of the functions also requires a small freeware utility program):
  • open a command line from a WPS folder, directly into that folder's directory
  • open a WPS folder from a command prompt
  • close a WPS folder from a command prompt
  • unpack a zip file into a new directory with the zip file's name

One might argue that several 'desktop enhancers' will provide the same functionality and much more, but where's the fun in that?

Opening a command prompt in a folder's directory

It may surprise you, but this feature doesn't even require REXX at all. Since the ability to open a prompt in a folder's directory comes in so handy at times, I didn't want to leave it out of this discussion. So here goes:

First step : locate the 'Command Prompt' object and open its Properties notebook. Select the 'Program' tab, and fill in the three text fields as follows :

  • 'Path and file name' : *
  • 'Parameters' : /K %**D && CD %**N
  • 'Working directory' : (leave this field blank)

Close the Properties notebook.

To use your 'enhanced' Command Prompt object, you will need to add it to the context menu of your WPS folders. A quick way to do this is by adding it to the context menu of the Folder Template object. From then on, every new folder you create with the Folder Template will have the new Command Prompt option in its menu by default.

Second step : open the Templates folder and open the Properties of the Folder Template object. Go to the 'Menu' tab and select the 'Open as' option in the 'Available menus' section. Next, drag the enhanced 'Command Prompt' object to the area under 'Actions on menu'. You can still 'fine-tune' this new menu option by selecting it in the list and using the 'Properties' button on the right. For example, you might want to define an accelerator key for the option.

Third step : existing folders won't be affected by the modifications you made to the Folder Template, so you will have to add the new menu option to existing folders by hand, performing exactly the same steps as described above. The result should look something like this:

Final step : try it out by right clicking on a folder to open its context menu, open the 'Open as' submenu and select 'Command Prompt' (or whatever name you chose for the menu option). If all is well, a command line window will open and you will notice that the prompt is in the folder's own directory. Congratulations, you've just added a new feature to OS/2!

Open a WPS folder from a command prompt

Adding this feature to your OS/2 system takes just a few lines of REXX code. Tune in, and follow closely:

First step : open a text editor (OS/2's System Editor will do fine) and type in the following REXX script (without the line numbers) :

1 /* open.cmd */
2 call RxFuncAdd 'SysSetObjectData','RexxUtil','SysSetObjectData'
3 call SysSetObjectData directory(),"OPEN=DEFAULT"
4 exit

As a side note, I'd like to point out that it is strongly recommended that you select a monospaced font in your editor, as that will make the code much more readable. Make sure to include the first line (/* open.cmd */) or the script won't run. Save the script in plain text format as 'open.cmd' in a directory of your choice. I recommend to use a directory in your path, e.g. C:\OS2\APPS

Line 3 is where all the action takes place. This line of code calls the 'SysSetObjectData()' function, which can be used to modify the attributes of a WPS object, but you can also use it to open objects. Because 'SysSetObjectData()' is part of the external 'RexxUtil' function library (luckily included in OS/2), you need to explicitly load the function to make it available to the REXX interpreter during runtime. This is done in line 2.

'SysSetObjectData()' takes two arguments: the first is the 'object-id' or the full path name of the object you want to modify/open. This example uses the REXX 'directory()' function to return the path of the current directory. The second argument is a 'setup string'. Lots of possibilities here, depending on what you want to do with the object in question. Since our objective is to open an object, we use "OPEN=DEFAULT" as the setup string. This will open the default view of the object.

Second step : open a command prompt window and change to the directory that contains the script so you can test it. Run the script by typing 'open' followed by <Enter>. You should see the current directory open as a folder on your Desktop (in the background). If the script doesn't run, verify that you have placed it in your path so that your system can find it.

Final step : use the documentation mentioned above to increase your knowledge of REXX, and you will soon notice that it is possible to add all kinds off features to this script with relatively little effort. For instance you could use a command line argument to let the user specify which 'View' of the object he wants to open, e.g. 'open TREE <Enter>' would open a Tree view of the current directory. Here's the script:

1 /* open.cmd */
2 parse arg viewArg
3 select
4     when viewArg = "ICON" then
5         view = "OPEN=ICON"
6     when viewArg = "TREE" then
7         view = "OPEN=TREE"
8     when viewArg = "DETAILS" then
9         view = "OPEN=DETAILS"
10    otherwise
11        view = "OPEN=DEFAULT"
12 end
13 call RxFuncAdd 'SysSetObjectData','RexxUtil','SysSetObjectData'
14 call SysSetObjectData directory(),view
15 exit

Line 2 reads the command line argument and remembers it by placing it in a variable called 'viewArg'. Lines 3 to 12 contain the REXX 'SELECT WHEN' structure, that can be used to compare a variable with different possible values. Depending on the value of 'viewArg', another variable ('view') is assigned a different value, which is subsequently used in line 14 to open the desired view of the current directory.

For those who still want more, here's a sample open.cmd script that has even more features. Study it and feel free to use it on your own system. Also pay attention to the code at the bottom which is a little trick to open folders above all other windows on your Desktop.

Close a WPS folder from a command prompt

This feature is the opposite of the previous one. Unfortunately, classic REXX does not provide a function to close a WPS object similar to 'SysSetObjectData()' or 'SysOpenObject()'. For this reason, it might be worth exploring Object REXX, which is also part of OS/2, but we'll discuss another alternative here.

It turns out that somebody already did most of the work by writing a small freeware utility program that can send a 'window message' to a running PM program or WPS folder. Martin Vieregg's 'ZipShell' package contains the 'sendmsg.exe' utility and it happens to be perfectly suited for use in our own project.

First step: download ZipShell and unzip 'sendmsg.exe' from the archive and place it somewhere in your path, e.g. C:\OS2\APPS.

Second step: all we have to do is let 'sendmsg.exe' send a 'WM_CLOSE' message to the object we want to close (i.e. the current directory). Here is the script:

/* close.cmd */
'sendmsg' substr(directory(),lastpos('\',directory())+1,) WM_CLOSE '> nul'

It should be no surprise that Line 2 does all the work here. It uses the REXX 'substr()' and 'lastpos()' functions to strip the folder name from the complete path name returned by 'directory()', because this is what 'sendmsg' expects as the argument. Save this script as 'close.cmd'.

Final step : try it out by opening a folder from the command line using your own 'open.cmd' script and then close the same folder again by typing 'close' followed by <Enter>. If this doesn't work, make sure you have both 'sendmsg.exe' and 'close.cmd' in your path.

I have included a sample script close.cmd with more features for you to study and build upon. Have fun!

Unpack a zip file into a new directory with the zip file's name

This example brings together some of the stuff we discussed earlier to build some kind of WarpZip 'lite' and add it to the WPS as a new feature. Let's summarize the objectives of our little project:

  • write a REXX script that uses 'unzip.exe' to unpack a zip file into a new directory
  • create a Program object to start the script and let the user (optionally) set a target directory
  • associate the program object with zip files, effectively adding a new menu option to the context menu of all zip files.

When we are all done with this, here's what the result should look like:

First step: copy and save the included sample script unpackme.cmd to a convenient directory on your disk. This script is the basis of our project. As you look at the script, the comments (text between /* */) should make the code relatively easy to read and understand, so I am not going to discuss the details here. However, there is some important stuff in the script that you should try to understand:

  • stream(sourcepath, 'c', 'query exists') is a function call to check if the zip file actually exists
  • the OS/2 command 'mkdir' is used to create the target folder for the unpack operation
  • 'unzip.exe' is called to perform the actual unzip operation. So make sure to put this separate program somewhere in your path (e.g. C:\OS2\APPS) or your script can won't find it.
  • 'SysSetObjectData()' is called several times to set some attributes of the target folder, including its position on screen, the background bitmap and the 'Always maintain sort order' attribute. For this to work, make sure you have a bitmap called 'zipbkgrd.bmp' in your \OS2\BITMAP directory.

I recommend studying the script using the online REXX documentation in OS/2 and looking up any functions or commands that you don't fully understand. Don't worry, because everything is well documented.

Second step: create a Program object using the Program template in your Templates folder. The Properties notebook should open automatically as you drag and drop a new object from the Template onto your Desktop (if it does not, you can open the Properties manually). Type the full path name of the script in the first text field off the Program tab, e.g. C:\OS2\APPS\UNPACKME.CMD.

In the 'Parameters' field, type the following text:

%* [Enter optional target path :]

The '%*' part of this string passes the name of the zip file to your script so it knows what file to process, while the '[ some text ]' part will open a dialog window prior to execution of the script, giving the user the opportunity to pass additional parameters to it (e.g. the target path for the unpack operation).

Final step: go to the 'Icon' tab and give the Program object a meaningful name (e.g. 'Unpack') and assign a nice icon to it unpackme.ico. You should also create an association between this Program object and *.zip files, so you can start the program from the context menu of any zip file. To do this, open the 'Association' tab and type '*.ZIP' in the 'New name' text field and press the 'Add' button.

That's it, you're done! Now see if works by selecting a zip file, open its context menu with a right mouse click, select 'Open as' and choose 'Unpack' and watch what happens... that's right, you have created your own WarpZip 'Lite'.


This article has discussed only a few basic features of REXX and yet, even with this very limited set of functions, we have shown that it is possible to add a number of very useful new features to the WorkPlace Shell. Readers who like the idea of enhancing their OS/2 system this way and want to learn more, should start exploring the possibilities offered by REXX. After all, as part of every OS/2 or eComStation system, it's right there at your fingertips, ready to be used. As a final glimpse of what REXX on OS/2 is capable of, I would like to invite everyone to take a look at RexxMail, a complete and full featured WPS-aware e-mail client completely written in REXX.

Previous Article
Next Article

Copyright (C) 2003. All Rights Reserved.