home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR4
/
V12N15.ZIP
/
DEMODL.ZIP
/
DEMODLL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-04
|
9KB
|
243 lines
// DEMODLL.C - Demonstrate use of WINHELP internal functions
// and access to "baggage" files within a Windows HLP file.
// Copyright (C) 1993 Ray Duncan
// PC Magazine * Ziff Davis Publishing
#include <windows.h>
#include <commdlg.h>
#include "dll.h"
#include "demodll.h"
#define READSIZE 32768 // size of I/O buffer
#define EXENAMESIZE 256 // max size of pathname
// far pointers to WINHELP internal functions
LPFN_HFSOPENSZ lpfnHfsOpenSz; // open HLP file system
LPFN_RCCLOSEHFS lpfnRcCloseHfs; // close HLP file system
LPFN_FACCESSHFS lpfnFAccessHfs; // check baggage file
LPFN_HFOPENHFS lpfnHfOpenHfs; // open baggage file
LPFN_LCBREADHF lpfnLcbReadHf; // read baggage file
LPFN_RCCLOSEHF lpfnRcCloseHf; // close baggage file
//
// LibMain() -- initialization routine called by system loader (via
// LibEntry) when DLL is first loaded. Called with the module handle
// for the DLL, the size of the local heap, and a pointer to the
// command line. Returns TRUE if DLL initialization successful,
// FALSE if initialization failed.
//
INT CALLBACK LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeap, LPSTR lpchCmdLine)
{
if (cbHeap) // unlock data segment
UnlockData(0); // if DLL has its own
// local heap
return(TRUE);
}
//
// WEP - termination routine called by system just before the
// DLL is unloaded from memory. The parameter idParam is not used.
// The routine always returns TRUE.
//
INT CALLBACK WEP(INT idParam)
{
return(TRUE);
}
//
// LDLLHandler() -- Callback entry point from WINHELP.EXE. Called
// with DW_WHATMSG the first time a macro within the DLL is run from
// the HLP file. The routine will be called additional times with
// other messages depending on what flags were returned by this
// routine in response to the DW_WHATMSG message.
//
LONG CALLBACK LDLLHandler(WORD wMsg, LONG lParam1, LONG lParam2)
{
switch(wMsg)
{
case DW_WHATMSG: // we only want the
return(DC_CALLBACKS); // DW_CALLBACKS message
case DW_CALLBACKS: // save entry points
GetCallBacks((VPTR) lParam1);
return(TRUE);
}
return(FALSE);
}
//
// GetCallBacks -- called from LDLLHandler in response to the
// DW_CALLBACKS message. Extracts the addresses of the WINHELP
// entry points for the functions that will be used by
// CopyBaggage from the far pointer array whose address was
// passed to LDLLHandler, and saves the addresses in
// global variables.
//
VOID GetCallBacks(VPTR VPtr)
{
lpfnHfsOpenSz = (LPFN_HFSOPENSZ) VPtr[HE_HfsOpenSz];
lpfnRcCloseHfs = (LPFN_RCCLOSEHFS) VPtr[HE_RcCloseHfs];
lpfnFAccessHfs = (LPFN_FACCESSHFS) VPtr[HE_FAccessHfs];
lpfnHfOpenHfs = (LPFN_HFOPENHFS) VPtr[HE_HfOpenHfs];
lpfnLcbReadHf = (LPFN_LCBREADHF) VPtr[HE_LcbReadHf];
lpfnRcCloseHf = (LPFN_RCCLOSEHF) VPtr[HE_RcCloseHf];
return;
}
//
// CopyBaggage() -- called as a "macro" from within a HLP file
// to copy a baggage file from the HLP file's internal file system
// to an ordinary DOS file. Arguments are the name of the HLP
// file, the name of the baggage file, the default name for the
// DOS file, the address of the Help error structure, and two
// flags that control display of the SaveAs and advisory dialogs.
// Returns TRUE if the copy was successful, FALSE otherwise.
//
BOOL CALLBACK CopyBaggage(LPSTR szHelpFile, LPSTR szSourceFile,
LPSTR szDefaultDest, QME lpHelpError, UINT fSaveAs, UINT fAlert)
{
BOOL fStatus; // operation status
HANDLE hHelpFile = 0; // HLP file handle
HANDLE hSourceFile = 0; // baggage file handle
HFILE hDestFile = -1; // output file handle
UINT ReadLen, WriteLen; // bytes read, written
HGLOBAL hBuffer = 0; // I/O buffer handle
LPBYTE lpBuffer; // I/O buffer pointer
OPENFILENAME ofn; // used by common dialog
OFSTRUCT ofs; // used by OpenFile
CHAR szDestFile[EXENAMESIZE]; // destination filename
CHAR szTemp[256]; // scratch buffer
// set default error result and error action
lpHelpError->wError == wMERR_NONE;
lpHelpError->fwFlags = fwMERR_ABORT;
// retrieve default destination filename
lstrcpy(szDestFile, szDefaultDest);
// try and open HLP file, exit if unsuccessful
hHelpFile = (*lpfnHfsOpenSz)(szHelpFile, fFSOpenReadOnly);
if(!hHelpFile)
goto CopyError;
// check if source file exists within HLP file system
fStatus = (*lpfnFAccessHfs)(hHelpFile, szSourceFile, NULL);
if(!fStatus)
goto CopyError;
// try and open the source file for I/O
hSourceFile = (*lpfnHfOpenHfs)(hHelpFile, szSourceFile, fFSOpenReadOnly);
if(!hSourceFile)
goto CopyError;
if(fSaveAs) // use Save-As dialog?
{
// initialize the data structure used by the common Save-As
// dialog, then prompt the user for the destination filename,
// using the filename passed as szDefaultDest as the default
ofn.lStructSize = sizeof(OPENFILENAME); // length of structure
ofn.hwndOwner = NULL; // handle of owner window
ofn.lpstrFilter = NULL; // address of filter list
ofn.lpstrCustomFilter = NULL; // custom filter address
ofn.nFilterIndex = 1L; // ignored for now
ofn.lpstrFile = szDestFile; // buffer for pathname
ofn.nMaxFile = EXENAMESIZE; // size of buffer
ofn.lpstrFileTitle = NULL; // buffer for filename only
ofn.lpstrInitialDir = NULL; // initial directory
ofn.lpstrTitle = NULL; // title for dialog box
ofn.Flags = OFN_PATHMUSTEXIST | // various dialog flags
OFN_HIDEREADONLY | OFN_NOTESTFILECREATE;
ofn.lpstrDefExt = NULL; // default extension
if(!GetSaveFileName(&ofn)) // display save-as dialog
goto CopyError; // exit if user canceled
}
// allocate memory for use as an I/O buffer
hBuffer = GlobalAlloc(GMEM_MOVEABLE, READSIZE);
if(!hBuffer)
goto CopyError;
// get far pointer to the I/O buffer
lpBuffer = GlobalLock(hBuffer);
// create the destination file
hDestFile = _lcreat(szDestFile, 0);
if(hDestFile == HFILE_ERROR)
goto CopyError;
// copy the data from the HLP file system to the
// newly created destination file
do {
ReadLen = (*lpfnLcbReadHf)(hSourceFile, lpBuffer, READSIZE);
WriteLen = _lwrite(hDestFile, lpBuffer, ReadLen);
if(ReadLen != WriteLen)
goto CopyError;
} while(ReadLen == READSIZE);
// close all files, release I/O buffer
(*lpfnRcCloseHf)(hSourceFile);
(*lpfnRcCloseHfs)(hHelpFile);
_lclose(hDestFile);
GlobalUnlock(hBuffer);
GlobalFree(hBuffer);
if(fAlert) // display alert?
{
// notify user of the successful file transfer
wsprintf(szTemp, "Baggage file %s\nfrom help file %s\n"
"was copied to %s.",
(LPSTR) szSourceFile, (LPSTR) szHelpFile,
(LPSTR) szDestFile);
strlwr(szTemp);
MessageBox(NULL, szTemp, "DEMODLL", MB_OK);
}
// return success flag to WINHELP.EXE
return(wMERR_NONE);
CopyError: // common error exit
// close any files that were opened, kill
// partial output file if necessary
if(hHelpFile)
(*lpfnRcCloseHfs)(hHelpFile);
if(hSourceFile)
(*lpfnRcCloseHf)(hSourceFile);
if(hDestFile != -1)
{
_lclose(hDestFile);
OpenFile(szDestFile, &ofs, OF_DELETE);
}
// release I/O buffer if it was allocated
if(hBuffer)
{
GlobalUnlock(hBuffer);
GlobalFree(hBuffer);
}
// display alert?
if(fAlert)
{
// notify user of the unsuccessful operation
wsprintf(szTemp, "Baggage file %s\nfrom help file %s\n"
"could not be copied.",
(LPSTR) szSourceFile, (LPSTR) szHelpFile);
strlwr(szTemp);
MessageBox(NULL, szTemp, "DEMODLL", MB_OK);
}
// set error code, return error flag to WINHELP.EXE
lpHelpError->wError = wMERR_ERROR;
return(wMERR_ERROR);
}