Introduction to PM ProgrammingWritten by Gavin Baker |
IntroductionMenus, dialog boxes and icons are all examples of Resources in OS/2. Resources are stored in their own read-only segment within the executable file (or DLL), can be shared between multiple instances of a program, and are normally loaded only when required at runtime rather than at the load time of the application. The most commonly used resource types along with their definition are shown below:
Resources are created in two ways (depending on the type of resource). They are either text or binary. The binary resources are POINTER, BITMAP, and FONT. All the other resources are textual. The RCDATA type is special, as it allows the programmer to define a custom structure for a resource. The RC.EXE program is called the Resource Compiler, and it takes the your source file and compiles it into a binary form (.RES). It also binds the .RES file with your executable. We will examine the general syntax of resources and the structure of the RC file, and then examine each type in detail. ScopeI am assuming that you are a competent C programmer, and have a working knowledge of OS/2 from a user's perspective. The sample code here was produced with Borland's Resource Workshop for PM and tested with the OS/2 Resource Compiler (RC). Syntax and the RC FileResources are defined in a text file with the .RC extension. There are a number of keywords for the different resource types, and each keyword defines one resource. Resources are referenced by an identifier, which takes the form of a C #define. Since the Resource Compiler (RC.EXE) supports C-like #includes and #defines, it is convenient to have all the symbols defined in one header file for the resources and their IDs. (Obviously they must have unique numbers). Resources are usually named according a certain convention - ID followed by a single letter denoting the resource type, an underscore and then a descriptive name. Here are some examples: #define IDM_FILE 10 /* the ID of the FILE Menu */ #define IDS_ERROR 300 /* the ID of the ERROR String */ #define IDD_OPTIONS 436 /* the ID of the OPTIONS Dialog */ Generally speaking, a resource statement consists of the following: TYPE | IDENTIFIER | +-----+ | | | MEMORY | OPTIONS | | +-----+ | RESOURCE DEFINITION | | - Due to the differing nature of resources, it is easier to show the syntax for each type's definition rather than to generalize here. The options refer to the Memory Options, which specify how OS/2 treats the memory occupied by the resource. The memory options are as follows:
Note that the default options are marked with an asterisk. These options apply to all of the resource types. ResourcesIn the following sections we will see each type of resource (at least the most common ones) and some examples, along with how to use them in your programs. The syntax diagrams follow those conventions used in the Command Reference, but also note that keywords are underlined. String TableSyntaxSTRINGTABLE | IDENTIFIER | +-----+ | | | MEMORY | OTIONS | | +-----+ | BEGIN | |<---------+ | | | IDENTIFIER | | | | STRING | | | +----------+ | END | | - NotesString tables are used to keep all of the static text which is used in a program in one place, thus making it easier to manage, and also to maintain versions in multiple languages. Ideally the program source code should be free of static or literal text, and instead use a STRINGTABLE to manage the text. Strings are loaded by using the WinLoadString call, and once loaded, are used exactly the same way as a normal string. ExampleSTRINGTABLE ID_ERRORS FIXED BEGIN IDS_FILENOTFOUND "Sorry - I can't find that file anywhere!" IDS_NOGAMES "Games are not allowed during office hours." IDS_BYEBYE "Are you sure you really truly want to go?" END OutputThere is no output as such from this resource - you would use it in your program like this: WinLoadString(hab, NULLHANDLE, IDS_BADCMD, MAXERRORLEN, pszError); WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, pszError,"Error!",0, MB_CUACRITICAL | MB_OK); This will load an error message from the executable file and display an error message in a box. Message TableSyntaxMESSAGETABLE | IDENTIFIER | +-----+ | | | MEMORY | OPTIONS | | +-----+ | BEGIN | |<---------+ | | | IDENTIFIER | | | | STRING | | | +----------+ | END | | - NotesA Message table works just the same way as a STRINGTABLE. Most applications use a STRINGTABLE, or use the MKMSGF (the Make MeSsaGe File utility, documented in the Toolkit Tools Reference). ExampleMESSAGETABLE ID_ERRORS BEGIN IDM_PRINTEDOK "The file has been successfully printed." IDM_SYNTAX "A syntax error was found on line %1." END MenuSyntaxMENU | IDENTIFIER | +----+ | | | MEMORY | OPTIONS | | +----+ | BEGIN | |<-----------------+ | | | MENUITEM | | | | TEXT | | | | IDENTIFIER | | | | STYLE | | | | BEGIN | | | |<-----------+ | | | | | | MENUITEM | | | | | | | TEXT | | | | | | | IDENTIFIER | | | | | | | STYLE | | | | | | | ATTRIBUTES | | | | | +------------+ | | | | END | | | +------------------+ | END | | - NotesI hope this diagram isn't too confusing - if you examine it, all it means is that a MENU consists of one or more SUBMENUs, which consist of one or more MENUITEMs. You can leave off the style and attributes if you don't want to specify any (see the example). Put a tilde ~ character in to specify that the following letter will be the underlined shortcut key. Note: If you make the ID of the menu the same as your main window that you create with WinCreateStdWindow and use the FCF_MENU style when you create it, PM will automatically load the menu and assign it to the window. ExampleMENU ID_MAIN BEGIN SUBMENU "~File", IDM_FILE BEGIN MENUITEM "~New", IDM_FILENEW MENUITEM "~Open...", IDM_FILEOPEN MENUITEM "~Save", IDM_FILESAVE MENUITEM "Save ~As...",IDM_FILESAVEAS END SUBMENU "Fon~t", IDM_FONT BEGIN MENUITEM "~Small", IDM_FONTSMALL MENUITEM "~Medium", IDM_FONTMED, MIS_TEXT, MIA_CHECKED MENUITEM "~Large", IDM_FONTLARGE MENUITEM SEPARATOR MENUITEM "~Options...",IDM_FONTOPTIONS END END Output
DialogSyntaxThe dialog template itself: DLGTEMPLATE | IDENTIFIER | +----+ | | | MEMORY | OPTIONS | | +----+ | BEGIN | DIALOG | TITLE, ID, X, Y, WIDTH, HEIGHT | +----+ | | | STYLES | | +----+ | BEGIN | |<---------+ | | | CONTROL | DEFINITION | | | +----------+ | END | | END | | - The Control Definition: CONTROL | TEXT | ID | X | Y | WIDTH | HEIGHT | +----+ | | | STYLES | | +----+ | - NotesA dialog template is used to define a dialog, which contains many controls. The control can be a custom control, or one of the following:
to name a few. Consult the Toolkit documentation for a complete description of all the different controls. Once you know how to use one, the others work basically the same. ExampleThis example was produced with Borland's Resource Workshop for PM (part of Borland C++ for OS/2), which makes it easy to visually design dialogs and other resources. The IBM Toolkit also includes a Dialog Editor. As you can see, a reasonably simple dialog can get fairly complex. If you were to write this by hand it would take hours to figure out the X and Y positions, flags, etc. This is not practical for anything but the simplest of dialogs, so a dialog editor (such as the two mentioned above) is invaluable. This may seem complicated, but it is fairly straightforward. Everything except the buttons is defined as a CONTROL (a generic way of specifying a control). The type of control is given in the flags, for example the comment edit field is defined as a WC_ENTRYFIELD, and has its own specific flags (ES_LEFT and the others). There are lots of flags specified (more than if you had done it by hand) but most have reasonable defaults. Three things to note:
DLGTEMPLATE 1 BEGIN DIALOG "Sample Dialog", 100, 30, 90, 300, 150, WS_VISIBLE, FCF_SYSMENU | FCF_TITLEBAR BEGIN CONTROL "", 109, 44, 104, 72, 35, WC_COMBOBOX, CBS_DROPDOWN | ES_ANY | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "", 112, 156, 128, 133, 9, WC_ENTRYFIELD, ES_LEFT | ES_AUTOSCROLL | ES_MARGIN | ES_ANY | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "~Preload", 102, 20, 96, 50, 10, WC_BUTTON, BS_AUTORADIOBUTTON | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "~Load on Call", 103, 20, 80, 72, 10, WC_BUTTON, BS_AUTORADIOBUTTON | WS_VISIBLE | WS_TABSTOP CONTROL "~Fixed", 104, 104, 96, 50, 10, WC_BUTTON, BS_AUTORADIOBUTTON | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "~Moveable", 105, 104, 80, 50, 10, WC_BUTTON, BS_AUTORADIOBUTTON | WS_VISIBLE | WS_TABSTOP CONTROL "~Discardable", 106, 20, 56, 68, 10, WC_BUTTON, BS_AUTOCHECKBOX | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "", 107, 172, 84, 48, 12, WC_SPINBUTTON, SPBS_MASTER | SPBS_ALLCHARACTERS | SPBS_JUSTLEFT | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "", 108, 236, 84, 48, 12, WC_SPINBUTTON, SPBS_MASTER | SPBS_ALLCHARACTERS | SPBS_JUSTLEFT | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "", 113, 172, 56, 48, 12, WC_SPINBUTTON, SPBS_MASTER | SPBS_ALLCHARACTERS | SPBS_JUSTLEFT | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "", 114, 236, 56, 48, 12, WC_SPINBUTTON, SPBS_MASTER | SPBS_ALLCHARACTERS | SPBS_JUSTLEFT | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "", 121, 16, 26, 268, 12, WC_ENTRYFIELD, ES_LEFT | ES_AUTOSCROLL | ES_MARGIN | ES_ANY | WS_VISIBLE | WS_GROUP | WS_TABSTOP CONTROL "~Memory Options", 101, 10, 48, 150, 72, WC_STATIC, SS_GROUPBOX | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE | WS_GROUP CONTROL "T~ype", 110, 8, 128, 27, 8, WC_STATIC, SS_TEXT | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE | WS_GROUP CONTROL "~Text", 111, 130, 128, 24, 8, WC_STATIC, SS_TEXT | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE | WS_GROUP CONTROL "X", 115, 172, 96, 32, 8, WC_STATIC, SS_TEXT | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE CONTROL "Size & Position", 116, 163, 48, 129, 72, WC_STATIC, SS_GROUPBOX | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE | WS_GROUP CONTROL "Y", 117, 238, 96, 32, 8, WC_STATIC, SS_TEXT | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE CONTROL "Width", 118, 172, 72, 45, 8, WC_STATIC, SS_TEXT | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE CONTROL "Height", 119, 236, 72, 45, 8, WC_STATIC, SS_TEXT | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE CONTROL "Comment", 120, 10, 20, 282, 28, WC_STATIC, SS_GROUPBOX | DT_LEFT | DT_TOP | DT_MNEMONIC | WS_VISIBLE | WS_GROUP DEFPUSHBUTTON "OK", DID_OK, 6, 4, 51, 14 PUSHBUTTON "Cancel", DID_CANCEL, 60, 4, 51, 14 PUSHBUTTON "Help", 998, 114, 4, 51, 14, BS_HELP END END Output
Fonts, Icons, Pointers, and BitmapsSyntax| +-------+ | | FONT | BITMAP | POINTER | | | +-------+ | IDENTIFIER | +----+ | | | MEMORY | OPTIONS | | +----+ | FILENAME | | - NotesFonts, icons, pointers and bitmaps are all treated in the same way. (In fact icons and pointers are more or less identical). They are all defined externally in their own binary file, and are bound in when the resources are compiled. There are editors available to design your own binary resources. An Icon Editor (also used for pointers and small bitmaps) is included in base OS/2, and there is a Font Editor in the Toolkit. ExampleBITMAP IDB_SMILEY Smiley.Bmp ICON IDI_MYPROG Whiz.Ico FONT IDF_BIGFONT Large.Fnt Output<Insert your favourite graphic here> RoundupWell, there you have Resources in a nutshell. You will find that tools such as Borland's Resource Workshop and those included with IBM's Toolkit can save you from ever having to understand all that we have just discussed, as you can point and click and the work is done for you. However, it is very useful to know just how resources are created as it gives you a better understanding of just what you are doing. Now for those of you who have eagerly gone to consult your manuals (or the header files for that matter), you will have noticed that I left out a few resource types. I did this to save both time and space, and also because they are infrequently used. I won't dare say that it is left as an excercise for the reader, but if there is enough demand I will cover the remaining types in a later article. What Next?Next we look at the Graphics Programming Interface (GPI). I would love to hear from you about what you thought, how useful it was, whether or not there was too much or not enough information, if it was too wordy or too simple - in short any and all comments are most welcome. Also, if there is something specific you would like to see covered, drop me a line too. BibliographyThe following references were used in the preparation of this article:
The following products were mentioned:
|