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 ***/ |