Portieren "RawDataToPrinter" von C nach PB?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Portieren "RawDataToPrinter" von C nach PB?

Beitrag von Falko »

Hi @all
Kann mir jemand helfen diese C-Source nach PB umzuwandeln?
Komme leider nicht weiter. Bin dankbar für jede weitere Hilfe :freak:
MfG Falko

Hier der MSDN-Original-C-Source:

Code: Alles auswählen

Sending Data Directly to a Printer
It is sometimes necessary to bypass the driver and send printer-specific data directly to a printer. The following code shows how this can be done for both local and networked printers. This method can be used to replace the PASSTHROUGH escape and SpoolFile methods. 

      // RawDataToPrinter - sends binary data directly to a printer
      // 
      // szPrinterName: NULL-terminated string specifying printer name
      // lpData:        Pointer to raw data bytes
      // dwCount        Length of lpData in bytes
      // 
      // Returns: TRUE for success, FALSE for failure.
      // 
       BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount)
      {
        HANDLE     hPrinter;
        DOC_INFO_1 DocInfo;
        DWORD      dwJob;
        DWORD      dwBytesWritten;

        // Need a handle to the printer.
        if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) )
          return FALSE;

        // Fill in the structure with info about this "document."
        DocInfo.pDocName = "My Document";
        DocInfo.pOutputFile = NULL;
        DocInfo.pDatatype = "RAW";
        // Inform the spooler the document is beginning.
        if( (dwJob = StartDocPrinter( hPrinter, 1, (LPSTR)&DocInfo )) == 0 )
        {
          ClosePrinter( hPrinter );
          return FALSE;
        }
        // Start a page.
        if( ! StartPagePrinter( hPrinter ) )
        {
          EndDocPrinter( hPrinter );
          ClosePrinter( hPrinter );
          return FALSE;
        }
        // Send the data to the printer.
        if( !WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) )
        {
          EndPagePrinter( hPrinter );
          EndDocPrinter( hPrinter );
          ClosePrinter( hPrinter );
          return FALSE;
        }
        // End the page.
        if( ! EndPagePrinter( hPrinter ) )
        {
          EndDocPrinter( hPrinter );
          ClosePrinter( hPrinter );
          return FALSE;
        }
        // Inform the spooler that the document is ending.
        if( ! EndDocPrinter( hPrinter ) )
        {
          ClosePrinter( hPrinter );
          return FALSE;
        }
        // Tidy up the printer handle.
        ClosePrinter( hPrinter );
        // Check to see if correct number of bytes were written.
        if( dwBytesWritten != dwCount )
          return FALSE;
        return TRUE;
      }
Und hier mein bescheidener PB-Versuch:

Code: Alles auswählen

; RawDataToPrinter - sends binary Data directly To a printer
      ; 
      ; szPrinterName: NULL-terminated string specifying printer name
      ; lpData:        Pointer To raw Data bytes
      ; dwCount        Length of lpData in bytes
      ; 
      ; Returns: TRUE For success, FALSE For failure.
      ; 
       Procedure.b RawDataToPrinter(szPrinterName.s,lpData.b,dwCount.l)
      
        hPrinter.l
        DocInfo.DOC_INFO_1
        dwJob.l
        dwBytesWritten.l

        ; Need a handle To the printer.
        If OpenPrinter_( szPrinterName, @hPrinter, 0)=0
          ProcedureReturn #FALSE
        EndIf
        RAW.s="RAW"  
        MyDocument.s="My_Document"
        
        ; Fill in the Structure with info about this "document."
        DocInfo\pDocName = @MyDocument
        DocInfo\pOutputFile = 0
        DocInfo\pDatatype = @RAW
        ; Inform the spooler the document is beginning.
        dwJob=StartDocPrinter_( hPrinter, 1, @DocInfo )
        If dwJob=0
           ClosePrinter_( hPrinter )
          ProcedureReturn  #FALSE
        EndIf
        ; Start a page.
        If StartPagePrinter_( hPrinter ) = 0
        
          EndDocPrinter_( hPrinter );
          ClosePrinter_( hPrinter );
          ProcedureReturn  #FALSE
        EndIf
        ; Send the Data To the printer.
        If WritePrinter_( hPrinter, lpData, dwCount,@dwBytesWritten ) =0
        
          EndPagePrinter_( hPrinter )
          EndDocPrinter_( hPrinter )
          ClosePrinter_( hPrinter )
         ProcedureReturn  #FALSE
        EndIf
        
        ; End the page.
        If EndPagePrinter_( hPrinter ) = 0
          EndDocPrinter_( hPrinter )
          ClosePrinter_( hPrinter )
          ProcedureReturn  #FALSE
        EndIf
        ; Inform the spooler that the document is ending.
        If EndDocPrinter_( hPrinter ) = 0
          ClosePrinter_( hPrinter )
          ProcedureReturn  #FALSE
        EndIf
        ; Tidy up the printer handle.
        ClosePrinter_( hPrinter );
        ; Check To see If correct number of bytes were written.
        If dwBytesWritten = dwCount 
          ProcedureReturn  #FALSE
        EndIf
      EndProcedure
      
      Drucker.s="EPSON Stylus COLOR 680"
      OpenFile(0,"Grafik1.plt")
 
      Anz.l=Eof(0)
      For i=0 To Anz
       Debug  RawDataToPrinter(Drucker,ReadByte(),Anz)
      Next i
     CloseFile(0)
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Hallo @all,
ich glaube, so müsste es soweit richtig sein. Man kann jetzt damit direkt aus einer Datei zum Drucker drucken. Für weitere Tips bin ich euch sehr dankbar.

