b782412b34
git-svn-id: svn://10.65.10.50/trunk@4211 c028cbd2-c16b-5b4b-a496-9718f37d4682
356 lines
9.3 KiB
C
Executable File
356 lines
9.3 KiB
C
Executable File
/* FILE: spool.c */
|
|
|
|
#include "spool.h"
|
|
#include <print.h>
|
|
#include <commdlg.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
// Play with this number
|
|
#define BUFSIZE 2048
|
|
|
|
// Convenient structure for use with PASSTHROUGH escape
|
|
typedef struct
|
|
{
|
|
WORD wSize;
|
|
BYTE bData[2]; // placeholder
|
|
} PASSTHROUGHSTRUCT, FAR *LPPTS;
|
|
|
|
|
|
BOOL bAbort; // Global printing abort flag
|
|
FILE *fp;
|
|
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// _PrintFile()
|
|
//
|
|
// Purpose:
|
|
// Reads a file and copies it to a printer using the
|
|
// PASSTHROUGH escape.
|
|
//
|
|
// Parameters:
|
|
// LPSTR szFile - Pointer to path/filename to print
|
|
// HDC hPrnDC - Handle to printer DC or NULL
|
|
// HGLOBAL hDevNames - Handle to DEVNAMES struct or NULL
|
|
// HGLOBAL hDevMode - Handle to DEVMODE struct or NULL
|
|
//
|
|
// Return:
|
|
// Returns nonzero for success or zero for failure.
|
|
//
|
|
// Comments:
|
|
// hDevNames and hDevMode are only used if hPrnDC is NULL.
|
|
// If both hPrnDC and hDevNames are NULL, the default
|
|
// printer is used.
|
|
//
|
|
// History: Date Author Comment
|
|
// 6/03/93 JMS Created
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL FAR PASCAL __export _PrintFile ( LPSTR szFile,
|
|
HDC hPrnDC,
|
|
HGLOBAL hDevNames,
|
|
HGLOBAL hDevMode )
|
|
{
|
|
int iEsc;
|
|
BOOL bLocalDC = TRUE; // Assume we must create a DC (hPrnDC == NULL)
|
|
|
|
bAbort = FALSE; // Haven't aborted yet
|
|
|
|
MessageBox(GetFocus(), "Inizio stampa file", "ERRORE FATALE", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
|
|
// Make sure we have a printer DC
|
|
|
|
if (!hPrnDC)
|
|
hPrnDC = GetPrinterDC(hDevNames, hDevMode);
|
|
else
|
|
bLocalDC = FALSE; // Use passed in hPrnDC
|
|
|
|
if (!hPrnDC)
|
|
{
|
|
MessageBox(GetFocus(), "Non riesco a ottenere il Printer DC", "ERRORE FATALE", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// PASSTHROUGH is required. If driver doesn't support it, bail out.
|
|
|
|
iEsc = PASSTHROUGH;
|
|
if (!Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
|
|
{
|
|
MessageBox(GetFocus(), "La stampante non ha il supporto passthrough", "ERRORE FATALE", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
bAbort = TRUE;
|
|
goto MSFCleanUp;
|
|
}
|
|
|
|
// If we created the DC, install an abort procedure. We don't have
|
|
// a Cancel dialog box, but the abort proc enables multitasking.
|
|
// (Use __export and compile with -GA or -GD so we don't need
|
|
// a MakeProcInstance.)
|
|
|
|
if (bLocalDC)
|
|
Escape (hPrnDC, SETABORTPROC, 0, (LPSTR) PrintAbortProc, NULL);
|
|
|
|
// Call EPSPRINTING if it is supported (that is, if we're on a
|
|
// PostScript printer) to suppress downloading the pscript header.
|
|
|
|
iEsc = EPSPRINTING;
|
|
if (Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
|
|
{
|
|
iEsc = 1; // 1 == enable PASSTHROUGH (disable pscript header)
|
|
Escape(hPrnDC, EPSPRINTING, sizeof(int), (LPSTR)&iEsc, NULL);
|
|
}
|
|
|
|
SendFile(hPrnDC, szFile); // Send file to printer (could do multiple
|
|
// files)
|
|
|
|
MSFCleanUp: // Done
|
|
|
|
if (bLocalDC) // Only delete DC if we created it
|
|
DeleteDC(hPrnDC);
|
|
|
|
return !bAbort;
|
|
|
|
} /* _PrintFile() */
|
|
|
|
|
|
BOOL FAR PASCAL __export PrintFile(LPSTR szFile)
|
|
{
|
|
return _PrintFile(szFile, NULL, NULL, NULL);
|
|
}
|
|
|
|
/* Le seguenti funzioni sono per aprire un file, scriverlo e chiuderlo*/
|
|
BOOL FAR PASCAL __export OpenText ( LPSTR szFile, LPSTR szMode)
|
|
{
|
|
fp = fopen(szFile,szMode);
|
|
return fp != NULL;
|
|
}
|
|
|
|
int FAR PASCAL __export WriteText(LPSTR szString)
|
|
{
|
|
return fprintf(fp,"%s",(char*)szString);
|
|
}
|
|
|
|
BOOL FAR PASCAL __export CloseText()
|
|
{
|
|
fclose(fp);
|
|
return TRUE;
|
|
}
|
|
|
|
VOID SendFile(HDC hPrnDC, LPSTR szFile)
|
|
{
|
|
HGLOBAL HMem;
|
|
LPPTS lpPTS; // Pointer to PASSTHROUGHSTRUCT
|
|
OFSTRUCT ofs;
|
|
HFILE hFile;
|
|
|
|
MessageBox(GetFocus(), "Inizio lettura file", "ERRORE FATALE", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
HMem = GlobalAlloc(GPTR, sizeof(WORD) + BUFSIZE);
|
|
if (HMem == NULL)
|
|
{
|
|
bAbort = TRUE;
|
|
return;
|
|
}
|
|
lpPTS = (LPPTS)GlobalLock(HMem);
|
|
if (lpPTS == NULL)
|
|
{
|
|
bAbort = TRUE;
|
|
GlobalFree(HMem);
|
|
return;
|
|
}
|
|
|
|
hFile = OpenFile((LPSTR) szFile, &ofs, OF_READ | OF_SHARE_COMPAT);
|
|
if (hFile == HFILE_ERROR)
|
|
{
|
|
MessageBox(GetFocus(), "Non riesco ad aprire il file di stampa", "ERRORE FATALE", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
bAbort = TRUE; // Can't open file|
|
|
GlobalUnlock(HMem);
|
|
GlobalFree(HMem);
|
|
return;
|
|
}
|
|
|
|
Escape (hPrnDC, STARTDOC, 0, "", NULL);
|
|
|
|
// Loop through the file, reading a chunk at a time and passing
|
|
// it to the printer. QueryAbort calls the abort procedure, which
|
|
// processes messages so we don't tie up the whole system.
|
|
// We could skip the QueryAbort, in which case we wouldn't need
|
|
// to set an abort proc at all.
|
|
|
|
do {
|
|
if ((lpPTS->wSize=_lread(hFile, lpPTS->bData, BUFSIZE)) == HFILE_ERROR)
|
|
{
|
|
MessageBox(GetFocus(), "Errore di lettura sul file di stampa", "ERRORE FATALE", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
bAbort = TRUE; // error reading file
|
|
break;
|
|
}
|
|
|
|
Escape(hPrnDC, PASSTHROUGH, NULL, (LPSTR)lpPTS, NULL);
|
|
}
|
|
while ((lpPTS->wSize == BUFSIZE) && QueryAbort(hPrnDC, 0));
|
|
|
|
if (!bAbort)
|
|
Escape(hPrnDC, ENDDOC, NULL, NULL, NULL);
|
|
|
|
_lclose(hFile);
|
|
GlobalUnlock(HMem);
|
|
GlobalFree(HMem);
|
|
} /* SendFile() */
|
|
|
|
HDC FAR PASCAL __export GetPrinterDC(HGLOBAL hDevNames, HGLOBAL hDevMode)
|
|
{
|
|
HDC hdc;
|
|
int iEsc;
|
|
char szPrinter[64];
|
|
LPSTR szDevice=NULL, szDriver=NULL, szOutput=NULL;
|
|
LPDEVMODE lpdm;
|
|
|
|
if (hDevNames)
|
|
{
|
|
LPDEVNAMES lpdn = (LPDEVNAMES) GlobalLock(hDevNames);
|
|
|
|
szDriver = (LPSTR) lpdn + lpdn->wDriverOffset;
|
|
szDevice = (LPSTR) lpdn + lpdn->wDeviceOffset;
|
|
szOutput = (LPSTR) lpdn + lpdn->wOutputOffset;
|
|
|
|
if (hDevMode)
|
|
lpdm = (LPDEVMODE) GlobalLock(hDevMode);
|
|
}
|
|
else
|
|
{ // Get default printer info
|
|
GetProfileString ("windows", "device", "", szPrinter, 64);
|
|
|
|
if (!((szDevice = strtok (szPrinter, "," )) &&
|
|
(szDriver = strtok (NULL, ", ")) &&
|
|
(szOutput = strtok (NULL, ", "))))
|
|
return NULL; // No default printer
|
|
|
|
lpdm = NULL; // Don't use DEVMODE with default printer
|
|
}
|
|
|
|
hdc = CreateDC(szDriver, szDevice, szOutput, lpdm);
|
|
// PASSTHROUGH is required. If driver doesn't support it, try to use raw.drv.
|
|
|
|
iEsc = PASSTHROUGH;
|
|
if (!Escape(hdc, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
|
|
{
|
|
DeleteDC(hdc);
|
|
// RAW.DRV can be either in current directory, WINDOWS directory or WINDOWS\SYSTEM directory
|
|
hdc = CreateDC( "RAW", NULL, szOutput, lpdm);
|
|
}
|
|
|
|
// hdc = CreateDC("RAW", NULL, szOutput, lpdm);
|
|
|
|
if (hDevMode && lpdm)
|
|
GlobalUnlock(hDevMode);
|
|
if (hDevNames)
|
|
GlobalUnlock(hDevNames);
|
|
|
|
return hdc;
|
|
|
|
} /* GetPrinterDC() */
|
|
|
|
|
|
BOOL CALLBACK __export PrintAbortProc(HDC hdc, int code)
|
|
{
|
|
MSG msg;
|
|
|
|
while (!bAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
return (!bAbort);
|
|
|
|
} /* PrintAbortProc() */
|
|
|
|
// The function that prints one line without formfeed
|
|
BOOL FAR PASCAL __export _SpoolRow( LPSTR pData,
|
|
WORD cbBytes,
|
|
HDC hPrnDC,
|
|
HGLOBAL hDevNames,
|
|
HGLOBAL hDevMode )
|
|
{
|
|
int iEsc;
|
|
BOOL bLocalDC = TRUE; // Assume we must create a DC (hPrnDC == NULL)
|
|
HGLOBAL HMem;
|
|
char * pOutput;
|
|
|
|
HMem = GlobalAlloc(GPTR, sizeof(WORD) + cbBytes);
|
|
if (HMem == NULL)
|
|
return FALSE;
|
|
pOutput = (char *)GlobalLock(HMem);
|
|
if (pOutput == NULL)
|
|
{
|
|
GlobalFree(HMem);
|
|
return FALSE;
|
|
}
|
|
|
|
bAbort = FALSE; // Haven't aborted yet
|
|
|
|
// Make sure we have a printer DC
|
|
|
|
if (!hPrnDC)
|
|
hPrnDC = GetPrinterDC(hDevNames, hDevMode);
|
|
else
|
|
bLocalDC = FALSE; // Use passed in hPrnDC
|
|
|
|
if (!hPrnDC)
|
|
return FALSE;
|
|
|
|
if (bLocalDC)
|
|
Escape (hPrnDC, SETABORTPROC, 0, (LPSTR) PrintAbortProc, NULL);
|
|
|
|
// PASSTHROUGH is required. If driver doesn't support it, bail out.
|
|
|
|
bAbort = FALSE;
|
|
iEsc = PASSTHROUGH;
|
|
if (!Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
|
|
{
|
|
bAbort = TRUE;
|
|
goto MPLCleanUp;
|
|
}
|
|
|
|
// Call EPSPRINTING if it is supported (that is, if we're on a
|
|
// PostScript printer) to suppress downloading the pscript header.
|
|
|
|
iEsc = EPSPRINTING;
|
|
if (Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
|
|
{
|
|
iEsc = 1; // 1 == enable PASSTHROUGH (disable pscript header)
|
|
Escape(hPrnDC, EPSPRINTING, sizeof(int), (LPSTR)&iEsc, NULL);
|
|
}
|
|
|
|
|
|
// Start a Document
|
|
Escape (hPrnDC, STARTDOC, 0, "", NULL);
|
|
|
|
// Put data in the buffer and send to the printer
|
|
*(WORD *)pOutput = cbBytes;
|
|
memcpy( &(pOutput[sizeof(WORD)]), pData, cbBytes );
|
|
if( Escape( hPrnDC, PASSTHROUGH, 0, pOutput, NULL ) <= 0 )
|
|
bAbort = TRUE;
|
|
|
|
// End the Document
|
|
if (!bAbort)
|
|
Escape(hPrnDC, ENDDOC, NULL, NULL, NULL);
|
|
|
|
MPLCleanUp: // Done
|
|
// Clean up
|
|
if (bLocalDC)
|
|
DeleteDC( hPrnDC );
|
|
|
|
GlobalUnlock(HMem);
|
|
GlobalFree(HMem);
|
|
|
|
return !bAbort;
|
|
}
|
|
|
|
BOOL FAR PASCAL __export SpoolRow( char *pData, WORD cbBytes )
|
|
{
|
|
return _SpoolRow(pData, cbBytes, NULL, NULL, NULL);
|
|
}
|
|
/*** EOF: spool.c ***/ |