If a DLL wants access to Viewer internal functions, its LDLLHandler function handles the DW_WHATMSG message by returning a DC_CALLBACKS flag. In DLLDEMO.C, the LDLLHandler function requests access as follows:
case DW_WHATMSG:
return DC_INITTERM | DC_CALLBACKS;
When it gets this flag, Viewer sends a DW_CALLBACKS message to the DLL. The lParam1 parameter is a long pointer to an array containing pointer to each of the 16 internal Viewer functions. The DLL.H file defines symbolic names for indexing each function in the array.
In processing the DW_CALLBACKS message, the LDLLHandler function calls a function named GetCallBacks to specify which functions it wants to access. GetCallbacks is defined as follows in DLLDEMO:
PUBLIC BOOL PASCAL EXPORT GetCallBacks(
VPTR VPtr,
LONG lVersion)
{
// hfs level:
lpfn_HfsOpenSz = VPtr[HE_HfsOpenSz];
lpfn_RcCloseHfs = VPtr[HE_RcCloseHfs];
lpfn_RcLLInfoFromHfs = VPtr[HE_RcLLInfoFromHfs];
// bag level routines
lpfn_FAccessHfs = VPtr[HE_FAccessHfs];
lpfn_HfOpenHfs = VPtr[HE_HfOpenHfs];
lpfn_LcbReadHf = (LPFN_LCBREADHF) VPtr[HE_LcbReadHf];
lpfn_RcCloseHf = VPtr[HE_RcCloseHf];
return TRUE;
}
The VPtr parameter in GetCallBacks is the lParam1 pointer passed by the DW_CALLBACKS message from Viewer. The GetCallbacks function gets pointers to the following Viewer internal functions, which it uses later in the example:
Function | What It Does |
HfsOpenSz | Opens the .MVB file system (the compound file containing the files internal to the title) |
RcCloseHfs | Closes the open .MVB file system |
RcLLInfoFromHfs | Maps a handle to the open .MVB file system (returned by HfsOpenSz) to low-level file information |
FAccessHfs | Determines whether or not a file within the .MVB file system is accessible |
HfOpenHfs | Opens a file within the .MVB file system |
LcbReadHf | Reads bytes from a file within the .MVB file system |
Important:
This sample code does not take multiple instances of Viewer into account. If more than one instance is started, the DLL receives different pointers to these callback functions—one pointer for each instance. You must keep track of which pointer is associated with each Viewer instance. One way to do this is to create an array associating the task with the callback pointer.