MFG Falko

Code: Alles auswählen

;;Portiert vo C nach Purebasic aus der MSDN von Falko
;
; RawDataToPrinter - sends binary Data directly To a printer
      ; 
      ; szPrinterName: NULL-terminated string specifying printer name
      ; lpData:        Pointer To raw Data bytes
      ; dwCount        Length of lpData in bytes
      ; 
      ; Returns: TRUE For success, FALSE For failure.
      ; 
       Procedure.b RawDataToPrinter(szPrinterName.s,lpData.l,dwCount.l)
      
        hPrinter.l
        DocInfo.DOC_INFO_1
        dwJob.l
        dwBytesWritten.l

        ; Need a handle To the printer.
        If OpenPrinter_( szPrinterName, @hPrinter, #NULL)=0
          ProcedureReturn #FALSE
        EndIf
        RAW.s="RAW"  
        MyDocument.s="My Document"
        
        ; Fill in the Structure with info about this "document."
        DocInfo\pDocName = @MyDocument
        DocInfo\pOutputFile = 0
        DocInfo\pDatatype = @RAW
        ; Inform the spooler the document is beginning.
        dwJob=StartDocPrinter_(hPrinter, 1, @DocInfo)
        If dwJob=0
           ClosePrinter_(hPrinter)
          Result=#FALSE
        EndIf
        ; Start a page.
        If StartPagePrinter_( hPrinter ) = 0
        
          EndDocPrinter_(hPrinter);
          ClosePrinter_(hPrinter);
          Result=#FALSE
        EndIf
        ; Send the Data To the printer.
        If WritePrinter_( hPrinter, lpData, dwCount,@dwBytesWritten)=0
        
          EndPagePrinter_(hPrinter)
          EndDocPrinter_(hPrinter)
          ClosePrinter_(hPrinter)
         Result=#FALSE
        EndIf
        
        ; End the page.
        If EndPagePrinter_(hPrinter) = 0
          EndDocPrinter_(hPrinter)
          ClosePrinter_(hPrinter)
          Result=#FALSE
        EndIf
        ; Inform the spooler that the document is ending.
        If EndDocPrinter_(hPrinter) = 0
          ClosePrinter_(hPrinter)
          Result=#FALSE
        EndIf
        ; Tidy up the printer handle.
        ClosePrinter_(hPrinter);
        ; Check To see If correct number of bytes were written.
        If dwBytesWritten = dwCount 
          Result=#FALSE
        EndIf
        Result=#TRUE

          ProcedureReturn Result
        
      EndProcedure
     ;Ab Hier Datei angeben, die gedruckt werden soll 
     ;
      ;Drucker.s="PDF Professionell"
      Drucker.s="EPSON Stylus COLOR 680"
     If ReadFile(0,"PB_Beta - ReadMe.txt")
      Anz.l=Lof()
      *Mem=AllocateMemory(Anz)
       laenge.l=ReadData(*Mem,Anz)
     
       Debug RawDataToPrinter(Drucker,*Mem ,laenge)
     
      CloseFile(0)
      FreeMemory(*Mem)
    EndIf
Zuletzt geändert von Falko am 08.12.2004 15:03, insgesamt 1-mal geändert.
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1765
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

@Falko: mal noch paar Tipps zur verbesserten Fehlerbehandlung:

Code: Alles auswählen

If OpenFile(0,"Handbuch.pdf")
Schlägt eigentlich nie fehl, da halt einfach eine neue Datei mit diesem Namen erstellt wird, wenn keine existiert. Würde ich daher mit ReadFile() ersetzen.

Andernfalls geht es nämlich weiter:

Code: Alles auswählen

      Anz.l=Lof() 
Hier ist Anz.l gleich 0, wenn die Datei gerade erst neu (und damit leer) erstellt wurde.

Code: Alles auswählen

      *Mem=AllocateMemory(Anz) 
Schlägt dann auch fehl.


Weiter hab ich's mangels angeschlossenem Drucker jetzt noch nicht getestet.

Wenn es in der Folge jedoch einwandfrei läuft, wäre dies tatsächlich ein sehr nützlicher Code :allright:
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

@Andre
Du hast Recht. Ich habe gestern Abend ziehmlich viel herum experimentiert bis ich den ersten RAW-Ausdruck aus meinem Drucker
herausbekommen hatte. Habe den Openfile... nach Readfile abgeändert
und getestet. Der Code funktioniert auch jetzt soweit prima. :)

