DrDialog, or: How I learned to stop worrying and love REXX - Part 1
By Thomas Klein
Dear readers, today I would like to start a new approach in writing articles: After some fellow contributors as well as the editors claimed to support me in my intention, I'll dare to start a series about "Introduction to REXX with DrDialog". Its aimed at people who either have no experience at all in matters of REXX or those who have some (more or less), but are lacking a way of writing GUI programs or who might just be afraid of getting in deeper contact with DrDialog or its usage.
I am not doing it for the sake of humanity - nope! I expect all the former non-developers to stand up and shout "hooray", covering the community with a flood of new OS/2 programs in 4 months in the large. ;)
Now to be serious: I was thinking that there might be more people out there who share my experience: A couple of ideas in your head but never learned any usable programming language when it comes to OS/2. Well, I've overcome that and wanted to offer them the same opportunity: If I have succeeded, then you can also!
How I got to know REXX
In all those years, that I've been using OS/2 (that's about a decade now), I've been successful in avoiding working with REXX. To me, REXX was alien technology. Back then, there was a colleague of mine who shared my interest in OS/2 and was not as biased as me. He told me that REXX was incredibly powerful, cool and fast - especially when considering that it is an interpreted language. And that I should try - maybe that made me even more insecure.
Those were the days when all my programming experience was made up of COBOL, COBOL and again COBOL. Well, I was a d**n good programmer, to be frank. It earned me a great reputation and a lot of bucks as well. On the other hand, I think that my addiction to COBOL did keep me away from looking at and trying out "new" stuff like Java, C and so on, let alone REXX of course. I deeply regret that today. Since then, my collection of programming languages did extend up to VisualBasic only, but let's forget about that.
During my last year's visit to Warpstock Europe I had the opportunity of sneaking around the Team Ruhr booth, where they were showing how easy it was to do backups of one's Palm PDA data using the PilotLink software. After returning home, I downloaded it immediately and checked it out. To my surprise, all "private" data that was kept well secret in the device was (of course) saved on the PC's hard disk without any encryption or access control.
I had the idea of a small script doing nothing special but simply zip these files using password encryption; the archive's name being derived from the current date. Although I hadn't really worked with REXX at all, I knew that this had to be a "classic task" for REXX. Which appeared to be correct. In addition, Visual Age for Basic was (and still is) a hell-hole of instability, and batch files didn't provide me the functionality I needed to accomplish the task... it had to be REXX - no way out. Well did it work out? Yes. I'm still using the program today and in the meantime I've got command over REXX. I guess. ;)
How I got to know DrDialog
After some time of playing around with REXX, there was one thing that began to bug me. It was the lack of development environment that enabled me to do GUI programming. I was questioning myself whether there was anything like Visual Basic available for OS/2. After getting hold of a copy of VisualAge for Basic on eBay, I quickly discovered why IBM decided to make that product disappear. Then I remembered that strange thing "DrDialog" that was lying around somewhere on my hard disk for years and decided to give it a try.
I must admit that it was hard in the beginning. Besides the fact that I was struggling with REXX' syntax back then (and still today in parts), I hardly succeeded in accomplishing even the most basic tasks using DrDialog's controls - like text output in a text box control for example.
But sooner or later I happened to understand the principles of what the DrDialog development environment was about. I am convinced, that things would have been a lot easier if there hadn't been my "microsoftical, visual-basical" way of thinking. But that's just the way it goes: Before you even notice, you'll be indoctrinated by those guys from Redmond... or is it called "assimilated"...? Well...
This brings us to a core point:
The less you have had to mess with objects and REXX in the past, the better you'll proceed. ;) If you can bring along basic knowledge of the "flow of control" in programs, that's fine - but that's not mandatory. To give you a short overview of how I want to proceed with this series I'll start by explaining download sources and installation of DrDialog and what all the buttons are about.
Next, we'll have a short "briefing" on matters of GUI elements with some examples to understand how those "controls" work, before we start to work on more complex tasks. Later on in the series, we'll take a look at what OS/2's environment is about when dealing with REXX like WPS objects or file input/output. Most probably I'll lead on to fellow authors who'll provide us with knowledge about TCP/IP-sockets (FTP, WWW), inter process communication functions ("named pipes", "semaphores") or maybe even the "king size" of REXX-programming: Database functions. The whole series is intended to be based entirely upon freely available software, so that everybody is able to follow it. And this gets us to the first step:
How you'll get to know DrDialog
DrDialog is an EWS (employee-written software) from IBM. It was developed in 1993/1994 by David C. Morrill who worked at IBM's T.J. Watson Research Labs in Austin/Texas back then (if I'm told correctly).
One special thing about EWS is, that it's freely available from IBM, although big blue holds all the rights to it without providing any support or warranty for those products... okay, it's free at least. As a matter of fact, both documentation and interface of DrDialog are in English. [Translator's note: The following paragraph was intended for the German readers] If you happen to need help but don't speak English there's no need to panic. Just go ahead and pop into a newsgroup with your questions. Even if English was meant to be the primary language, you'll find someone who takes care of you. Don't let those "this-is-English-only"-folks get you down. You'll find such ignorant people everywhere - if you require help with a technical or programmatical problem, you shouldn't give up because of foreign language. (Until now, I haven't seen anybody get upset if somebody else wasn't able to speak a certain language. Especially when dealing with OS/2 you'll find German speakers (who might assist you in translating your question) in almost every newsgroup / newslist).
Of course you're free to download DrDialog from Hobbes (I included the link at the end of this article). But for now, I would like to point your attention to another source, introducing you to a way of getting help as well: It's the "GuiObjectREXX" group at Yahoo!-groups (formerly known as egroups).
Although I scanned egroups lists various times in search for "OS/2", this one never showed up (or maybe it didn't exist back then yet), and just recently became added to my list of regular checks. I only got in contact with that group thanks to Chris Wohlgemuth, who pointed me there. I had a question concerning DrDialog but didn't know of any point to start because as many others I'm living on an island of OS/2 in an ocean of windows. Then I remembered Chris fiddling around with DrDialog during last year's Warpstock Europe and emailed him. And he replied (pointing me to the group). Yes, sir/ma'am: Can you picture what great events those Warpstocks really are and that you should really get there? Just drop by and do some talking with the boys and girls at the booths - they'll be pleased, you'll see.
Back to Yahoo!-groups: You don't need a newsreader to participate. It's entirely made up of HTML and provides you with the means of exchanging news and share files. Both beginners as well as "professionals" team up here to solve problems or provide support in matters of DrDialog, VX-REXX, Vispro and so on. And it's intended for users/developers of OS/2 programs.
Well, okay... I must admit that it isn't a quite "active" group, but there simply aren't that many questions ...up to now. ;) It's up to you to change this situation. Lately I posted a question (still being a novice) and I got a reply within the same day. ( Of course, there's the "usual" newsgroups as well ! And there are special German-speaking groups too, in case of... you know).
The GuiObjectREXX-group was set up to not require you to join the group in order to download files or read messages. Posting messages or replying to other messages however requires you to sign in and join the group - don't worry, it's free. You only have to stand those annoying ads popping in from time to time that will make you click once more to get where you actually wanted to. So, once you've arrived at http://groups.yahoo.com/group/GuiObjectREXX/ you'll be presented the welcome screen along with a short overview of the most recent five messages:
On the left, you'll find a navigation tree that holds all parts of the group activities (messages, chat, files, photos...). Click the link named "files" and it will quickly take you here:
Now, just click on the file named "drdialog.zip" to download it. Those among you, who find themselves caught behind a "hostile" (or badly set up) firewall will certainly appreciate the fact of the download being done in HTTP, not FTP. ;)
Other things you'll need
...are those two fixes, which are available in the "files" section of the group as well:
- DrDlgFix.zip (contains a revised module for the development environment's extension mechanism)
- DrDlgRc.zip (contains a previous version of os/2's resource compiler 'rc.exe')
I didn't really quite understand, what that "old" resource compiler thing is meant for. It's a version dated 30-may-1995. This makes it the most vintage version I've seen around in Warp4, including the one that came on the Warp4-GA CD and others from various toolkits. Don't ask me, what this is all about. I downloaded it and just did what I was told in the readme without any further thinking about whether it was useful or not (foolish behaviour, one might say) and have had no problems up to now. Other users have said, that they didn't have any trouble using the newer versions of rc.exe either - for what its worth, get yourself the older version and in case of problems just change back to a newer version.
There are two types of installation programs in my opinion: The first one will copy (or unpack) files from a source directory into a user-specified target directory and eventually creates desktop folders and objects. The second type (the one that INSTALL.CMD from DrDialog's ZIP file belongs to) simply creates WPS objects in place - thus, it refers to the place of the files at install time - no copying is done. This means, that before running INSTALL.CMD, you should create an appropriate directory that contains the unpacked contents of DrDialog's ZIP file (the one you downloaded). Then, run the install script that will do all necessary steps... or maybe not, just like when I did:
Well... that's no surprise, because the files it is complaining about don't even exist in the package. Neither does DREXAM.RAM, intended to contain additional examples. Normally one would start the module DrExam.RES from within the DrDialog environment. It would then take usage of LOADRAM2.EXE (an unpacking module that is not contained either) to extract the sample programs from DREXAM.RES and place them into the program directory. Hmm. Seems like things went wrong back in the days when the ZIP file was packaged, and my search attempts for DREXAM.RES didn't turn out to be successful. Well, okay, I didn't really spend a lot of time on the search, but it's somehow strange to my mind.
There's no need to worry anyway. Everything works despite the missing files and talking about examples, well, you'll get that from me. ;) Anyway, once the install has completed, you'll notice DrDialog's folder on your desktop:
Now, let's just quickly deal with the additional 2 ZIP files: The contents of DrDlgFix.zip (a file named DRSAIDE.RES) is to be copied into the program directory where you just placed the DrDialog files before. It's meant to replaces a previous version of the same file. The contents of DrDlgRc.zip (RC.EXE) have to be copied there as well.
Actually, we have now arrived at the very moment where I planned to stop the first part and get off into holidays,,, but wouldn't that be a little mean? So here we go - let's take a look at what you can take comfort in 'til I'm back with the second part in October...
Invoke the development environment by double-clicking the "DrDialog" object (yep, the one with the 'hand'). This should bring up a scene like...
DrDialog now already started a new "project" for you, providing an empty "dialog" template too. The background window is DrDialog's "workspace". All components of DrDialog's environment are designed to be placed wherever you want them to on your screen (tool bars, color selection window, code editor window and so on). If you take in account all other windows that might be opened on your desktop (those of other programs), this will soon mix up into one large mess, making you lose control about "who belongs to what". Thus, the intention of the workspace window is to "overlay" all other windows that don't belong to DrDialog.
To start somewhere, just click on the "Tools" menu entry. Whoops - don't be afraid... yep, there's only icons, no text. Next, click the lowest entry in the third column (from left) and - voilá! - Mr. Morrill, David C., the guy who gave us DrDialog.
This is the "product information" screen of DrDialog, providing the version information in its titlebar. There's nothing much left to explore from here: EDIT will take you back to the edit mode (closing the windows), whereas HELP obviously fires up DrDialog's online help.
Before we start with the famous "hello world" example, there's one usage note about DrDialog: As you might have noticed, there are some small "knobs" or "grab points" visible at both corners and centers of the empty dialog window's frame.
Obviously, they're meant to drag the frame of the window to change its size and/or position. This is correct, but it won't work if you intend to do it "as usual," using mouse button 1, because at design time (while in edit mode), this mouse button is only used for control of the development environment, that's to say clicking on menu items or selecting objects. In order to change size or position of dialogs or dialog elements (like check boxes, listboxes or entry fields for example), you'll need to rely on mouse button 2. This behaviour is easily explained by figuring out what happens, if mouse button 1 would have been used to do such editing as well: Once you would have finished arranging all your screen objects on the dialog with such sophistication, you'd have to struggle with a lot of accidental moving or sizing. As far as I remember, the guys from Redmond overcame this problem by providing an additional "lock in place"-property for each type of control type at design time. Sizing or moving the object was only possible by either manually entering the values in the properties window or by un-locking the object again, thus providing a "slippery-safe" way of using the mouse. Wow - what a hell of a good idea. Of course, this speeded up design incredibly. ;) I prefer DrDialog's way of controlling it by mouse button assignments by lightyears.
Later on, when your program will be running, the dialog will act and behave just like any other window in matters of sizing and moving. But for now, we're in design mode and this means, that the dialog window just is another element as all other GUI elements, so-called "controls".
All components that make up a graphical user interface (GUI) are called "controls". Besides the dialog that we're just looking at, this includes buttons (or "command buttons"), selection list boxes, text entry fields, even menus and a lot more.
So let's dare to start our example and provide our dialog with an "OK" button. What we need now is some kind of list or selection of controls... to say it clear: Where to get the button? As you know, there's many roads leading to Rome. And there are three ways leading us to buttons:
- the obvious way
- In the workspace menu bar, select "controls". The first entry stands for a button ("P" meaning "pushbutton"). Once you select the entry, DrDialog provides an empty button template and is awaiting your command, where to place that thing (you might notice the change in shape of the mouse pointer when moving it over the dialog). To finally drop our button somewhere, just click. Done.
- the fast way
- Click mouse button 2 ("context menu button") while above an empty region of the dialog window - it shouldn't be too difficult to find an empty spot at this stage <g>. From the context menu popping up, select "controls". The rest just works as described above.
- the concise way
- The one I love best. In the workspace menu bar, select "tools". Goodness - even more pictures.... don't panic, we'll talk about it later. First, select the entry that looks just like a button (rightmost column, middle entry). Ohhh, Uhhh!
Well, doesn't that look great? There they are, the button being the first one (top left). Go ahead and click it. Doesn't work, right? It acts just like a template - use mouse button 2 to click and drag it to the desired location. Done. Phew! Now, let's immediately take a look a something VERY important: Move the mouse pointer to an empty spot of your dialog window and click mouse button 2. Whoops - where's the controls selection window gone? Now you see what made me go mad for almost a week or more when starting to work with DrDialog. I was upset: Such a great concept based on mouse button assignments but then I'll find stupid windows closing and the need to click over and over to get the job done? But: Some things in life take longer to make it to one's brain. That's especially true for me. While going through the online help, I discovered a note about how to get rid of that symptom: Each tool or control window of DrDialog comes with three additional entries in its system menu:
- Auto Open
- If selected, the corresponding window will be opened automatically at startup
- Auto hide
- If selected, the corresponding window will be closed automatically if another window is opened (Unfortunately, context-menus belong into this category as well)
- If selected, the corresponding window will be shown on top of all dialogs that are being edited, even if it's not the active window (Very useful e.g. when comparing properties of multiple objects that need to be selected by consecutive mouse clicks)
Of course, the above three options are NOT mutually exclusive but can be combined according to your needs at any time. Even if you don't use option 3 (Float), you should at least make sure as a DrDialog beginner, that the "Auto hide" option ist NOT activated. As you're about to start working with DrDialog, your programs will be made of small interfaces and you will prefer to hold all tools windows opened as it might take you some time to find them and it will defer your concentration to think how/where they can be opened. Later on, you'll know where to find that stuff and you'll need all available space to design bombastic, x-large interfaces.
If you move the mouse pointer on top of the button you just placed on your dialog, you'll notice the text of the status line at the bottom of the workspace window to display "101 (PUSHBUTTON)".
That's the name of your button - "101" and it was automatically derived from the button's object-ID. Each component of your GUI interface (button, dialog, etc.) is referred to by the system via it's unique object-ID. Everything you're about to do while working with controls in your REXX code will include this reference. "This button over there" might simply not be enough to tell the program what you mean. ;)
Besides this rather cryptic way of naming controls, you can assign them names too - actually, the current name "101" doesn't seem to be a real progress. So let's change it: Click mouse button 2 while pointing at the button we just dropped. From the context menu, select "Name". You'll be presented an entry field: Type "sayhello" (without the quotes) and press <Enter>.
(The screenshots are taken from the German version of this article; "saghallo" translates as "sayhello"...) Now, If moving the mouse pointer on top of the button, the status line will say "101 - sayhello (PUSHBUTTON)". You just assigned a name to the control. Okay, what more do we need to finish the example?
A Textbox. That's an area used ONLY for output of text, which means that you can't enter anything. Go get yourself the textbox in the same way (or another one of the three ways) that we did to get the button. That's not too difficult, as "Text" is written on the according symbol. So, let's go get it:
We'll assign a "useful" name to the textbox too, as "102" doesn't really help us to remember what's behind it. Just like before: Click mouse button 2 (context menu) on top of the textbox. Select "Name" from the menu and enter "output" - again, without the quotes.
By the way: You can't assign a name more than once. Trying to do so by naming our textbox "sayhello" for example would result in DrDialog changing it to "sayhello_2" and proposing this new name in the entry windows. Either you accept this new name or you figure out something else, but there's no secret name change happening under the hood.
Now let's breathe some life into it: We're about to tell the program what it should do if somebody clicks our button: The textbox should display "Hello world!". Well, that's nothing truly inventive, but it's okay for now. ;)
Along with its properties, each control provides means to react on certain events. In our example, the button is able to react on the "click" event. This event will be triggered by the system, if the button was pressed (either by clicking the mouse on it or by pressing the <space> key after it was tabbed to).
Once again, there are various ways to get where we want to: The fastest way is to simply double-click on the button. Another quite fast way is to activate the buttons context menu and select "events", then "click". The second approach - by the way - is very useful to explore all events, that a certain control can react upon. But okay - here we are:
Now it's time - for programming in REXX? Not really, it's "DrREXX". While it's basically still REXX, there is a bunch of extensions built into it to be able to deal with the GUI controls and so on. Now to make sure: We find ourselves in the very step that will be invoked by the system, if somebody clicked our button. And it states... nothing. And this is exactly what will happen, if we run the program now and click on the button: Nothing. Okay, for heavens sake, let's tell it finally what the heck is has to do:
call output.text("Hello world!")
And that's it. But we need to get into some theory, I'm afraid, to understand what's going on here: Each control has got its properties. The control (or: object) named "output" is a textbox and therefore has got a property named "text" which is the text being displayed. To change properties, we use mechanisms called "methods". In this case, we need to use a method that is named exactly like the property: "Text". By using the CALL command, we're invoking a method. This method is called "Text" and we pass it along the parameter "Hello world". And for the program to be able to know, *whose* method we're calling, we'll additionally provide the name of the control. So to be more detailed...
call output.text("Hello world!")
CALL the control OUTPUT's method named TEXT and pass it "HELLO WORLD!"
That's how it works. If you managed to follow up to this point, I would like to take the occasion and welcome you in the world of object-oriented programming. ;) Seriously: It surely takes more, to do object-orientation, but hey: You just learned some basic principles about it and managed to get something done!
But... shouldn't we first check it out? Fine: Form the workspace menu, select "tools", then the entry that shows the running guy. This will bring up the Run-Time Monitor window.
Later, I'll talk about all those buttons and the meaning of "run-time", but for now, there's southern France waiting for me (and two unfinished suitcases as well as my wife). Just click on the running guy symbol again - Wow! Now your dialog is looking somewhat different, right? And it reacts to drags and sizings just as usual... oh come on, click it! ;)
Great! Unfortunately, there's no button to quit yet - and there's no window buttons in the title bar either, because we didn't use a "suitable" type of dialog. For today, use ALT-F4 or double-click our dialog's system menu. Now we're back in editing mode. To save your first application with DrDialog, select the "File" menu, then "save". Select drive and path and specify a name in the topmost entry field. There is no need to specify an extension, but make sure you selected the "Resource" checkbox in the lower right area of the screen.
Click on "SAVE" and that's it.
Before I leave you fiddling around, there's a little homework for you until October: As you might have noticed, our textbox has "Text" being displayed upon startup. That's bad, hm? This is due to a default value that can be assigned. This is useful e.g. when you create a data entry dialog that states "Name:" in front of an entry field. This way, you save the need to go through all the textboxes, assigning them appropriate texts to de displayed but instead, you can easily and comfortably do this work at design time, making your dialog appear with everything loaded and prepared. Of course, we would prefer our textbox being empty at startup. There's two ways of doing so:
- At design time, we select the textbox property to specify "empty" contents.
- At run time (when the dialog starts), we assign an empty string to the textbox.
Okay, to be honest: I know this is difficult, when you just started with DrREXX and there's obviously a lot of information missing and your head keeps spinning around with all the terms and syntax stuff. But just try to find out, how to solve this problem. If you don't succeed, just play around with our example and don't let it get you down: Rome wasn't built in a day either... no matter, how many roads were leading towards it. ;)