659 lines
18 KiB
C
659 lines
18 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1990 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOKEYSTATE
|
|||
|
#define NOSYSCOMMANDS
|
|||
|
#define NORASTEROPS
|
|||
|
#define NOSHOWWINDOW
|
|||
|
#define NOATOM
|
|||
|
#define NOCREATESTRUCT
|
|||
|
#define NODRAWTEXT
|
|||
|
#define NOMB
|
|||
|
#define NOMETAFILE
|
|||
|
#define NOWH
|
|||
|
#define NOWNDCLASS
|
|||
|
#define NOSOUND
|
|||
|
#define NOCOLOR
|
|||
|
#define NOSCROLL
|
|||
|
#define NOCOMM
|
|||
|
|
|||
|
#include <windows.h>
|
|||
|
#include "mw.h"
|
|||
|
#include "dlgdefs.h"
|
|||
|
#include "cmddefs.h"
|
|||
|
#include "machdefs.h"
|
|||
|
#include "docdefs.h"
|
|||
|
#include "propdefs.h"
|
|||
|
#include "printdef.h"
|
|||
|
#include "str.h"
|
|||
|
#include "fmtdefs.h"
|
|||
|
#include <commdlg.h>
|
|||
|
#include <cderr.h>
|
|||
|
#include <print.h>
|
|||
|
#include <stdlib.h>
|
|||
|
|
|||
|
extern CHAR (**hszPrinter)[];
|
|||
|
extern CHAR (**hszPrDriver)[];
|
|||
|
extern CHAR (**hszPrPort)[];
|
|||
|
extern BOOL vfPrDefault;
|
|||
|
|
|||
|
#ifdef JAPAN // added 08 Jun. 1992 by Hiraisi
|
|||
|
BOOL FAR PASCAL _export fnPrintHook( HWND, UINT, WPARAM, LPARAM );
|
|||
|
extern HANDLE hMmwModInstance;
|
|||
|
BOOL fWriting = FALSE;
|
|||
|
BOOL bWriting = FALSE;
|
|||
|
#endif //JAPAN
|
|||
|
|
|||
|
BOOL vbCollate = TRUE;
|
|||
|
|
|||
|
static void GetPrNames(BOOL bPrDialog);
|
|||
|
PRINTDLG PD = {0,0,0,0,0}; /* Common print dlg structure, initialized in the init code */
|
|||
|
|
|||
|
void PrinterSetupDlg(BOOL bGetDevmodeOnly /* not used */)
|
|||
|
{
|
|||
|
extern HWND vhWnd;
|
|||
|
BOOL bDevMode = PD.hDevMode ? TRUE : FALSE;
|
|||
|
|
|||
|
PD.Flags |= PD_PRINTSETUP;
|
|||
|
PD.Flags &= ~PD_RETURNDEFAULT;
|
|||
|
|
|||
|
if (vfPrDefault && !PD.hDevNames)
|
|||
|
if (PD.hDevMode)
|
|||
|
{
|
|||
|
/*
|
|||
|
So dlg will show that default is selected. Its a pity
|
|||
|
to do this because hDevMode is perfectly good. Alternative
|
|||
|
is to build a DevNames structure which we could do, but
|
|||
|
that would just allocate a new devmode anyways.
|
|||
|
*/
|
|||
|
GlobalFree(PD.hDevMode);
|
|||
|
PD.hDevMode = 0;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef JAPAN // added 08 Jun. 1992 by Hiraisi
|
|||
|
PD.hInstance = NULL;
|
|||
|
PD.lpPrintTemplateName = (LPCSTR)NULL;
|
|||
|
PD.Flags &= ~PD_ENABLEPRINTTEMPLATE;
|
|||
|
PD.Flags &= ~PD_ENABLEPRINTHOOK;
|
|||
|
#endif //JAPAN
|
|||
|
|
|||
|
TryPrnSetupAgain:
|
|||
|
if (!PrintDlg(&PD))
|
|||
|
{
|
|||
|
/* Bug #11531: When PrintDlg returns 0, it could me we gave it garbage in
|
|||
|
* the DevNames or DevMode structures, perhaps due to the user making
|
|||
|
* changes through Control Panel that we don't monitor. Clean out the
|
|||
|
* appropriate structure and try again. Note that these errors can't be
|
|||
|
* returned to us again after cleaning out the structure.
|
|||
|
* 23 August 1991 Clark R. Cyr
|
|||
|
*/
|
|||
|
switch (CommDlgExtendedError())
|
|||
|
{
|
|||
|
case PDERR_PRINTERNOTFOUND:
|
|||
|
case PDERR_DNDMMISMATCH:
|
|||
|
if (PD.hDevNames)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevNames);
|
|||
|
PD.hDevNames = 0;
|
|||
|
}
|
|||
|
|
|||
|
if (PD.hDevMode)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevMode);
|
|||
|
PD.hDevMode = 0;
|
|||
|
}
|
|||
|
goto TryPrnSetupAgain;
|
|||
|
|
|||
|
default:
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
PD.Flags &= ~PD_PRINTSETUP;
|
|||
|
|
|||
|
GetPrNames(FALSE); // this gets new PrinterDC
|
|||
|
|
|||
|
ResetFontTables();
|
|||
|
|
|||
|
#if defined(OLE)
|
|||
|
ObjSetTargetDevice(TRUE);
|
|||
|
#endif
|
|||
|
|
|||
|
InvalidateRect(vhWnd, (LPRECT)NULL, fFalse);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void fnPrPrinter(
|
|||
|
void)
|
|||
|
{
|
|||
|
/* This routine is the outside world's interface to the print code. */
|
|||
|
extern int docCur;
|
|||
|
extern int vfPrPages, vpgnBegin, vpgnEnd, vcCopies;
|
|||
|
extern WORD fPrintOnly;
|
|||
|
extern CHAR (**hszPrPort)[];
|
|||
|
HANDLE hPort=NULL;
|
|||
|
LPDEVNAMES lpDevNames;
|
|||
|
int Len3;
|
|||
|
char szPort[cchMaxFile];
|
|||
|
extern struct SEL selCur;
|
|||
|
BOOL bDevMode = PD.hDevMode ? TRUE : FALSE;
|
|||
|
#ifdef JAPAN // added 08 Jun. 1992 by Hiraisi
|
|||
|
FARPROC lpfnPrintHook;
|
|||
|
BOOL bReturn;
|
|||
|
#endif
|
|||
|
|
|||
|
PD.Flags &= ~(PD_RETURNDEFAULT|PD_PRINTSETUP|PD_SELECTION); /*turn off PRINTSETUP flag */
|
|||
|
if (vbCollate)
|
|||
|
PD.Flags |= PD_COLLATE;
|
|||
|
else
|
|||
|
PD.Flags &= ~PD_COLLATE;
|
|||
|
|
|||
|
if (selCur.cpFirst == selCur.cpLim) // no selection
|
|||
|
PD.Flags |= PD_NOSELECTION;
|
|||
|
else
|
|||
|
PD.Flags &= ~PD_NOSELECTION;
|
|||
|
|
|||
|
if (vfPrDefault && !PD.hDevNames)
|
|||
|
if (PD.hDevMode)
|
|||
|
{
|
|||
|
/*
|
|||
|
So dlg will show that default is selected. Its a pity
|
|||
|
to do this beause hDevMode is perfectly good. Alternative
|
|||
|
is to build a DevNames structure.
|
|||
|
*/
|
|||
|
GlobalFree(PD.hDevMode);
|
|||
|
PD.hDevMode = 0;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef JAPAN // added 08 Jun. 1992 by Hiraisi
|
|||
|
PD.hInstance = hMmwModInstance;
|
|||
|
PD.Flags |= PD_ENABLEPRINTTEMPLATE;
|
|||
|
PD.lpPrintTemplateName = (LPCSTR)MAKEINTRESOURCE( dlgPrint );
|
|||
|
PD.Flags |= PD_ENABLEPRINTHOOK;
|
|||
|
lpfnPrintHook = MakeProcInstance( fnPrintHook, hMmwModInstance );
|
|||
|
PD.lpfnPrintHook = (FARPROC)lpfnPrintHook;
|
|||
|
TryPrintAgain:
|
|||
|
bReturn = PrintDlg(&PD);
|
|||
|
FreeProcInstance( lpfnPrintHook );
|
|||
|
if (!bReturn)
|
|||
|
#else
|
|||
|
TryPrintAgain:
|
|||
|
if (!PrintDlg(&PD))
|
|||
|
#endif
|
|||
|
{
|
|||
|
switch (CommDlgExtendedError())
|
|||
|
{
|
|||
|
case PDERR_PRINTERNOTFOUND:
|
|||
|
case PDERR_DNDMMISMATCH:
|
|||
|
if (PD.hDevNames)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevNames);
|
|||
|
PD.hDevNames = 0;
|
|||
|
}
|
|||
|
|
|||
|
if (PD.hDevMode)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevMode);
|
|||
|
PD.hDevMode = 0;
|
|||
|
}
|
|||
|
goto TryPrintAgain;
|
|||
|
|
|||
|
default:
|
|||
|
if (!bDevMode && PD.hDevMode)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevMode);
|
|||
|
PD.hDevMode = 0;
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifdef JAPAN // added 08 Jun. 1992 by Hiraisi
|
|||
|
fWriting = bWriting;
|
|||
|
#endif
|
|||
|
|
|||
|
if (PD.Flags & PD_PAGENUMS) /* Page Range specified? */
|
|||
|
{
|
|||
|
vfPrPages = TRUE;
|
|||
|
if (PD.nFromPage)
|
|||
|
vpgnBegin = PD.nFromPage;
|
|||
|
if (PD.nToPage)
|
|||
|
vpgnEnd = PD.nToPage;
|
|||
|
if (vpgnEnd < vpgnBegin)
|
|||
|
{
|
|||
|
int temp = vpgnBegin;
|
|||
|
|
|||
|
vpgnBegin = vpgnEnd;
|
|||
|
vpgnEnd = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
else /* No, print all pages */
|
|||
|
vfPrPages = FALSE;
|
|||
|
|
|||
|
vcCopies = PD.nCopies;
|
|||
|
vbCollate = PD.Flags & PD_COLLATE;
|
|||
|
|
|||
|
GetPrNames(TRUE);
|
|||
|
|
|||
|
/** At this point, we have the following :
|
|||
|
|
|||
|
vfPrPages = true if print page range else print all pages
|
|||
|
vpgnBegin = starting page number (if vfPrPages)
|
|||
|
vpgnEnd = ending page number (if vfPrPages)
|
|||
|
vcCopies = number of copies to print
|
|||
|
vbCollate = whuddya think?
|
|||
|
**/
|
|||
|
|
|||
|
#if defined(OLE)
|
|||
|
ObjSetTargetDevice(TRUE);
|
|||
|
#endif
|
|||
|
|
|||
|
if (PD.Flags & PD_SELECTION)
|
|||
|
{
|
|||
|
int docTmp;
|
|||
|
BOOL bIssueError;
|
|||
|
extern WORD ferror;
|
|||
|
extern typeCP cpMinCur, cpMacCur, cpMinDocument;
|
|||
|
extern struct DOD (**hpdocdod)[];
|
|||
|
typeCP cpMinCurT = cpMinCur;
|
|||
|
typeCP cpMacCurT = cpMacCur;
|
|||
|
typeCP cpMinDocumentT = cpMinDocument;
|
|||
|
|
|||
|
docTmp = DocCreate(fnNil, HszCreate(""), dtyNormal);
|
|||
|
if (docTmp != docNil)
|
|||
|
{
|
|||
|
ClobberDoc( docTmp, docCur, selCur.cpFirst, selCur.cpLim-selCur.cpFirst );
|
|||
|
|
|||
|
if (!ferror)
|
|||
|
{
|
|||
|
cpMinCur = cp0;
|
|||
|
cpMacCur = (**hpdocdod) [docTmp].cpMac;
|
|||
|
PrintDoc(docTmp, TRUE);
|
|||
|
cpMinCur = cpMinCurT;
|
|||
|
cpMacCur = cpMacCurT;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
cpMinDocument = cpMinDocumentT; /* destroyed possibly by DocCreate */
|
|||
|
|
|||
|
bIssueError = ferror;
|
|||
|
|
|||
|
if (ferror)
|
|||
|
ferror = FALSE; // to enable the following:
|
|||
|
|
|||
|
if (docTmp != docNil)
|
|||
|
KillDoc (docTmp); // do this first to free memory to assist messagebox if necessary
|
|||
|
|
|||
|
if (bIssueError)
|
|||
|
Error(IDPMTPRFAIL);
|
|||
|
}
|
|||
|
else
|
|||
|
PrintDoc(docCur, TRUE);
|
|||
|
}
|
|||
|
|
|||
|
BOOL FInitHeaderFooter(fHeader, ppgn, phrgpld, pcpld)
|
|||
|
BOOL fHeader;
|
|||
|
unsigned *ppgn;
|
|||
|
struct PLD (***phrgpld)[];
|
|||
|
int *pcpld;
|
|||
|
{
|
|||
|
/* This routine initializes the array of print line descriptors used in
|
|||
|
positioning the header/footer on the printed page. FALSE is returned if an
|
|||
|
error occurs; TRUE otherwise. */
|
|||
|
|
|||
|
extern typeCP cpMinHeader;
|
|||
|
extern typeCP cpMacHeader;
|
|||
|
extern typeCP cpMinFooter;
|
|||
|
extern typeCP cpMacFooter;
|
|||
|
extern int docCur;
|
|||
|
extern struct PAP vpapAbs;
|
|||
|
extern struct SEP vsepAbs;
|
|||
|
extern int dxaPrOffset;
|
|||
|
extern int dyaPrOffset;
|
|||
|
extern int dxpPrPage;
|
|||
|
extern int dxaPrPage;
|
|||
|
extern int dypPrPage;
|
|||
|
extern int dyaPrPage;
|
|||
|
extern struct FLI vfli;
|
|||
|
extern int vfOutOfMemory;
|
|||
|
|
|||
|
typeCP cpMin;
|
|||
|
typeCP cpMac;
|
|||
|
|
|||
|
/* Get the cpMin and the cpMac for the header/footer. */
|
|||
|
if (fHeader)
|
|||
|
{
|
|||
|
cpMin = cpMinHeader;
|
|||
|
cpMac = cpMacHeader;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
cpMin = cpMinFooter;
|
|||
|
cpMac = cpMacFooter;
|
|||
|
}
|
|||
|
|
|||
|
/* Is there a header/footer. */
|
|||
|
if (cpMac - cpMin > ccpEol)
|
|||
|
{
|
|||
|
int cpld = 0;
|
|||
|
int cpldReal = 0;
|
|||
|
int cpldMax;
|
|||
|
int xp;
|
|||
|
int yp;
|
|||
|
int ichCp = 0;
|
|||
|
typeCP cpMacDoc = CpMacText(docCur);
|
|||
|
|
|||
|
/* Compute the page number of the start of the headers/footers. */
|
|||
|
CacheSect(docCur, cpMin);
|
|||
|
if ((*ppgn = vsepAbs.pgnStart) == pgnNil)
|
|||
|
{
|
|||
|
*ppgn = 1;
|
|||
|
}
|
|||
|
|
|||
|
/* Does the header/footer appear on the first page. */
|
|||
|
CachePara(docCur, cpMin);
|
|||
|
if (!(vpapAbs.rhc & RHC_fFirst))
|
|||
|
{
|
|||
|
(*ppgn)++;
|
|||
|
}
|
|||
|
|
|||
|
/* Calculate the bounds of the header/footer in pixels. */
|
|||
|
xp = MultDiv(vsepAbs.xaLeft - dxaPrOffset, dxpPrPage, dxaPrPage);
|
|||
|
yp = fHeader ? MultDiv(vsepAbs.yaRH1 - dyaPrOffset, dypPrPage,
|
|||
|
dyaPrPage) : 0;
|
|||
|
|
|||
|
/* Initialize the array of print line descriptors for the header/footer.
|
|||
|
*/
|
|||
|
if (FNoHeap(*phrgpld = (struct PLD (**)[])HAllocate((cpldMax = cpldRH) *
|
|||
|
cwPLD)))
|
|||
|
{
|
|||
|
*phrgpld = NULL;
|
|||
|
return (FALSE);
|
|||
|
}
|
|||
|
|
|||
|
/* We now have to calculate the array of print line descriptors for the
|
|||
|
header/footer. */
|
|||
|
cpMac -= ccpEol;
|
|||
|
while (cpMin < cpMac)
|
|||
|
{
|
|||
|
/* Format this line of the header/footer for the printer. */
|
|||
|
FormatLine(docCur, cpMin, ichCp, cpMacDoc, flmPrinting);
|
|||
|
|
|||
|
/* Bail out if an error occurred. */
|
|||
|
if (vfOutOfMemory)
|
|||
|
{
|
|||
|
return (FALSE);
|
|||
|
}
|
|||
|
|
|||
|
/* Is the array of print line descriptors big enough? */
|
|||
|
if (cpld >= cpldMax && !FChngSizeH(*phrgpld, (cpldMax += cpldRH) *
|
|||
|
cwPLD, FALSE))
|
|||
|
{
|
|||
|
return (FALSE);
|
|||
|
}
|
|||
|
|
|||
|
/* Fill the print line descriptor for this line. */
|
|||
|
{
|
|||
|
register struct PLD *ppld = &(***phrgpld)[cpld++];
|
|||
|
|
|||
|
ppld->cp = cpMin;
|
|||
|
ppld->ichCp = ichCp;
|
|||
|
ppld->rc.left = xp + vfli.xpLeft;
|
|||
|
ppld->rc.right = xp + vfli.xpReal;
|
|||
|
ppld->rc.top = yp;
|
|||
|
ppld->rc.bottom = yp + vfli.dypLine;
|
|||
|
}
|
|||
|
|
|||
|
/* Keep track of the non-blank lines in the header/footer */
|
|||
|
if ((vfli.ichReal > 0) || vfli.fGraphics)
|
|||
|
{
|
|||
|
cpldReal = cpld;
|
|||
|
}
|
|||
|
|
|||
|
/* Bump the counters. */
|
|||
|
cpMin = vfli.cpMac;
|
|||
|
ichCp = vfli.ichCpMac;
|
|||
|
yp += vfli.dypLine;
|
|||
|
}
|
|||
|
|
|||
|
/* If this is a footer, then we have to move the positions of the lines
|
|||
|
around so that the footer ends where the user has requested. */
|
|||
|
if (!fHeader && cpldReal > 0)
|
|||
|
{
|
|||
|
register struct PLD *ppld = &(***phrgpld)[cpldReal - 1];
|
|||
|
int dyp = MultDiv(vsepAbs.yaRH2 - dyaPrOffset, dypPrPage, dyaPrPage)
|
|||
|
- ppld->rc.bottom;
|
|||
|
int ipld;
|
|||
|
|
|||
|
for (ipld = cpldReal; ipld > 0; ipld--, ppld--)
|
|||
|
{
|
|||
|
ppld->rc.top += dyp;
|
|||
|
ppld->rc.bottom += dyp;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Record the number of non-blank lines in the head/footer. */
|
|||
|
*pcpld = cpldReal;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* Indicate there is no header/footer. */
|
|||
|
*ppgn = pgnNil;
|
|||
|
*phrgpld = NULL;
|
|||
|
*pcpld = 0;
|
|||
|
}
|
|||
|
return (TRUE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void GetPrNames(BOOL bPrDialog)
|
|||
|
{
|
|||
|
HANDLE hPrinter = NULL, hDriver = NULL, hPort = NULL;
|
|||
|
LPDEVNAMES lpDevNames;
|
|||
|
char szPrinter[cchMaxFile], szDriver[cchMaxFile], szPort[cchMaxFile];
|
|||
|
int Len1, Len2, Len3; /* count of words in each string */
|
|||
|
|
|||
|
hPrinter = NULL;
|
|||
|
hDriver = NULL;
|
|||
|
hPort = NULL;
|
|||
|
|
|||
|
lpDevNames = MAKELP(PD.hDevNames,0);
|
|||
|
|
|||
|
if (lpDevNames == NULL)
|
|||
|
/* we're in trouble */
|
|||
|
return;
|
|||
|
|
|||
|
lstrcpy(szPrinter, (LPSTR)lpDevNames+lpDevNames->wDeviceOffset);
|
|||
|
lstrcpy(szDriver, (LPSTR)lpDevNames+lpDevNames->wDriverOffset);
|
|||
|
|
|||
|
if (bPrDialog && (PD.Flags & PD_PRINTTOFILE))
|
|||
|
lstrcpy(szPort, (LPSTR)"FILE:");
|
|||
|
else
|
|||
|
lstrcpy(szPort, (LPSTR)lpDevNames+lpDevNames->wOutputOffset);
|
|||
|
|
|||
|
vfPrDefault = lpDevNames->wDefault & DN_DEFAULTPRN;
|
|||
|
|
|||
|
if (FNoHeap((hPrinter = (CHAR (**)[])HAllocate(Len1 =
|
|||
|
CwFromCch(CchSz(szPrinter))))))
|
|||
|
goto err;
|
|||
|
if (FNoHeap((hDriver = (CHAR (**)[])HAllocate(Len2 =
|
|||
|
CwFromCch(CchSz(szDriver))))))
|
|||
|
goto err;
|
|||
|
if (FNoHeap((hPort = (CHAR (**)[])HAllocate(Len3 =
|
|||
|
CwFromCch(CchSz(szPort))))))
|
|||
|
goto err;
|
|||
|
|
|||
|
/* Free old printer, driver and port handles */
|
|||
|
if (hszPrinter)
|
|||
|
FreeH(hszPrinter);
|
|||
|
if (hszPrDriver)
|
|||
|
FreeH(hszPrDriver);
|
|||
|
if (hszPrPort)
|
|||
|
FreeH(hszPrPort);
|
|||
|
/* Set printer, driver and port handles */
|
|||
|
hszPrinter = hPrinter;
|
|||
|
hszPrDriver = hDriver;
|
|||
|
hszPrPort = hPort;
|
|||
|
|
|||
|
/* copy strings into the memory corresponding to the new handles */
|
|||
|
blt(szPrinter, *hszPrinter, Len1);
|
|||
|
blt(szDriver, *hszPrDriver, Len2);
|
|||
|
blt(szPort, *hszPrPort, Len3);
|
|||
|
|
|||
|
FreePrinterDC();
|
|||
|
GetPrinterDC(FALSE);
|
|||
|
return;
|
|||
|
|
|||
|
err:
|
|||
|
if (FNoHeap(hPrinter))
|
|||
|
FreeH(hPrinter);
|
|||
|
if (FNoHeap(hDriver))
|
|||
|
FreeH(hDriver);
|
|||
|
if (FNoHeap(hPort))
|
|||
|
FreeH(hPort);
|
|||
|
}
|
|||
|
|
|||
|
BOOL fnPrGetDevmode(void)
|
|||
|
/* Set the devmode structure for the currently-selected printer,
|
|||
|
Assumes all needed values are correctly initialized!
|
|||
|
Return whether an error. */
|
|||
|
{
|
|||
|
int nCount;
|
|||
|
HANDLE hDevice=NULL;
|
|||
|
FARPROC lpfnDevMode;
|
|||
|
BOOL bRetval=FALSE;
|
|||
|
char szDrvName[_MAX_PATH];
|
|||
|
|
|||
|
if (PD.hDevMode) // then already set (why called?)
|
|||
|
return FALSE;
|
|||
|
else if (PD.hDevNames) // then device is not extended
|
|||
|
return TRUE;
|
|||
|
|
|||
|
if (hszPrinter == NULL || hszPrDriver == NULL || hszPrPort == NULL)
|
|||
|
return TRUE;
|
|||
|
|
|||
|
if (**hszPrinter == '\0' || **hszPrDriver == '\0' || **hszPrPort == '\0')
|
|||
|
return TRUE;
|
|||
|
|
|||
|
/* is this necessary for GetModuleHandle? For sure if calling LoadLibrary(). */
|
|||
|
wsprintf((LPSTR)szDrvName, (LPSTR)"%s%s", (LPSTR)*hszPrDriver, (LPSTR)".DRV");
|
|||
|
|
|||
|
#if 1
|
|||
|
SetErrorMode(1); /* No kernel error dialogs */
|
|||
|
if ((hDevice = LoadLibrary((LPSTR)szDrvName)) < 32)
|
|||
|
{
|
|||
|
bRetval = TRUE;
|
|||
|
goto end;
|
|||
|
}
|
|||
|
#else
|
|||
|
hDevice = GetModuleHandle((LPSTR)szDrvName);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
if ((lpfnDevMode = GetProcAddress(hDevice, (LPSTR)"ExtDeviceMode")) == NULL)
|
|||
|
{
|
|||
|
#ifdef DEBUG
|
|||
|
OutputDebugString("Unable to get extended device\n\r");
|
|||
|
#endif
|
|||
|
|
|||
|
bRetval = TRUE;
|
|||
|
goto end;
|
|||
|
}
|
|||
|
|
|||
|
/* get sizeof devmode structure */
|
|||
|
nCount = (*lpfnDevMode)(NULL,
|
|||
|
hDevice,
|
|||
|
(LPSTR)NULL,
|
|||
|
(LPSTR)(*hszPrinter),
|
|||
|
(LPSTR)(*hszPrPort),
|
|||
|
(LPSTR)NULL,
|
|||
|
(LPSTR)NULL,
|
|||
|
NULL);
|
|||
|
|
|||
|
if ((PD.hDevMode =
|
|||
|
GlobalAlloc(GMEM_MOVEABLE,(DWORD)nCount)) == NULL)
|
|||
|
{
|
|||
|
bRetval = TRUE;
|
|||
|
goto end;
|
|||
|
}
|
|||
|
|
|||
|
if ((*lpfnDevMode)( NULL,
|
|||
|
hDevice,
|
|||
|
MAKELP(PD.hDevMode,0),
|
|||
|
(LPSTR)(*hszPrinter),
|
|||
|
(LPSTR)(*hszPrPort),
|
|||
|
(LPSTR)NULL,
|
|||
|
(LPSTR)NULL,
|
|||
|
DM_COPY) != IDOK)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevMode);
|
|||
|
PD.hDevMode = NULL;
|
|||
|
bRetval = TRUE;
|
|||
|
goto end;
|
|||
|
}
|
|||
|
|
|||
|
end:
|
|||
|
|
|||
|
#if 1
|
|||
|
if (hDevice >= 32)
|
|||
|
FreeLibrary(hDevice);
|
|||
|
#endif
|
|||
|
|
|||
|
SetErrorMode(0); /* reset kernel error dialogs */
|
|||
|
|
|||
|
/* can't allow hDevNames to be out of sync with hDevmode */
|
|||
|
if (PD.hDevNames)
|
|||
|
{
|
|||
|
GlobalFree(PD.hDevNames);
|
|||
|
PD.hDevNames = NULL;
|
|||
|
}
|
|||
|
|
|||
|
return bRetval;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef JAPAN // added 08 Jun. 1992 by Hiraisi
|
|||
|
|
|||
|
#include <dlgs.h>
|
|||
|
|
|||
|
BOOL FAR PASCAL _export fnPrintHook( hDlg, uMsg, wParam, lParam )
|
|||
|
HWND hDlg;
|
|||
|
UINT uMsg;
|
|||
|
WPARAM wParam;
|
|||
|
LPARAM lParam;
|
|||
|
{
|
|||
|
switch( uMsg ){
|
|||
|
case WM_INITDIALOG:
|
|||
|
CheckRadioButton(hDlg, rad4, rad5, fWriting ? rad5 : rad4 );
|
|||
|
return TRUE;
|
|||
|
case WM_COMMAND:
|
|||
|
switch( wParam ){
|
|||
|
case rad4:
|
|||
|
case rad5:
|
|||
|
if( HIWORD(lParam) == BN_CLICKED ){
|
|||
|
CheckRadioButton(hDlg, rad4, rad5, wParam );
|
|||
|
bWriting = ( wParam == rad4 ? FALSE : TRUE );
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
|