Danke Für Deinen Tip und ich freue mich sehr diesen Source in PureArea.net zu sehen :allright: .

MfG Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
kunstlust
Beiträge: 259
Registriert: 12.04.2012 23:47
Wohnort: Hannover
Kontaktdaten:

Re: Portieren "RawDataToPrinter" von C nach PB?

Beitrag von kunstlust »

Ich habe den Code Minimal angebpasst und nun geht es mit PB 5.11, ist es möglich, das der Drucker bestimmte Formate nicht druckt? Also ein PCL Drucker kein PDF, ob das abzufragen ist?
Auf jedenfall 1000 Dank, das habe ich gesucht :bounce:

Code: Alles auswählen

;;Portiert vo C nach Purebasic aus der MSDN von Falko
;
; RawDataToPrinter - sends binary Data directly To a printer
      ;
      ; szPrinterName: NULL-terminated string specifying printer name
      ; lpData:        Pointer To raw Data bytes
      ; dwCount        Length of lpData in bytes
      ;
      ; Returns: TRUE For success, FALSE For failure.
      ;
       Procedure.b RawDataToPrinter(szPrinterName.s,lpData.l,dwCount.l)
     
        hPrinter.l
        DocInfo.DOC_INFO_1
        dwJob.l
        dwBytesWritten.l

        ; Need a handle To the printer.
        If OpenPrinter_( szPrinterName, @hPrinter, #Null)=0
          ProcedureReturn #False
        EndIf
        RAW.s="RAW" 
        MyDocument.s="My Document"
       
        ; Fill in the Structure with info about this "document."
        DocInfo\pDocName = @MyDocument
        DocInfo\pOutputFile = 0
        DocInfo\pDatatype = @RAW
        ; Inform the spooler the document is beginning.
        dwJob=StartDocPrinter_(hPrinter, 1, @DocInfo)
        If dwJob=0
           ClosePrinter_(hPrinter)
          Result=#False
        EndIf
        ; Start a page.
        If StartPagePrinter_( hPrinter ) = 0
       
          EndDocPrinter_(hPrinter);
          ClosePrinter_(hPrinter);
          Result=#False
        EndIf
        ; Send the Data To the printer.
        If WritePrinter_( hPrinter, lpData, dwCount,@dwBytesWritten)=0
       
          EndPagePrinter_(hPrinter)
          EndDocPrinter_(hPrinter)
          ClosePrinter_(hPrinter)
         Result=#False
        EndIf
       
        ; End the page.
        If EndPagePrinter_(hPrinter) = 0
          EndDocPrinter_(hPrinter)
          ClosePrinter_(hPrinter)
          Result=#False
        EndIf
        ; Inform the spooler that the document is ending.
        If EndDocPrinter_(hPrinter) = 0
          ClosePrinter_(hPrinter)
          Result=#False
        EndIf
        ; Tidy up the printer handle.
        ClosePrinter_(hPrinter);
        ; Check To see If correct number of bytes were written.
        If dwBytesWritten = dwCount
          Result=#False
        EndIf
        Result=#True

          ProcedureReturn Result
       
      EndProcedure
     ;Ab Hier Datei angeben, die gedruckt werden soll
     ;
      ;Drucker.s="PDF Professionell"
      Drucker.s="HP Color LaserJet 2800 Series PS"
     If ReadFile(0,"Test.pdf")
      Anz.l=Lof(0) 
      *Mem=AllocateMemory(Anz)
       laenge.l=ReadData(0,*Mem,Anz)
     Debug laenge
       Debug RawDataToPrinter(Drucker,*Mem ,laenge)
     
      CloseFile(0)
      FreeMemory(*Mem)
    EndIf
Moderation: Code in <Code> gesteckt.
Antworten