|
|
Microsoft OS/2 SDK 2.0 05-30-1990
/*==============================================================*\
* Prnt.c - routines for printing of a document
* Created 1989, 1990 Microsoft Corp.
*--------------------------------------------------------------
*
* This module contains the routines for the printing of a
* a document. Included are the routines for calling the
* standard dialogs for obtaining the user's printer and
* page setup preferences. Also included is the routine to
* determine the number of pages in a document as well as the
* routine to obtain the printer DC and print the document.
*
*--------------------------------------------------------------
*
* This source file contains the following functions:
*
* InitPrinting();
* PageSetup(hwndOwner);
* PrintSetup(hwndOwner);
* Print();
* PrintDoc(hdc);
* QueryMaxPages();
*
\*==============================================================*/
/*--------------------------------------------------------------*\
* Include files, macros, defined constants, and externs
\*--------------------------------------------------------------*/
#define INCL_DEV
#include <os2.h>
#include "main.h"
#include "xtrn.h"
#define MAXHEADERLEN 100 /* maximum length of header */
#define MAXFOOTERLEN 100 /* maximum length of footer */
#define DLGTITLELEN 30 /* length of dialog title string */
#define DEVDATACOUNT 7L /* # fields of DEVOPENSTRUCT used */
#define FONTLCID 1L /* LCID for printer font */
#define QMP_ERROR -1 /* error return from QueryMaxPages() */
/* constants used in InitPrintingDlgs() for initial and maximum margins */
#define ONEINCH (MAKEFIXED(1, 0))
#define EIGHTINCHES (MAKEFIXED(8, 0))
#define ELEVENINCHES (MAKEFIXED(11, 0))
/* Macro for converting a FIXED integer value into LO_ENGLISH
world coordinates */
#define FIXEDTOWORLD(x) ((FIXEDINT(x) * 100L) + \
((FIXEDFRAC(x) * 100L) / 65536L))
/*--------------------------------------------------------------*\
* Global variables
\*--------------------------------------------------------------*/
#ifdef PRINT_DLGS_ENABLED
static PAGESETUPDLG pgsd;
static PRINTSETUPDLG psd;
static PRINTDLG prtd;
static CHAR szHeader[MAXHEADERLEN], szFooter[MAXFOOTERLEN];
static CHAR szPgsdTitle[DLGTITLELEN];
static CHAR szPsdtitle[DLGTITLELEN];
static CHAR szPrtdTitle[DLGTITLELEN];
#endif
/*--------------------------------------------------------------*\
* Entry point declarations
\*--------------------------------------------------------------*/
SHORT QueryMaxPages(VOID);
BOOL PrintDoc(HDC hdc);
/****************************************************************\
* Initializes the print dialog structures
*--------------------------------------------------------------
*
* Name: InitPrintDialogs()
*
* Purpose: Places defaults in the global info structures
* used by the standard print dialogs
*
* Usage: called once from the initialization routine
*
* Method: places standard defaults into each of the fields
* of the Page Setup, Print Setup, and Print Dialog
* structures. The values used are standard defaults,
* such as inches for the page units, which can be
* easily changed by changing the default values in
* the routine. The application developer should
* modify these values if he wishes to have the
* default printer and page setup use different values.
*
* Returns:
*
\****************************************************************/
VOID InitPrintingDialogs(VOID)
{
#ifdef PRINT_DLGS_ENABLED
fPrintEnabled = TRUE;
/*--------------------------------------------------------------*\
* Initialize the Page Setup structure
\*--------------------------------------------------------------*/
pgsd.kgd.cbSize = sizeof(PAGESETUPDLG);
pgsd.kgd.flStyle = PGSS_CENTER;
if(!WinLoadString(hab,
NULL,
IDS_PAGESETUPTITLE,
DLGTITLELEN,
(PSZ)szPgsdTitle)) {
MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
fPrintEnabled = FALSE;
return;
}
pgsd.kgd.pszDlgTitle = szPgsdTitle;
pgsd.kgd.pfnDlgProc = NULL;
pgsd.kgd.hmod = NULL;
pgsd.kgd.idDlg = 0;
pgsd.kgd.lReturn = 0L;
pgsd.kgd.x = 0;
pgsd.kgd.y = 0;
pgsd.flFlags = PGSF_INCHES;
/* Setup the header and footer fields. */
pgsd.cchHeader = MAXFOOTERLEN;
pgsd.cchFooter = MAXHEADERLEN;
pgsd.pszHeader = szHeader;
pgsd.pszFooter = szFooter;
/* Setup the margin fields to one inch top and side margins */
pgsd.fxLeftMargin = ONEINCH;
pgsd.fxRightMargin = ONEINCH;
pgsd.fxTopMargin = ONEINCH;
pgsd.fxBottomMargin = ONEINCH;
/* maximum margins are 8 inch left and right, 11 inch bottom. We
are assuming the default page size is 8 1/2" x 11 " */
pgsd.fxLeftMarginMax = EIGHTINCHES;
pgsd.fxRightMarginMax = EIGHTINCHES;
pgsd.fxTopMarginMax = ELEVENINCHES;
pgsd.fxBottomMarginMax = ELEVENINCHES;
pgsd.lUser = 0L;
/*--------------------------------------------------------------*\
* Initialize the Print Setup structure
\*--------------------------------------------------------------*/
psd.kgd.cbSize = sizeof(PRINTSETUPDLG);
psd.kgd.flStyle = PGSS_CENTER;
if(!WinLoadString(hab,
NULL,
IDS_PRINTSETUPTITLE,
DLGTITLELEN,
(PSZ)szPsdTitle)) {
MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
fPrintEnabled = FALSE;
return;
}
psd.kgd.pszDlgTitle = szPsdTitle;
psd.kgd.pfnDlgProc = NULL;
psd.kgd.hmod = NULL;
psd.kgd.idDlg = 0;
psd.kgd.lReturn = 0L;
psd.kgd.x = 0;
psd.kgd.y = 0;
psd.pszAppName = szAppName;
psd.lUser = 0L;
/*--------------------------------------------------------------*\
* Initialize the Print Dialog structure
\*--------------------------------------------------------------*/
prtd.kgd.cbSize = sizeof(PRINTDLG);
prtd.kgd.flStyle = PGSS_CENTER;
if(!WinLoadString(hab,
NULL,
IDS_PRINTTITLE,
DLGTITLELEN,
(PSZ)szPrtdTitle)) {
MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
fPrintEnabled = FALSE;
return;
}
prtd.kgd.pszDlgTitle = szPrtdTitle;
prtd.kgd.pfnDlgProc = NULL;
prtd.kgd.hmod = NULL;
prtd.kgd.idDlg = 0;
prtd.kgd.lReturn = 0L;
prtd.kgd.x = 0;
prtd.kgd.y = 0;
prtd.flFlags = PRTF_ALLPAGES;
prtd.cPages = 0;
prtd.cCopies = 1;
prtd.iFrom = 0;
prtd.iTo = 0;
prtd.cchFileName = 0;
prtd.pszFileName = NULL;
prtd.lUser = 0L;
/*--------------------------------------------------------------*\
* Associate all of the dialog structures with each other so
* that the dialogs can be called from one another
\*--------------------------------------------------------------*/
pgsd.ppsd = &psd;
pgsd.pprtd = &prtd;
psd.ppgsd = &pgsd;
psd.pprtd = &prtd;
prtd.ppsd = &psd;
prtd.ppgsd = &pgsd;
/*--------------------------------------------------------------*\
* Initialize the DEVOPENSTRUC in psd and prtd with the data
* from the default printer in os2.ini
\*--------------------------------------------------------------*/
psd.kgd.flStyle |= PSS_INITDEVOPENSTRUC;
if(!KitPrintSetupDlg(NULL, &psd))
fPrintEnabled = FALSE;
prtd.kgd.flStyle |= PSS_INITDEVOPENSTRUC;
if(!KitPrintDlg(NULL, &prtd))
fPrintEnabled = FALSE;
if(!fPrintEnabled)
MessageBox(HWND_DESKTOP,
IDMSG_PRINTINITFAILED,
MB_OK | MB_ERROR,
FALSE);
#else
fPrintEnabled = FALSE;
#endif
} /* InitPrintDialogs() */
#ifdef PRINT_DLGS_ENABLED
/****************************************************************\
* Calls the page setup dialog
*--------------------------------------------------------------
*
* Name: PageSetup(hwndOwner)
*
* Purpose: Changes the page setup options by calling the
* standard page setup dialog
*
* Usage: called whenever the user wants to update his
* page setup.
*
* Method: Calls the standard Page Setup dialog with the
* global PAGESETUPDLG structure which currently
* holds the user's choices.
*
* Returns:
*
\****************************************************************/
VOID PageSetup(hwndOwner)
HWND hwndOwner; /* Owner of the dialog */
{
if(!KitPageSetupDlg(hwndOwner, &pgsd))
MessageBox(hwndOwner,
IDMSG_CANNOTRUNPAGESETUP,
MB_OK | MB_ERROR,
TRUE);
} /* PageSetup() */
/****************************************************************\
* Calls the print setup dialog
*--------------------------------------------------------------
*
* Name: PrintSetup(hwndOwner)
*
* Purpose: Changes the printer setup by calling the standard
* print setup dialog
*
* Usage: called whenever the user wants to update his
* printer set up.
*
* Method: Calls the standard Print Setup dialog with the
* global PRINTSETUPDLG structure which currently
* holds the user's choices.
*
* Returns:
*
\****************************************************************/
VOID PrintSetup(hwndOwner)
HWND hwndOwner; /* Owner of the dialog */
{
if(!KitPrintSetupDlg(hwndOwner, &psd))
MessageBox(hwndOwner,
IDMSG_CANNOTRUNPRINTSETUP,
MB_OK | MB_ERROR,
TRUE);
} /* PrintSetup() */
/****************************************************************\
* Begins the printing of a document
*--------------------------------------------------------------
*
* Name: Print()
*
* Purpose: Does the groundwork necessary when printing a file
*
* Usage: called whenever the user wants to print his file
*
* Method: - determines the number of pages in the document
* - calls the standard print dialog to get the user's
* printing options
* - opens the DC for the selected printer
* - calls the application's printing routine, passing
* it the handle to the DC of the printer
*
* Returns:
*
\****************************************************************/
VOID Print(hwndOwner)
HWND hwndOwner; /* owner of the print dialog */
{
HDC hdcPrinter;
/* Determine number of pages available to print */
prtd.cPages = QueryMaxPages();
if(prtd.cPages == QMP_ERROR) {
MessageBox(hwndOwner, IDMSG_CANNOTGETPAGEINFO, MB_OK | MB_ERROR, FALSE);
return;
}
prtd.cCopies = 1; /* initialize the number of copies to one */
/* Bring up the Print Dialog */
if(!KitPrintDlg(hwndOwner, &prtd)) {
MessageBox(hwndOwner, IDMSG_CANNOTRUNPRINT, MB_OK | MB_ERROR, TRUE);
return;
}
/* if user cancelled the dialog, cancel the printing */
if(prtd.kgd.lReturn == ID_CANCEL)
return;
/*--------------------------------------------------------------*\
* Open the DC for the default printer. The default printer
* DEVOPENDATA is stored in the prtd structure
\*--------------------------------------------------------------*/
hdcPrinter = DevOpenDC(hab,
OD_QUEUED,
"*",
DEVDATACOUNT,
(PDEVOPENDATA)&prtd.ppsd->dop,
(HDC)NULL);
if(!hdcPrinter) {
MessageBox(hwndMain,
IDMSG_CANNOTOPENPRINTER,
MB_OK | MB_ERROR,
FALSE);
return;
}
/*--------------------------------------------------------------*\
* Call the application's printing function
\*--------------------------------------------------------------*/
if(!PrintDoc(hdcPrinter)) {
MessageBox(hwndOwner, IDMSG_PRINTERROR, MB_OK | MB_ERROR, FALSE);
}
DevCloseDC(hdcPrinter);
} /* Print() */
/****************************************************************\
* Determines the maximum number of pages in the document
*--------------------------------------------------------------
*
* Name: QueryMaxPages()
*
* Purpose: returns the maximum number of pages in a file
*
* Usage: called by Print() to initialize the prtd.cPages
* field
*
* Method:
*
* Returns: Number of pages in the document, QMP_ERROR if an error
* occurred
*
\****************************************************************/
SHORT QueryMaxPages(VOID)
{
/*--------------------------------------------------------------*\
* Add code to determine the number of pages in the document
* to be printed and return that value
\*--------------------------------------------------------------*/
return 1;
} /* QueryMaxPages() */
/****************************************************************\
* Performs the actual printing of a document
*--------------------------------------------------------------
*
* Name: PrintDoc(hdc)
*
* Purpose: Performs the printing of a file
*
* Usage: called by Print() to actually print the file
*
* Method: Application specific print routines
*
* Note: this routine should NOT close the printer DC
*
* Returns: TRUE if successful, FALSE if not
*
\****************************************************************/
BOOL PrintDoc(hdc)
HDC hdc; /* hdc of the printer */
{
SIZEL szl;
HPS hpsPrinter;
USHORT usNumCopies;
BOOL fRet = TRUE;
/*--------------------------------------------------------------*\
* Create a PS for the DC. Note that you can associate an
* existing HPS to the DC here instead if you are using
* retained graphics in the HPS. The PS should use any page units
* that are convenient. This PS uses LOENGLISH since the margins
* returned by the page setup dialog are in inches
\*--------------------------------------------------------------*/
szl.cx = szl.cy = 0L;
hpsPrinter = GpiCreatePS(hab,
hdc,
&szl,
PU_LOENGLISH | GPIT_NORMAL | GPIF_DEFAULT | GPIA_ASSOC);
if(hpsPrinter == NULL)
return FALSE;
/* print one document for each number of copies */
usNumCopies = (USHORT)prtd.cCopies;
while(usNumCopies--) {
/* send a DEVESC_STARTDOC to start the printing */
if(DevEscape(hdc,
DEVESC_STARTDOC,
(LONG)MAXNAMEL,
(PBYTE)szAppName,
(PLONG)NULL,
(PBYTE)NULL) != DEV_OK) {
MessageBox(hwndMain,
IDMSG_CANNOTOPENPRINTER,
MB_OK | MB_ERROR,
FALSE);
fRet = FALSE;
goto PrintDocExit;
}
/*--------------------------------------------------------------*\
* Include any code necessary for printing here. Note that
* all page and printer setup information can be found in
* the pgsd, psd, and prtd global variables. Remember to
* send a DEVESC_NEWFRAME escape code to the hdc after each
* page.
\*--------------------------------------------------------------*/
/* send a DEVESC_ENDDOC to end the printing */
if(DevEscape(hdc,
DEVESC_ENDDOC,
0L,
(PBYTE)NULL,
(PLONG)&lOutData,
(PBYTE)&usSpoolId) != DEV_OK) {
MessageBox(hwndMain,
IDMSG_CANNOTOPENPRINTER,
MB_OK | MB_ERROR,
FALSE);
fRet = FALSE;
goto PrintDocExit;
}
} /* while(usNumCopies) */
PrintDocExit:
/* Destroy the printer PS */
GpiAssociate(hpsPrinter, NULL);
GpiDestroyPS(hpsPrinter);
return fRet;
} /* PrintDoc() */
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.