Say Good-bye to Hello World
(Building OpenDoc Parts Just Got Easier!)
Caveat: As this article went to press, the final versions of OpenDoc and Part Meister were being prepared. As a result, the screens in this article might vary slightly from what you see on your screen. These differences are due to last-minute improvements to the OpenDoc and Part Meister software.
Back in Volume 6 of The Developer Connection News we introduced the technique of subclassing an existing part in order to simplify the building of an OpenDoc part handler. We used the Hello World part as a sample of how to subclass the OpenDoc container part. Our Hello World part inherited all of the default capabilities on the container part and added just a few minor functions by overriding the Draw, HandleEvent, and Externalize methods of our parent. This saved us lots of time - we avoided writing code for all of the 60+ methods that a part handler is responsible for, but for which default implementations would be all that we needed or wanted.
Still, there remained a substantial amount of work in order to get our part running. We had to build a makefile, write the interface definition (also known as the IDL file), generate our code template, and finally edit the code template before we could compile our part. Most of this procedure was routine and repetitive. Worse, it was error prone. So a lot of time was spent tinkering with the part to get it to build and run, and fixing all the typos, omissions, and so on that are apt to be in human-generated code. There had to be a better way...and we were determined to find one. An answer is emerging in the form of a prototype tool called "Part Meister."
Part Meister automates the routine tasks involved in creating an OpenDoc part. The developer merely enters information about the part's class name, location of toolkit files, and a target directory. Part Meister then generates an IDL file, a template source file, and a makefile to build the new part.
Let's see how it works.
To Build a Part...
Find the Part Meister object and double-click on it (you can find the object in the "Try Me!" folder). The following notebook control will appear:
In this example the settings page has entries appropriate to my system. Fill them in to match your system, and then click on the Part tab.
It's on this page that you give Part Meister the information it needs to fill in the skeleton part handler it's going to generate for you. The Template field indicates the name of the part handler that is going to be subclassed. Usually you will want to use the container part as your parent so that you can have embedding as a default behavior. After all, an OpenDoc part is much more useful if it can contain other parts as well as be embedded into a document. But in some special cases, it might be desirable to build a part that doesn't allow embedding. For those cases you'll find the simple part as a choice in the "combo" box.
Choose a class name and short name and enter them in their respective fields. The class name will be used as the object name. You'll find it prefixed liberally throughout the generated source code. Just be glad that it wasn't you who had to type it all in by hand!
The short name is used for file names and directory names. You'll usually want to pick some abbreviated form of your class name, or at least something that will help you correlate your source file names with your part handler class.
The part kind is a value that is unique to your part handler. OpenDoc uses a part's kind to match data in a document with a part handler that can understand it. Kind is specified as an ISO string (see Footnote 1), which makes it easy to create a value unique to your part. You can choose anything you like. The suggested format should contain the name of your part handler as well as enough information to differentiate between different versions of your handler. For this example I used GoodByePart:Kind:Version1 as my part kind.
You must choose a part category as well. Categories are used by OpenDoc to choose an alternate part handler when the one that created the data in your document isn't available. Category allows part handlers of similar capabilities (for example, text editors, graphics editors, spreadsheet editors, and so on) to be grouped together. Component Integration Laboratories (CI Labs) has defined a set of standard categories that part developers should use (in other words, don't go out and invent your own!).
Here's a partial list from the OpenDoc Programming Guide:
kODCategoryPlainText kODCategoryPresentation kODCategoryDrawing kODCategoryCalendar kODCategory3DGraphic kODCategoryForm kODCategoryPainting kODCategoryExecutable kODCategoryVideo kODCategoryCompressed kODCategorySound kODCategoryControlPanel kODCategoryChart kODCategoryControl kODCategoryFormula kODCategoryPersonalInfo kODCategorySpreadsheet kODCategorySpace kODCategoryTable kODCategoryProject kODCategoryDatabase kODCategorySignature kODCategoryQuery kODCategoryKey kODCategoryConnection kODCategoryUtility kODCategoryScript kODCategoryMailingLabel kODCategoryOutline kODCategoryLocator kODCategoryPageLayout kODCategoryPrinter kODCategoryTime
The GoodByePart handler doesn't really have any data that it operates on. I decided to use kODCategoryExecutable (see Footnote 2) for this example as the closest match.
From the Part pull-down menu I selected Generate. Part Meister created the following files:
Directory of G:\TOOLKITS\WARPTLKT\TOOLKIT\BETA\BIN\PMEISTER . <DIR> 8-28-95 2:56p .. <DIR> 8-28-95 2:56p BYE IDL 1473 8-28-95 2:56p BYE CPP 12647 8-28-95 2:56p BYE MAK 1152 8-28-95 2:56p 5 file(s) 15272 bytes used 224133120 bytes free
I started the build process with the following command:
nmake -f bye.mak
A coffee break later and my part was done!
To Register a Part...
Next I have to register my part. Did I forget to say that PARTS.DAT has gone away? In its place is a registration process. As of Volume 8 of The Developer Connection, all parts must provide a metaclass that OpenDoc calls during this process to determine the capabilities of a part handler (such as its supported part kinds). Part Meister created these for you so you don't have to write any code (if you don't believe me, go search the files for M_GoodByePart and see for yourself). But you do have to register a part before you can use it. To register parts, use the utility ODINST.EXE. For information on how to use it, type the following:
You'll get the following help text:
This is a generic registration program for OpenDoc part handlers.
Accepts the following command line parameters:
odinst SAMPLES registers the sample parts odinst STANDARD registers graphics, page, and text parts odinst MULTIMEDIA registers the multimedia parts odinst ALL registers graphics, page, text, and multimedia parts odinst -cSomClassName -dDLLName registers a particular parthandler odinst -uSomClassName deregisters a parthandler odinst -h or -? displays help text
At this point I entered the following command:
odinst -cGoodByePart -dbye
and waited expectantly as OpenDoc registered my part. If all goes well (see Footnote 3), you'll find a template in your template folder that looks like this:
To Run a Part...
Go ahead and drag GoodByePart onto the desktop and double-click on it.
Well, that's all there is to it. With Part Meister, you can build a new part from scratch almost in the amount of time it takes to read this article. It sort of does for OpenDoc development what instant cake mixes did for baking.
There are lots more features and angles about Part Meister that I didn't cover. Browse the source code (located in the \TOOLKITS\WARPTLKT\TOOLKIT\BETA\BIN\PMEISTER subdirectory on disc 3 of your accompanying Developer Connection CD-ROMs) and you'll see what I mean. There is this tantalizing piece of code that turns on debugging to a log file. With a minor modification it can be made to print out to the screen via PMPrintf. How to do it is left as an exercise for the reader. If you get stumped, refer to the article titled "Understanding How OpenDoc "Ticks" Using Trace and Debug Tools" in Volume 8 of The Developer Connection News on your accompanying Developer Connection CD-ROMs.
- A null terminated 7-bit ASCII string, specified in hierarchical format with colons separating the components (for example, BOCAWriter:StyledText:Version 1). For the sake of efficiency, part kinds and other values represented as ISO strings are manipulated as tokens (sometimes referred to as atoms in other systems).
- In case you were wondering, kODCategory... is defined to be an ISO string just like part kind.
- If anything goes wrong, you probably forgot to run SOMDD. I always do. So run it now, and see what happens. Anyway, why don't you just put the line START SOMDD in your STARTUP.CMD file and you'll be better off for it.
Note: This article originally appeared in a recent issue of OS/2 Inside magazine, published by AWi Inside Verlags GmbH.
About the Author
Robert Tycast has 18 years of experience in the computer software industry. He was the technical lead for the Distributed Presentation Manager Project on OS/2, and is currently an Advisory Programmer in the OS/2 Architecture and Design group. He holds a bachelor's degree from Massachusetts Institute of Technology. Robert has worked on OpenDoc for the past two years. He can be reached at email@example.com.