Έκανα κάποιες αλλαγές στον κώδικα για να δούμε ελληνικά. Επειδή δεν έχω dot matrix εκτυπωτή στο σπίτι, αν μπορεί κάποιος να επιβεβαιώσει ότι παίζει σωστά.
Εν αρχή έχουμε την κλάση RawPrinterHelper
Imports System.IO
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Imports System.Text
Public Class RawPrinterHelper
Private mvarInitialized As Boolean
Private mvarDeviceName As String
Private thisPrinterHandler As IntPtr
Private thisDocumentHandler As IntPtr
Private thisDocInfo As DOCINFOW
' Structure and API declarions:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Structure DOCINFOW
<MarshalAs(UnmanagedType.LPWStr)> Public pDocName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pOutputFile As String
<MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String
End Structure
<DllImport("winspool.Drv", EntryPoint:="OpenPrinterW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function OpenPrinter(ByVal src As String, ByRef hPrinter As IntPtr, ByVal pd As Long) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, ByRef pDI As DOCINFOW) As IntPtr
End Function
<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="WritePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByRef dwWritten As Int32) As Boolean
End Function
Public ReadOnly Property DocumentName() As String
Get
DocumentName = thisDocInfo.pDocName
End Get
End Property
Public ReadOnly Property DocumentDatatype() As String
Get
DocumentDatatype = thisDocInfo.pDataType
End Get
End Property
Public ReadOnly Property DocumentOutputFile() As String
Get
DocumentOutputFile = thisDocInfo.pOutputFile
End Get
End Property
Public ReadOnly Property DocumentHandler() As IntPtr
Get
DocumentHandler = thisDocumentHandler
End Get
End Property
Public ReadOnly Property PrinterHandler() As IntPtr
Get
PrinterHandler = thisPrinterHandler
End Get
End Property
Public ReadOnly Property DeviceName() As String
Get
DeviceName = mvarDeviceName
End Get
End Property
Public ReadOnly Property Initialized() As Boolean
Get
Initialized = mvarInitialized
End Get
End Property
Public Sub New()
MyBase.New()
mvarInitialized = False
End Sub
Protected Overrides Sub Finalize()
If Me.Initialized Then
Call EndDocPrinter(thisPrinterHandler)
Call ClosePrinter(thisPrinterHandler)
End If
MyBase.Finalize()
End Sub
Public Function Initialize(ByVal PrinterName As String) As Integer
Initialize = OpenPrinter(PrinterName, thisPrinterHandler, 0)
If Initialize = 0 Then
Err.Raise(vbObjectError, "WinPrinter.RawPrinterHelper", "Δεν είναι δυνατόν να ενεργοποιηθεί ο εκτυπωτής.")
Exit Function
End If
thisDocInfo.pDocName = "WinPrinter Document"
thisDocInfo.pOutputFile = Nothing
thisDocInfo.pDataType = "RAW"
thisDocumentHandler = StartDocPrinter(thisPrinterHandler, 1, thisDocInfo)
mvarInitialized = True
End Function
Public Function PageBegin() As Integer
PageBegin = StartPagePrinter(thisPrinterHandler)
End Function
Public Function PageEnd() As Integer
PageEnd = EndPagePrinter(thisPrinterHandler)
End Function
Public Function SendLine(ByVal sData As String) As Integer
SendLine = Me.Send(sData & vbCrLf)
End Function
Public Function Send(ByVal sData As String) As Integer
Dim lpcWritten As Integer
Dim pData As IntPtr
pData = Marshal.AllocCoTaskMem(sData.Length())
Marshal.Copy(ConvertToOEM(sData), 0, pData, sData.Length())
Send = WritePrinter(thisPrinterHandler, pData, sData.Length(), lpcWritten)
Marshal.FreeCoTaskMem(pData)
End Function
Public Function SendNewLine() As Integer
SendNewLine = Me.Send(vbCrLf)
End Function
Public Function SendNewPage() As Integer
SendNewPage = Me.Send(Chr(12))
End Function
Private Function ConvertToOEM(ByRef sData As String) As Byte()
Dim enc_OEM As System.Text.Encoding = Encoding.GetEncoding(737)
Dim enc_Windows As System.Text.Encoding = Encoding.Unicode
ConvertToOEM = Encoding.Convert(enc_Windows, enc_OEM, enc_Windows.GetBytes(sData))
End Function
End Class
Αυτή την κλάση θα μπορούσαμε να την καλέσουμε από κάποιο σημείο του προγραμματός μας ως εξής:
Dim o As RawPrinterHelper
o = New RawPrinterHelper
If Not cmbPrinters.SelectedIndex > -1 Then
MsgBox("Επιλέξτε ένα εκτυπωτή!", MsgBoxStyle.Exclamation)
Exit Sub
End If
o.Initialize(cmbPrinters.Text)
If Not o.Initialized Then
Exit Sub
End If
o.PageBegin()
o.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
o.SendNewPage()
o.PageEnd()
o = Nothing
Η χρήση είναι αρκετά απλή, αλλά μιας και δεχόμαστε ότι οι printer είναι είτε IBM είτε EPSON συμβατοί, μπορούμε κάνοντας inherit την RawPrinterHelper να βάλουμε λίγο κώδικα ακόμα που θα βοηθούσε να τυπωθούν τα Bold/Italics/Underline/DoubleWidth πιο εύκολα. Έστω ότι νέα κλάση TextPrinter:
Public Class TextPrinter
Inherits RawPrinterHelper
Public Enum PrinterMode
Epson_Compatible
IBM_Compatible
End Enum
Private mvarMode As PrinterMode
Private mvarBold As Boolean
Private mvarDoubleHeight As Boolean
Private mvarDoubleWidth As Boolean
Private mvarItalics As Boolean
Private mvarUnderline As Boolean
Public Property Mode() As PrinterMode
Get
Mode = mvarMode
End Get
Set(ByVal Value As PrinterMode)
mvarMode = Value
End Set
End Property
Public Property Bold() As Boolean
Get
Bold = mvarBold
End Get
Set(ByVal Value As Boolean)
'
'27 69 ESC E Emphasised (bold) printing on (overprinted with sideways shift)
'27 70 ESC F Emphasised (bold) printing off
'
mvarBold = Value
If Value = True Then
Call Me.Send(Chr(27) & Chr(69))
Else
Call Me.Send(Chr(27) & Chr(70))
End If
End Set
End Property
Public Property DoubleHeight() As Boolean
Get
DoubleHeight = mvarDoubleHeight
End Get
Set(ByVal Value As Boolean)
'
'27 119 48 ESC w 0 Double-height off ESC/P
'27 119 49 ESC w 1 Double-height on ESC/P
'
mvarDoubleHeight = Value
If Value = True Then
If Me.Mode = PrinterMode.IBM_Compatible Then
'Call Me.Send(Chr(27) & Chr(37) & Chr(71))
Else
Call Me.Send(Chr(27) & Chr(119) & Chr(49))
End If
Else
If Me.Mode = PrinterMode.IBM_Compatible Then
'Call Me.Send(Chr(27) & Chr(37) & Chr(72))
Else
Call Me.Send(Chr(27) & Chr(119) & Chr(48))
End If
End If
End Set
End Property
Public Property DoubleWidth() As Boolean
Get
DoubleWidth = mvarDoubleWidth
End Get
Set(ByVal Value As Boolean)
'
'27 87 48 ESC W 0 • Enlarged (double-width) printing off
'27 87 49 ESC W 1 • Enlarged (double-width) printing on
'
mvarDoubleWidth = Value
If Value = True Then
Call Me.Send(Chr(27) & Chr(87) & Chr(49))
Else
Call Me.Send(Chr(27) & Chr(87) & Chr(48))
End If
End Set
End Property
Public Property Italics() As Boolean
Get
Italics = mvarItalics
End Get
Set(ByVal Value As Boolean)
'
'27 37 71 ESC % G Italic printing on IBM
'27 37 72 ESC % H Italic printing off IBM
'27 52 ESC 4 Italic characters on ESC/P
'27 53 ESC 5 Italic characters off ESC/P
'
mvarItalics = Value
If Value = True Then
If Me.Mode = PrinterMode.IBM_Compatible Then
Call Me.Send(Chr(27) & Chr(37) & Chr(71))
Else
Call Me.Send(Chr(27) & Chr(52))
End If
Else
If Me.Mode = PrinterMode.IBM_Compatible Then
Call Me.Send(Chr(27) & Chr(37) & Chr(72))
Else
Call Me.Send(Chr(27) & Chr(53))
End If
End If
End Set
End Property
Public Property Underline() As Boolean
Get
Underline = mvarUnderline
End Get
Set(ByVal Value As Boolean)
'
'27 45 48 ESC - 0 Underlining off
'27 45 49 ESC - 1 Underlining on
'
mvarUnderline = Value
If Value = True Then
Call Me.Send(Chr(27) & Chr(45) & Chr(49))
Else
Call Me.Send(Chr(27) & Chr(45) & Chr(48))
End If
End Set
End Property
Public Sub New()
MyBase.New()
mvarMode = PrinterMode.IBM_Compatible
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
End Class
Και demo κώδικας χρήσης:
Dim textPrinter As TextPrinter
textPrinter = New TextPrinter
textPrinter.Initialize(cmbPrinters.Text)
If Not textPrinter.Initialized Then
Exit Sub
End If
textPrinter.Mode = PrinterMode.Epson_Compatible
textPrinter.PageBegin()
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.Bold = True
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.Bold = False
textPrinter.DoubleHeight = True
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.DoubleHeight = False
textPrinter.DoubleWidth = True
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.DoubleWidth = False
textPrinter.Italics = True
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.Italics = False
textPrinter.Underline = True
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.Underline = False
textPrinter.SendLine("Θέλει αρετή και τόλμη η ελευθερία.")
textPrinter.SendNewPage()
textPrinter.PageEnd()
textPrinter = Nothing
George J.