428 lines
12 KiB
C
428 lines
12 KiB
C
/************************************************************/
|
||
/* Windows Write, Copyright 1985-1990 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
/* This file contains the dialog box routines for the print dialog box and the
|
||
printer initialization code. */
|
||
|
||
#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 NOMEMMGR
|
||
#define NOMETAFILE
|
||
#define NOWH
|
||
#define NOWNDCLASS
|
||
#define NOSOUND
|
||
#define NOCOLOR
|
||
#define NOSCROLL
|
||
#define NOCOMM
|
||
#include <windows.h>
|
||
#include "mw.h"
|
||
#include "cmddefs.h"
|
||
#include "dlgdefs.h"
|
||
#include "str.h"
|
||
#include "printdef.h"
|
||
#include "fmtdefs.h"
|
||
#include "propdefs.h"
|
||
|
||
|
||
fnPrPrinter()
|
||
{
|
||
/* This routine is the outside world's interface to the print code. */
|
||
|
||
extern HWND hParentWw;
|
||
extern HANDLE hMmwModInstance;
|
||
extern CHAR *vpDlgBuf;
|
||
extern int docCur;
|
||
CHAR rgbDlgBuf[sizeof(int) + 2 * sizeof(BOOL)];
|
||
#ifdef INEFFLOCKDOWN
|
||
extern FARPROC lpDialogPrint;
|
||
#else
|
||
BOOL far PASCAL DialogPrint(HWND, unsigned, WORD, LONG);
|
||
FARPROC lpDialogPrint;
|
||
if (!(lpDialogPrint = MakeProcInstance(DialogPrint, hMmwModInstance)))
|
||
{
|
||
WinFailure();
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
vpDlgBuf = &rgbDlgBuf[0];
|
||
switch (OurDialogBox(hMmwModInstance, MAKEINTRESOURCE(dlgPrint), hParentWw,
|
||
lpDialogPrint))
|
||
{
|
||
case idiOk:
|
||
/* Force all of the windows to clean up their act. */
|
||
DispatchPaintMsg();
|
||
|
||
/* 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 */
|
||
PrintDoc(docCur, TRUE);
|
||
break;
|
||
|
||
case -1:
|
||
/* We didn't even have enough memory to create the dialog box. */
|
||
#ifdef WIN30
|
||
WinFailure();
|
||
#else
|
||
Error(IDPMTNoMemory);
|
||
#endif
|
||
break;
|
||
}
|
||
#ifndef INEFFLOCKDOWN
|
||
FreeProcInstance(lpDialogPrint);
|
||
#endif
|
||
}
|
||
|
||
|
||
BOOL far PASCAL DialogPrint( hDlg, message, wParam, lParam )
|
||
HWND hDlg;
|
||
unsigned message;
|
||
WORD wParam;
|
||
LONG lParam;
|
||
{
|
||
/* This routine handles input to the Print dialog box. */
|
||
extern CHAR *vpDlgBuf;
|
||
extern int vfPrPages; /* true if print page range */
|
||
extern int vpgnBegin; /* starting page number to print */
|
||
extern int vpgnEnd; /* ending page number to print */
|
||
extern int vcCopies; /* nubmer of copies to print */
|
||
extern BOOL vfPrinterValid;
|
||
extern HDC vhDCPrinter;
|
||
extern int vfDraftMode;
|
||
extern HWND vhWndMsgBoxParent;
|
||
extern ferror;
|
||
extern HCURSOR vhcArrow;
|
||
extern int vfCursorVisible;
|
||
extern CHAR (**hszPrinter)[];
|
||
extern CHAR (**hszPrDriver)[];
|
||
extern CHAR (**hszPrPort)[];
|
||
|
||
int *pidiRBDown = (int *)vpDlgBuf;
|
||
BOOL *pfDraftMode = (BOOL *)(vpDlgBuf + sizeof(int));
|
||
BOOL *pfDraftSupport = (BOOL *)(vpDlgBuf + sizeof(int) + sizeof(BOOL));
|
||
int iEscape;
|
||
CHAR szPrDescrip[cchMaxProfileSz];
|
||
|
||
switch (message)
|
||
{
|
||
case WM_INITDIALOG:
|
||
BuildPrSetupSz(szPrDescrip, &(**hszPrinter)[0], &(**hszPrPort)[0]);
|
||
SetDlgItemText(hDlg, idiPrtDest, (LPSTR)szPrDescrip);
|
||
SetDlgItemText(hDlg, idiPrtCopies, (LPSTR)"1");
|
||
SelectIdiText(hDlg, idiPrtCopies);
|
||
if (vfPrPages)
|
||
{
|
||
*pidiRBDown = idiPrtFrom;
|
||
SetDlgItemInt(hDlg, idiPrtPageFrom, vpgnBegin, TRUE);
|
||
SetDlgItemInt(hDlg, idiPrtPageTo, vpgnEnd, TRUE);
|
||
}
|
||
else
|
||
{
|
||
*pidiRBDown = idiPrtAll;
|
||
}
|
||
|
||
iEscape = DRAFTMODE;
|
||
if (*pfDraftSupport = vfPrinterValid && vhDCPrinter &&
|
||
Escape(vhDCPrinter, QUERYESCSUPPORT, sizeof(int),
|
||
(LPSTR)&iEscape, (LPSTR)NULL))
|
||
{
|
||
CheckDlgButton(hDlg, idiPrtDraft, *pfDraftMode = vfDraftMode);
|
||
}
|
||
else
|
||
{
|
||
EnableWindow(GetDlgItem(hDlg, idiPrtDraft), FALSE);
|
||
if (!vhDCPrinter) /* we've got a timing thing whereby they
|
||
managed to get into the print dialog
|
||
inbetween the time printer.setup had
|
||
unhooked the old printer and the hookup
|
||
of the new one! ..pault */
|
||
EnableWindow(GetDlgItem(hDlg, idiOk), FALSE);
|
||
}
|
||
|
||
CheckDlgButton(hDlg, *pidiRBDown, TRUE);
|
||
EnableOtherModeless(FALSE);
|
||
break;
|
||
|
||
case WM_SETVISIBLE:
|
||
if (wParam)
|
||
{
|
||
EndLongOp(vhcArrow);
|
||
}
|
||
return(FALSE);
|
||
|
||
case WM_ACTIVATE:
|
||
if (wParam)
|
||
{
|
||
vhWndMsgBoxParent = hDlg;
|
||
}
|
||
if (vfCursorVisible)
|
||
{
|
||
ShowCursor(wParam);
|
||
}
|
||
return (FALSE);
|
||
|
||
case WM_COMMAND:
|
||
switch (wParam)
|
||
{
|
||
BOOL fPages;
|
||
int pgnBegin;
|
||
int pgnEnd;
|
||
int cCopies;
|
||
|
||
case idiOk:
|
||
if (fPages = (*pidiRBDown == idiPrtFrom))
|
||
{
|
||
/* Get the range of pages to print. */
|
||
if (!WPwFromItW3Id(&pgnBegin, hDlg, idiPrtPageFrom,
|
||
pgnMin, pgnMax, wNormal, IDPMTNPI))
|
||
{
|
||
/* Reset error condition, so as to report any further error.
|
||
*/
|
||
ferror = FALSE;
|
||
return(TRUE);
|
||
}
|
||
if (!WPwFromItW3Id(&pgnEnd, hDlg, idiPrtPageTo,
|
||
pgnMin, pgnMax, wNormal, IDPMTNPI))
|
||
{
|
||
/* Reset error condition, so as to report any further error.
|
||
*/
|
||
ferror = FALSE;
|
||
return(TRUE);
|
||
}
|
||
}
|
||
|
||
/* Get the number of copies to print. */
|
||
if (!WPwFromItW3IdFUt(&cCopies, hDlg, idiPrtCopies, 1, 32767,
|
||
wNormal, IDPMTNPI, FALSE, 0
|
||
))
|
||
{
|
||
/* Reset error condition, so as to report any further error. */
|
||
ferror = FALSE;
|
||
return(TRUE);
|
||
}
|
||
|
||
/* If we have gotten this far, then everything must be okey-dokey.
|
||
*/
|
||
vfDraftMode = *pfDraftSupport ? *pfDraftMode : FALSE;
|
||
if (vfPrPages = fPages)
|
||
{
|
||
vpgnBegin = pgnBegin;
|
||
vpgnEnd = pgnEnd;
|
||
}
|
||
vcCopies = cCopies;
|
||
|
||
case idiCancel:
|
||
OurEndDialog(hDlg, wParam);
|
||
break;
|
||
|
||
case idiPrtPageFrom:
|
||
case idiPrtPageTo:
|
||
if (HIWORD(lParam) == EN_CHANGE)
|
||
{
|
||
if (SendMessage(LOWORD(lParam), WM_GETTEXTLENGTH, 0, 0L) &&
|
||
*pidiRBDown != idiPrtFrom)
|
||
{
|
||
CheckDlgButton(hDlg, *pidiRBDown, FALSE);
|
||
CheckDlgButton(hDlg, *pidiRBDown = idiPrtFrom, TRUE);
|
||
}
|
||
return(TRUE);
|
||
}
|
||
return(FALSE);
|
||
|
||
case idiPrtAll:
|
||
case idiPrtFrom:
|
||
CheckDlgButton(hDlg, *pidiRBDown, FALSE);
|
||
CheckDlgButton(hDlg, *pidiRBDown = wParam, TRUE);
|
||
|
||
// set focus to the edit field automatically
|
||
|
||
if (wParam == idiPrtFrom)
|
||
SetFocus(GetDlgItem(hDlg, idiPrtPageFrom));
|
||
|
||
break;
|
||
|
||
case idiPrtDraft:
|
||
CheckDlgButton(hDlg, wParam, *pfDraftMode = !(*pfDraftMode));
|
||
break;
|
||
|
||
default:
|
||
return(FALSE);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return(FALSE);
|
||
}
|
||
return(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);
|
||
}
|
||
|