[ Next ] [ Previous ] | Chapter 12 |
Although resources such as CPU rime and memory in the traditional sense
are viewed as "things" that need so be shared, the term has a different
meaning in a GUI environment. In a Presentation Manager environment
resources
are viewed as items that are necessary for the user interface of an
application
but nor part of the application code itself.
So, why does this book contain a chapter dedicated
to resources if they aren't code-related? The operative phrase in the
preceding
paragraph is "necessary for the user interface." Resources are not
something
that can be done without. Instead, programmers will spend a large
amount
of time on "developing" resources, since they define the look of the
resulting
application (though not its operation).
This chapter discusses the following types of
resources,
what they are, and how they are used within an application: pointers,
icons,
bitmaps, string tables, accelerator tables, and application defined
resources.
Help tables, dialog boxes, and menus are also resources that are
discussed
briefly. with cross-references to chapters on these topics provided.
Fonts,
which are the other resource type defined, will not be discussed
because
their use requires a detailed look as the Graphics Programming
Interface
(GPI), which It a hock in itself.
In an orchestra, there are the musicians, the conductor, and the seating arrangement, which allows the conductor to know exactly where everything can be found. In this chapter, we will look the analogous parts in a PM application:
The resources are the actual user interface items that are used by the application - pointers, menus, and so on; as in an orchestra, without the resources themselves, the rest is pointless. The application coordinates the use of the resources to get a meaningful result: is wouldn't make sense, for example, to show an "Open" dialog when the user requested that the document should be printed. The resource file is where the compiler is instructed which resources the application will use; these resources, as we will show, are appended to the executable in a separate area (called resource segments ), which are analogous to the seats in the orchestra section.
Table 12.1 shows the types of resources, defined by OS/2, that we
look
at this chapter
Resource | Description |
Pointer | Pointer or icon data |
Bitmap | Bitmap data |
String table | Table of strings |
Accelerator table | Table of "shortcut" keys |
Menu | Menu description |
Dialog | Dialog description |
Font | Font description |
Help table | Table of frame windows and dialogs for which online help is to be provided |
Help subtable | Table of windows within a frame window or dialog for which online help is to be provided |
User data | Data in an application-specific format |
All resources are defined using resource identifiers, numeric constants that, together with the type of the resource being referenced, uniquely identify each resource in an application. A resource is said to be loaded when an application needs to use it for the first time; this loading of the resource results in a handle that the application uses when it calls a Presentation Manager function.
But before we can look at the resources themselves, we must first look
at the place in which they are specified and the compiler used to
append
them to the executable. The resource file usually has a main file with
the extension .RC, and this file usually includes one or more
dialog
definition files with the extension .DLG. The resource file can
include C header files using the #include keyword and also can
include
comments according to the C++ standard (i.e., using "/*" and "*/" or
using
"//"). Where a construct requires a BEGIN and END keywords, the symbols
"{" and "}" also may be used.
Dialog files are included in a funny manner: The main file uses the
keyword DLGINCLUDE to specify that dialog file is to be included.
DLGINCLUDE resid filename
resid specifies the resource identifier of the file (!) and filename is the name of the file to be included. The original intent was that each dialog definition would go in a separate file and all of the files would be included by the main file.
![]() |
Gotcha!
Because the original purpose of the dialog file is as described, each DLGINCLUDE statement must have a unique resource identifier. It is not necessary, however, to limit each dialog file to having a single dialog box definition. |
Now that a resource file is defined, it needs to be compiled into a
.RES
file. This is accomplished using the resource compiler
(RC.EXE).
The compiler comes with the base operating system and can be found in
the
\OS2 directory. It also comes with the Programmer's Toolkit, Visual Age
C++ and Watcom compilers. It supports the command-line options
listed
in Table 12.2.
Option | Description |
-d defname -Ddefname |
Preprocessor define - Defines a macro and optionally a value |
-i | Include file path - specifies a path to include when searching files |
-r | Create .res file - Do not attach the compiled .RES file to the .EXE or .DLL |
-p | Pack - 386 resources will not cross 64K boundaries |
-x[1|2] | Exepack - Compress resources, using method 1 or 2 |
-cc cc | Country code |
-cp cp | lb,tb,... | DBCS codepage or lead/trail byte info. |
-n | Don't show logo |
-w2 | Suppress warnings |
-? -h |
Access Help |
To compile a resource file, MYAPP.RC, to a .RES file without attaching MYAPP.RES to MYAPPS.EXE, compressing resources, and using "." as a directory to search, the following code would be entered:
RC -R -X1 -I. MYAPP.RC
Pointers and icons are defined and accessed in the same manner. This isn't coincidence; with the exception of the first two bytes in the file containing the actual data, the two are identical. Both resources are defined in the resource file in the following manner:
POINTER resid filename
resid is the resource identifier of the pointer or icon, and filename
is the name of the file containing the pointer or icon data. These
files
are created using the "icon editor" utility (ICONEDIT.EXE), which is
provided
by OS/2 and also can be found as part of the Programmer's Toolkit. For
help on using the icon editor, programmers should refer to the online
documentation.
In a program, both are loaded using the WinLoadPointer
function.
HPOINTER APIENTRY WinLoadPointer(HWND hwndDesktop,
HMODULE hmod,
ULONG idres);
hwndDesktop is the desktop window handle, for which HWND_DESKTOP can he specified. hmDll is the handle to a DLL that was loaded with DosLoadModule or WinLoadLibrary to which the resource is attached. If the resources are appended to the executable, then NULLHANDLE should he used for this parameter. ulId is the resource identifier of the pointer or icon to he loaded. This function returns a handle to the pointer or icon that was loaded, which is used in subsequent functions that act upon pointers or icons.
Once a pointer or icon is loaded, it can be drawn in a window with WinDrawPointer function.
BOOL APIENTRY WinDrawPointer(HPS hpsWnd,
LONG lX,
LONG lY,
HPOINTER hpPointer,
ULONG ulFlags);
hpsWnd is a handle to the presentation space in which the
pointer
or icon is to be drawn. lX and lY specify the position
within
the presentation space where the pointer or icon is to be drawn. hpPointer
specifies the handle of the pointer or icon that is to be drawn.
ulFlags
specifies
how the pointer or icon is to be drawn, and is one of the constants
listed
in Table 12.3.
Constant | Description |
DP_NORMAL | Draw the pointer or icon in the "normal" manner. |
DP_HALFTONED | Draw the pointer or icon in a halftone manner. |
DP_INVERTED | Draw the pointer or icon in color-inverted state. |
DP_MINI | 0x0004 /* Feature:85493 */ (???) |
This function returns a flag indicating success or failure.
The WinDrawPointer function is useful for drawing
an icon in a window, but it cannot be used to set the mouse pointer to
anything. To accomplish this, we instead need the WinSetPointer
function.
BOOL APIENTRY WinSetPointer(HWND hwndDesktop,
HPOINTER hptrNew);
hwndDesktop is the handle to the desktop; again, the HWND_DESKTOP constant for this can be specified. hptrNew is the handle to the pointer to which one wishes the mouse pointer to change. This function also returns a flag indicating success or failure.
![]() |
Gotcha!
Just because the mouse is set to a specified pointer doesn't mean that something else cannot set it to something else. In fact. WinDefWindowProc will set the pointer to the arrow pointer within its processing for the WM_MOUSEMOVE message. Typically, the application would intercept the WM_MOUSEMOVE message and call WinSetPointer at that point to change the mouse pointer and not call WinDefWindowProc. |
In addition to any user-drawn pointers or icons, Presentation Manager defines a number of "system pointers": the arrow pointer, the waiting pointer, and some icons that have been discussed come from here. These pointers and icons can be accessed or reloaded using the WinQuerySysPointer function.
HPOINTER APIENTRY WinQuerySysPointer(HWND hwndDesktop,
LONG lptr,
BOOL bLoad);
hwndDesktop is the desktop handle (HWND_DESKTOP). lPtr
specifies
which system pointer or icon one wishes to access or load. It is one of
the constants found in Table 12.4.
Constant | Description |
SPTR_APPICON | Default icon for a PM application |
SPTR_ARROW | Arrow pointer |
SPTR_FILE | File icon |
SPTR_FOLDER | Folder icon |
SPTR_ICONERROR | Error icon |
SPTR_ICONINFORMATION | Information icon |
SPTR_ICONQUESTION | Query icon |
SPTR_ICONWARNING | Warning icon |
SPTR_ILLEGAL | Illegal action icon |
SPTR_MOVE | Move icon |
SPTR_MULTFILE | Multiple object icon |
SPTR_PROGRAM | Executable object icon |
SPTR_SIZE | Sizing pointer |
SPTR_SIZENESW | Sizing pointer from upper right to lower left |
SPTR_SIZENWSE | Sizing pointer from upper left to lower right |
SPTR_SIZENS | Vertical sizing pointer |
SPTR_SIZEWE | Horizontal sizing pointer |
SPTR_SIZETEXT | Text "I-beam" pointer |
SPTR_WAIT | Waiting pointer |
bLoad specifies whether the handle to the pointer that the system loaded during its initialization should be returned or whether the pointer should be loaded again and a new handle returned. To make modifications to the pointer for use within your application, bLoad should be specified TRUE. This function returns a handle to the specified pointer or to a copy of the specified pointer, depending on the value of bLoad.
Pointers and icons that were loaded explicitly by an application are destroyed using the WinDestroyPointer function.
BOOL APIENTRY WinDestroyPointer(HPOINTER hpPointer);
hpPointer specifies the handle of the pointer or icon to be destroyed. This function returns a flag indicating success or failure.
Bitmaps are similar to their cousins, pointers and icons. However, pointers and icons are of a fixed size, defined by Presentation Manager and cannot be any bigger or smaller. Bitmaps do not have this restriction;they do not have a "transparency" color, though, which is something that pointers and icons do have. Bitmaps in general have many uses - no blanket statement describes their usual purpose in an application.
The manner in which a bitmap is specified within a resource file is like that of the pointer and icon.
BITMAP resid filename
This causes the bitmap file with the specified name, filename,
to
be included in the resource tables and be assigned the specified
resource
id, resid.
Bitmaps are loaded with the GpiLoadBitmap function.
HBITMAP APIENTRY GpiLoadBitmap(HPS hpsWnd,
HMODULE hmDll,
ULONG idBitmap,
LONG lWidth,
LONG lHeight);
hpsWnd is a handle to the presentation space that is used to
load
the bitmap; this parameter is complex and will not be discussed. hmDll
is a handle to a DLL that contains the resources, if this is the case.
Again, if the resource is appended to the executable, NULLHANDLE should
be specified. idBitmap is the resource identifier of the bitmap
to be loaded. lWidth and lHeight are the width and
height
to which the bitmap should be stretched, if this is desired. Specifying
0 for both of these parameters specifies that the bitmap should
be
kept at its original size. This function returns a handle to the bitmap
loaded.
Drawing a bitmap is accomplished in one of many ways. We will look
at the simplest of these, which is to use the WinDrawBitmap function.
Like WinDrawPointer, this will draw a bitmap into a
presentation
space that is associated with a window.
BOOL APIENTRY WinDrawBitmap(HPS hpsWnd,
HBITMAP hbmBitmap,
PRECTL prclSrc,
PPOINTL pptlDst,
LONG clrFore,
LONG clrBack,
ULONG ulFlags);
hpsWnd is, again, a handle to a presentation space in which the
bitmap will be drawn. hbmBitmap is a handle to the bitmap to be
drawn. prclSrc points to a RECTL structure that defines the
portion
of the bitmap to be drawn. If NULLHANDLE is specified, the entire
bitmap
is drawn. pptlDst specifies the point corresponding to where
the
lower left corner of the bitmap is to be in the presentation space.
clrFore and clrBack are the foreground and
background
colors and are used for monochrome bitmaps only. ulFlags specifies
how the bitmap is to be drawn and can be one of the constants depicted
in Table 12.5
Constant | Description |
DBM_NORMAL | Draw the bitmap in a "normal" fashion. |
DBM_INVERT | Draw the bitmap in a color-inverted state. |
DBM_HALFTONE | Draw the bitmap in a halftone manner. |
DBM_STRETCH | Draw the bitmap stretched to fit prclSrc. |
DBM_IMAGEATTRS | Draw the (monochrome) bitmap using the current foreground and background colors of the presentation space. clrFore and clrBack are ignored if this is specified. |
This function returns a flag indicating its success or failure.
We've used the word "monochrome" twice, so it is helpful to be able to determine what the parameters are that were used to create the bitmap. This is done with the GpiQueryBitmapInfoHeader function
BOOL APIENTRY GpiQueryBitmapInfoHeader(HBITMAP hbmBitmap,
PBITMAPINFOHEADER2 pbmpData);
hbmBitmap is a handle to the bitmap in which the programmer is interested. pbmpData points to a very interesting structure - BITMAPINFOHEADER2.
typedef struct
_BITMAPINFOHEADER2
/* bmp2 */
{
ULONG
cbFix;
/* Length of
structure
*/
ULONG
cx;
/* Bit-map width in
pels
*/
ULONG
cy;
/* Bit-map height in
pels
*/
USHORT
cPlanes;
/* Number of bit
planes
*/
USHORT
cBitCount;
/* Number of bits per pel within a plane */
ULONG ulCompression; /*
Compression
scheme used to store the bitmap */
ULONG
cbImage;
/* Length of bit-map storage data in bytes*/
ULONG cxResolution;
/* x resolution of target
device
*/
ULONG cyResolution;
/* y resolution of target
device
*/
ULONG
cclrUsed;
/* Number of color indices
used
*/
ULONG cclrImportant; /* Number
of important color indices */
USHORT
usUnits;
/* Units of
measure
*/
USHORT usReserved;
/*
Reserved
*/
USHORT usRecording;
/* Recording
algorithm
*/
USHORT usRendering;
/* Halftoning
algorithm
*/
ULONG
cSize1;
/* Size value
1
*/
ULONG
cSize2;
/* Size value
2
*/
ULONG ulColorEncoding; /* Color
encoding
*/
ULONG ulIdentifier;
/* Reserved for application
use
*/
} BITMAPINFOHEADER2;
typedef BITMAPINFOHEADER2 *PBITMAPINFOHEADER2;
The GpiQueryBitmapInfoHeader function returns
a flag indicating success or failure of the function..
In OS/2 versions l.x. this structure was called BITMAPINFOHEADER
and contained only the first five fields. In the current structure, PM
developers have enabled programmers to have much more control over the
creation of a bitmap (or, in this situation, much mow information about
a bitmap). However, they also realized that programmers probably still
will use only the first five fields. So, the Gpi requires only
that
programmers initialize all fields up to the last one they are
interested
in and that they specify the number of bytes initialized in the cbFix
field;
and if the parameters of an existing bitmap are being queried, only cbFix
needs to be initialized to specify how many bytes need to be returned.
Thus, if cbFix has the value 16. only the first five
fields
(sizeof(cbFix) + sizeof(cx) + sizeof(cy) + sizeof(cPlanes)
+ sizeof(cBitCount) = 16) would be provided, but any value that
makes sense, up to the size of the structure, can be specified. Before
GpiQueryBitmapInfoHeader is called,
cbFix should be
initialized to specify bow much information should be returned.
![]() |
Gotcha! Initializing cbFix to the proper value is a must when calling the GpiQueryBitmapInfoHeader function, or unpredictable information will be returned. |
cx and cy specify the width and height of the bitmap.
cPlanes
specifies the number of color planes used by the bitmap; while OS/2
supports
multiplane bitmaps, the APIs to draw bitmaps support only single-plane
bitmaps. cBitCount specifies the number of bits it takes to
represent
one pel in the bitmap and can have a value 1, 2, 4, 8, or 24; if the
value
is 1, it is a monochrome bitmap, since it can base only 21
colors.
ulCompression specifies the compression scheme used to compress
the
bitmap in memory and can be one of the values listed in Table 12.7.
Constant | Description |
BCA_UNCOMP | Uncompressed |
BCA_HUFFMAN1D | Huffman encoding scheme |
BCA_RLE4 | Run-length encoding for 4 bit-per-pel (BPP) bitmaps |
BCA_RLE8 | Run-length encoding for 8 BPP bitmaps |
BCA_RLE24 | Run-length encoding for 24 BPP bitmaps |
cbImage specifies how much memory is needed to store the bitmap data. cxResolution and cyResolution specify the resolution of the device for which the bitmap was intended to be displayed upon. This does not prohibit the bitmap from being displayed on another display type; it merely indicates the display type for which the bitmap was drawn. cclrUsed, cclrImportant, ulRecording, ulRendering, cSizel, cSize2, and ulColorEncoding all specify additional data as described in structure's comments and are beyond the scope of this text.
Bitmaps are destroyed using the GpiDeleteBitmap function.
BOOL APIENTRY GpiDeleteBitmap(HBITMAP hbmBitmap);
hbmBitmap specifies the handle to the bitmap to be deleted. This function returns a flag indicating the success or failure of the function.
String tables are very simple in concept and implementation. They age lookup tables where the application provides the resource identifier of a string and Presentation Manager provides the corresponding text that was defined in the resource file. The purpose of a string table is to allow easy translation of an application to other languages, providing all of the "user-readable" text is placed into a string table. "User-readable" in this sense means text that the user sees; window class names would not be included in this group, but messages would be.
Unlike all other resources, string tables do not have a resource identifier explicitly assigned to them by the programmer. Instead, the resource compiler breaks up the string table into groups of 16 strings and automatically assigns an identifier to each 16- string group. A string table has the following form in a resource file.
STRINGTABLE
{ resid1, "string1"
rasid2, "string2"'
rasid3, "string3"'
}
As was stated earlier and is now obvious, a string table is simply that - a table of strings. Each string has a unique identifier associated with it, which is specified on the call to WinLoadString which loads a string from the string table.
LONG APIENTRY WinLoadString(HAB habAnchor,
HMODULE hmDll,
ULONG ulId,
LONG lSzBuffer,
PCSZ pchBuffer);
habAnchor is the handle to the anchor block of the calling thread. hmDll is the handle to the DLL where the string table resides, or NULLHANDLE if it resides in the executable's resource tables. ulId is the identifier of the string to be loaded. lSzBuffer specifies the size of the buffer pointed to by pchBuffer. This function returns the number of characters loaded from the string table, up to a maximum of lSzBuffer - 1.
That's all there is to it!
Accelerators are "shortcut" keys that accelerate the rate at which a
user
is able to complete certain tasks within an application. The
accelerator
table defines a translation from a keystroke, modified by the Alt,
Ctrl,
or Shift keys if specified, to a numeric identifier that is sent to the
application via the WM_COMMAND message.
The accelerator table has the following form.
ACCELTABLE resid
{
key, cmd_id, type [, modifiers ]
key, cmd_id, type [, modifiers ]
key, cmd_id, type [, modifiers ]
}
resid is the resource identifier for the accelerator table, key
is
the base key for the accelerator and can be a VK_ constant (e.g. VK_F1)
or a character in quotes. cmd_id is the numeric identifier to
be
sent as SHORT1FROMMP(mpParm1) in the WM_COMMAND message. type
is the type of character and must be CHAR or VIRTUALKEY. modifiers
are optional and can be one or more of those listed in Table
12.8,
separated by commas.
Modifier | Description |
CONTROL | Ctrl key must be pressed. |
ALT | Alt key must be pressed. |
SHIFT | Shift key must be pressed. |
![]() |
Gotcha! If a character (instead of a virtual key) is specified (or an accelerator, it is case-sensitive, so two entries must he provided to cover both possibilities of the shift key stale (unless each case should have different meanings, of course). |
ACCELTABLE RES_CLIENT
{ "^O", MI_OPEN
"^o", MI_OPEN
}
Accelerator tables usually are associated with standard windows through the use of it FCF_ACCELTABLE frame control flag. However, an accelerator table can be loaded explicitly with WinLoadAccelTable function.
HACCEL APIENTRY WinLoadAccelTable(HAB habAnchor,
HMODULE hmDll
ULONG idAccelTable);
habAnchor is the handle to the anchor block of the calling
thread.
hmDll
is the handle to the DLI if the accelerator table resides there,
or
to NULLHANDLE if is in the executable's resource tables. idAccelTable
is the resource identifier of the accelerator table. This function
returns
a handle to the loaded accelerator table.
After an accelerator table is loaded, is can be made active with the
WinSetAccelTable
function.
BOOL APIENTRY WinSetAccelTable(HAB habAnchor,
HACCEL haAccel,
HWND hwndFrame);
habAnchor is the handle to the anchor block of the calling thread. haAccel is the handle to the accelerator table o be made active. hwndFrame is the handle to the frame window to which the accelerator table attached. This function returns a flag indicating success or failure.
For each message queue, there are certain "standard" accelerators
that
are defined, such as Alt+F4 to close a frame window. These are called
"queue
accelerators," since they are in effect for the entire message queue
and
are independent of the active window. If hwndFrame in the call
to
WinSetAccelTable
is NULLHANDLE, the accelerator table replaces the queue accelerator
table.
Accelerator tables are destroyed with the WinDestroyAccelTable
function.
BOOL APIENTRY WinDestroyAccelTable(HACCEL haAccel);
This function destroys the accelerator table whose handle is specified
in haAccel and returns a flag indicating success or failure.
Dialog boxes are complicated beasts, but their use is simplified greatly through the use of the "dialog box" editor DLGEDIT.EXE (as well as through the use of resource editor URE named IRE in VisualAge C++ 4) A dialog box is described in a resource file using the dialog template. This template consists of three parts:
The nice thing is that the dialog box editor will create the template
for
the programmer; all he or she needs to do is build the dialog box using
its WYSIWYG interface. When the work is saved in the dialog box editor,
a dialog file (.DLG) is generated, containing the dialog templates
corresponding
to the dialog boxes that the programmer designed.
However, it is nice to know how to make minor adjustments manually,
so let us look briefly at the format of of the dialog template.
DLGTEMPLATE resid
{
DIALOG "title text", resid, x, y, cx, cy, style, flags
[CTLDATA controldata]
[PRESPARAM presparam]
{ CONTROL "text", id, x, y, cx, cy, class, style
[CTLDATA controldata]
[PRESPARAM presparam]
}
}
![]() |
Gotcha! The resid on the DLGTEMPLATE and DIALOG statements must match, or the dialog will fail to load. Why the same constant must be specified twice is beyond our understanding. |
x,y, cx, and cy are the coordinates of the lower left corner and the size of the dialog or window, respectively. style is one or more style flags; since a dialog is really nothing more than a subclassed frame window, it can use the FS_ constants in addition to the WS_ constants. The child windows (CONTROL statement) can use the WS_. constants as well as the constants specific to their window class. class can be a WC_ constant or an application-defined class-registered prior to the loading of the dialog with WinRegisterClass - in double quotes.
The control data (CTLDATA statement) is used to initialize
the
dialog or the child window, as will be shown in later chapters. The presentation
parameters (PRESPARAM statement) define the appearance, such as the
font used, the foreground and background colors, and so on. See Chapter
9 for more information on setting presentation parameters.
It should be noted that the coordinates and size of the dialog and
the child windows are based on a different coordinate system; the units
are dialog units, which are based on the average character
width
of the system font for the resolution of the display. The
concept-went-awry
is that dialog units are supposed to be "display independent," meaning
that the dialog will occupy the same amount of physical space on
different
resolutions; however, most monitors (in 1995) do not report their pel
densities
properly, so this rarely works. WinMapDlgPoints can
be used to convert between dialog units and pels.
BOOL APIENTRY WinMapDlgPoints(HWND hwndDlg,
PPOINTL pptlPoints,
ULONG ulNumPoints,
BOOL bCalcWindowCoords);
hwndDlg is the handle to the dialog window. pptlPoints points to one or more POINTL structures to convert. ulNumPoints specifies how many structures pptlPoints points to. bCalcWindowCoords is TRUE if the programmer wants to convert to window coordinates from dialog coordinates or FALSE if the opposite is desired.
Menus are a familiar user-interface component to anyone who has used a Macintosh, Windows, OS/2 or some other GUI. Their definition in a resource file is also quite simple, for there are only three different parts: the main "MENU" keyword, submenu definitions, and menu item definitions.
MENU resid
{ SUBMENU "Text", submenu_id [,styles]
{ MENUITEM "Text", menuitem_id [,attributes]
MENUITEM "Text", menuitem_id [,attributes]
}
}
resid is the resource identifier of the menu, submenu_id and
menuitem_id
are unique identifiers of the submenus and menu items, respectively.
They
are used when communicating with the menu via the MM_ messages, styles
are one or more MIS_ constants that affect the entire submenu. attributes
are one or more MI_A constants that affect a specific menu item. Both styles
and attributes
optional.
See Chapter 14 for more information on
using menus.
Help tables are used to provide a linkage between the application's child windows (including menu items, which are child windows in an odd way) and the help panels which are defined by a help developer. As you will see in Chapter 29, there are two parts to this linkage: the HELPTABLE and the various HELPSUBTABLES. See that chapter for information on the resource file syntax and how online help is provided by an application.
Application-defined data is the general case for all resources. In facts all of the APIs discussed in this chapter for loading resources follow these instructions in the bowels of the Presentation Manager code. The OS/2 kernel provides two APIs for resource management that are used to load and unload a specific resource - DosGetResource and DosFreeResource .
APIRET APIENTRY DosGetResource(HMODULE hmDll,
ULONG ulType,
ULONG ulId,
PPVOID ppvData);APIRET APIENTRY DosFreeResource(PVOID pvData);
hmDll is the handle to the DLL where the resource resides, or
is
NULLHANDLE if it is found in the executable's resource tables. uIType
is an RT_ constant that specifies the type of the resource.
Constant | Description |
RT_POINTER | Pointer data |
RT_BITMAP | Bitmap data |
RT_MENU | Menu template |
RT_DIALOG | Dialog template |
RT_STRING | String table |
RT_FONTDIR | Font directory |
RT_FONT | Font data |
RT_ACCELTABLE | Accelerator table |
RT_RCDATA | Binary data |
RT_MESSAGE | Error message |
RT_DLGINCLUDE | File name for the DLGINCLUDE statement |
RT_HELPTABLE | Help table for Help Manager |
RT_HELPSUBTABLE | Help subtable for Help Manager |
ulId is the resource identifier to be loaded. ppvData is
a pointer to a pointer that is initialized by OS/2 to point to the
beginning
of the resource data. This pointer is specified on the call to DosFreeResource
to return the memory consumed to the system, since OS/2 allocates the
memory
for the programmer when DosGetResource is called.
In the resource file, application-defined data must reside in a
separate
file and is included via the RESOURCE keyword.
RESOURCE type resid filename
type and resid correspond to their definitions as described earlier, and filename is the name of the file where the resource data resides. It should be noted that application-defined resources must have a value for type of 256 or greater.
[ Next ] [ Previous ] | Chapter 12 |