Reinen Text per USB an Brailledrucker senden

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    Reinen Text per USB an Brailledrucker senden

    Hallo,

    ich habe einen Brailledrucker, der über Parallel, Seriell, TCP/IP und USB angesteuert werden kann. Bis auf USB funktionieren die anderen Wege. Es wird ein String erzeugt, der jeweils an die Schnittstelle gesendet wird. Dieser Drucker stanzt dann eine Grafik aus Braillepunkten in das Papier.

    Nun möchte ich, dass auch über USB gedruckt werden soll. Der Treiber ist korrekt installiert und der Drucker wird auch angezeigt.

    Der String "Inhalt" besteht aus ASCII-Zeichen, die der Drucker dann als die gewünschte Grafik druckt. Beispielsweise wird ein "g" als 2x2 Punkte gedruckt.

    Über Seriell drucke ich folgendermaßen:

    VB.NET-Quellcode

    1. Dim Anschluesse() As String
    2. Dim Anschluss as String = "Index Basic-D V3"
    3. Anschluesse = IO.Ports.SerialPort.GetPortNames()
    4. If Anschluesse.Length = 0 Then
    5. Exit Sub
    6. End If
    7. For X As Integer = 0 To Anschluesse.Length - 1
    8. If Anschluesse(X).ToString.ToUpper = Anschluss.ToUpper Then
    9. Try
    10. SeriellerAnschluss.PortName = Anschluesse(X)
    11. SeriellerAnschluss.BaudRate = CInt(Baudrate)
    12. SeriellerAnschluss.DataBits = CInt(Datenbits)
    13. If Stopbit = My.Resources.Keine Then
    14. SeriellerAnschluss.StopBits = IO.Ports.StopBits.None
    15. Else
    16. SeriellerAnschluss.StopBits = IO.Ports.StopBits.One
    17. End If
    18. Select Case Paritaet.ToUpper
    19. Case My.Resources.Keine.ToUpper
    20. SeriellerAnschluss.Parity = IO.Ports.Parity.None
    21. Case My.Resources.Ungerade.ToUpper
    22. SeriellerAnschluss.Parity = IO.Ports.Parity.Odd
    23. Case My.Resources.Gerade.ToUpper
    24. SeriellerAnschluss.Parity = IO.Ports.Parity.Even
    25. Case My.Resources.Markierung.ToUpper
    26. SeriellerAnschluss.Parity = IO.Ports.Parity.Mark
    27. Case My.Resources.Leerzeichen.ToUpper
    28. SeriellerAnschluss.Parity = IO.Ports.Parity.Space
    29. End Select
    30. SeriellerAnschluss.DtrEnable = True
    31. SeriellerAnschluss.RtsEnable = True
    32. Select Case Handshake
    33. Case My.Resources.Keine
    34. SeriellerAnschluss.Handshake = IO.Ports.Handshake.None
    35. Case "XOn/XOff"
    36. SeriellerAnschluss.Handshake = IO.Ports.Handshake.RequestToSendXOnXOff
    37. Case "Hardware"
    38. SeriellerAnschluss.Handshake = IO.Ports.Handshake.RequestToSend
    39. End Select
    40. If SeriellerAnschluss.IsOpen Then
    41. SeriellerAnschluss.Close()
    42. End If
    43. SeriellerAnschluss.Open()
    44. SeriellerAnschluss.Write(Inhalt & vbNewLine)
    45. SeriellerAnschluss.Close()


    Eine herkömmliche Grafik drucke ich folgendermaßen auf einem normalen Drucker:

    VB.NET-Quellcode

    1. 'Die zu druckende Grafik wird inclusive der Ränder auf die Druckseite kopiert. Danach wird die Druckseite ins Hochformat gedreht und schließlich
    2. 'ausgedruckt.
    3. DruckseitePuffer = New Bitmap(Seitenbreite, Seitenhoehe)
    4. Druckseiteobjekt = Graphics.FromImage(DruckseitePuffer)
    5. Druckseiteobjekt.Clear(Drawing.Color.White)
    6. If Bild = "Originalbild" Then
    7. Druckseiteobjekt.DrawImage(OriginalbildBitmap, New Rectangle(LinkerRand, ObererRand, DruckseitePuffer.Width - LinkerRand - RechterRand, DruckseitePuffer.Height - ObererRand - UntererRand), New Rectangle(0, 0, OriginalbildBitmap.Width, OriginalbildBitmap.Height), GraphicsUnit.Pixel)
    8. Else
    9. Using Ausgefuellt = New SolidBrush(Drawing.Color.Black)
    10. For X As Integer = 0 To PunktbildArray.GetUpperBound(0)
    11. For Y As Integer = 0 To PunktbildArray.GetUpperBound(1)
    12. If PunktbildArray(X, Y) > HelligkeitScroll.Value Then
    13. Druckseiteobjekt.FillEllipse(Ausgefuellt, New Rectangle(CInt((LinkerRand + (X * Punktgroesse) + (Punktgroesse / 10))), CInt(ObererRand + ((Y * Punktgroesse) + (Punktgroesse / 10))), CInt(Punktgroesse * 0.8), CInt(Punktgroesse * 0.8)))
    14. End If
    15. Next
    16. Next
    17. End Using
    18. End If
    19. If Grafikausrichtung = 1 Then
    20. DruckseitePuffer.RotateFlip(RotateFlipType.Rotate270FlipNone)
    21. End If
    22. DruckerObjekt.PrinterSettings.PrinterName = Farbdrucker
    23. DruckerObjekt.Print()


    Folgendes habe ich, leider Erfolglos versucht:

    VB.NET-Quellcode

    1. 'Die zu druckende Grafik wird inclusive der Ränder auf die Druckseite kopiert. Danach wird die Druckseite ins Hochformat gedreht und schließlich
    2. 'ausgedruckt.
    3. DruckseitePuffer = New Bitmap(Seitenbreite, Seitenhoehe)
    4. Druckseiteobjekt = Graphics.FromImage(DruckseitePuffer)
    5. Druckseiteobjekt.Clear(Drawing.Color.White)
    6. 'Hier die entsprechende Seite füllen
    7. Dim lBrush = New SolidBrush(System.Drawing.Color.Black)
    8. Dim lFontNorm As Font = New Font("Arial", 10)
    9. 'Umstellen der Maßeinheit auf Millimeter
    10. Druckseiteobjekt.PageUnit = GraphicsUnit.Millimeter
    11. Druckseiteobjekt.DrawString("Hallo Welt", lFontNorm, lBrush, 10, 10)
    12. DruckerObjekt.PrinterSettings.PrinterName = Farbdrucker
    13. DruckerObjekt.Print()


    Es erscheint folgende Fehlermeldung:
    "System.ComponentModel.Win32Exception: "Der an einen Systemaufruf übergebene Datenbereich ist zu klein"

    Hat jemand eine Idee, woran das liegt oder wie ich einen reinen String an einen Drucker senden kann, ohne ihn vorher auf eine PrintPage malen zu müssen?

    Vielen Dank
    Ich schicke auch blanke Strings an einen Etikettendrucker. Die einzige Klasse in meiner Sammlung, die ich nie angefasst habe, also vermutlich sehr altbacken.

    Habe mal geschaut, ob ich was dazu finde. Hier auch was ähnliches aus 2011, vermutlich aus derselben Quelle, welche ich allerdings nicht kenne.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Rawprinter
    2. Public Structure DOCINFO
    3. <MarshalAs(UnmanagedType.LPWStr)> Public DocumentName As String
    4. <MarshalAs(UnmanagedType.LPWStr)> Public OutputFile As String
    5. <MarshalAs(UnmanagedType.LPWStr)> Public DataType As String
    6. End Structure
    7. <DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall)>
    8. Private Shared Function OpenPrinter(ByVal pPrinterName As String, ByRef phPrinter As IntPtr, ByVal pDefault As Integer) As Long
    9. End Function
    10. <DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall)>
    11. Private Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal Level As Integer, ByRef pDocInfo As DOCINFO) As Long
    12. End Function
    13. <DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    14. Private Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Long
    15. End Function
    16. <DllImport("winspool.drv", CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    17. Private Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal data As String, ByVal buf As Integer, ByRef pcWritten As Integer) As Long
    18. End Function
    19. <DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    20. Private Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Long
    21. End Function
    22. <DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    23. Private Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Long
    24. End Function
    25. <DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    26. Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Long
    27. End Function
    28. Public Shared Sub SendToPrinter(ByVal printerJobName As String, ByVal rawStringToSendToThePrinter As String, ByVal printerNameAsDescribedByPrintManager As String)
    29. Dim handleForTheOpenPrinter = New IntPtr()
    30. Dim documentInformation = New DOCINFO()
    31. Dim printerBytesWritten = 0
    32. documentInformation.DocumentName = printerJobName
    33. documentInformation.DataType = vbNullString
    34. documentInformation.OutputFile = vbNullString
    35. OpenPrinter(printerNameAsDescribedByPrintManager, handleForTheOpenPrinter, 0)
    36. StartDocPrinter(handleForTheOpenPrinter, 1, documentInformation)
    37. StartPagePrinter(handleForTheOpenPrinter)
    38. WritePrinter(handleForTheOpenPrinter, rawStringToSendToThePrinter, rawStringToSendToThePrinter.Length, printerBytesWritten)
    39. EndPagePrinter(handleForTheOpenPrinter)
    40. EndDocPrinter(handleForTheOpenPrinter)
    41. ClosePrinter(handleForTheOpenPrinter)
    42. End Sub
    43. End Class
    Sorry, aber ich war über das Wochenende nicht da. Daher konnte ich erst heute deine Nachricht lesen.

    Erst einmal vielen Dank dafür. Kannst du mir auch schreiben, wie du die Funktion aufrufst? Bei mir möchte er einen PrinterJobnamen haben.

    VB.NET-Quellcode

    1. Dim Erledigt As Boolean
    2. Erledigt = Brailleprinter.SendToPrinter(Brailledrucker, Inhalt)


    Ich habe den Klassennamen geändert.
    In der Variablen "Brailledrucker" steht der im System registrierte Name des Druckers.
    Die Variable "Inhalt" enthält den zu druckenden Text.
    Danke, habe ich jetzt getestet. Die Funktionen laufen ohne Fehler durch, allerdings wird nichts gedruckt. Das gute daran ist, dass es syntaktisch korrekt ist, aber ich noch nicht die richtige Schreibweise der Zeichenfolge gefunden habe. Ich habe es bereits mit "Nur Text" und auch mit den entsprechenden vorangestellten ESC-Sequenzen versucht. Gestern habe ich auch den Vertreiber angeschrieben und um Unterstützung angefragt. Nachher werde ich mal nach Infos direkt vom Hersteller suchen, was wahrscheinlich nicht so einfach sein wird.

    Normalerweise empfängt ein Brailledrucker reinen ASCII-Code und druckt dann die entsprechenden Punktmuster für die einzelnen Zeichen aus.