Yes. They are called "Escape characters" because they are non printable
characters. When the printer gets one, it interprets it as a command
instead of as output text.
This code is from my POS system bravopos (see
www.bravopos.com). Verified
working (we've been testing for like two years because I can't figure out
what to do with it hehe).
It's in VB6, but it should give you a clear starting point to PInvoke from,
because the process is the same. My target printer set was the Star line of
printers. I haven't tried it on anything else, but I have verified it works
under Star. This COM+ object sits on a Win2K server and directs output
appropriately to printers.
Note that the pop command is coming from the server in this example.
The "meat" of the code you will need is in the exec_POSCommand. You'll
notice I went through some of the same problems you are going through,
because in the database I'm storing a "control char" and then translating it
to the appropriate escape code sequence. If you have multiple cash drawers,
you can set them to respond differently A, B... etc.
If you have trouble converting it to .NET, please let me know and I'll lend
a hand.
'---------------------------------------------------------------------------
----
' File Name cCashDrawer.c
'
' Description Business Object that handles all Cash Drawer operations
'
'
' Comments
'
'
'
'
'
'
'
' Date Modified
'---------------------------------------------------------------------------
----
' 01/10/2002 Justin Weinberg Class Created
'---------------------------------------------------------------------------
----
Private Const THIS_MODULE = "BOCashDrawers.cCashDrawer"
Private Const sBravoTempConnect = "File Name=c:\Bravo\UDL\BravoTemp.udl"
Public Enum EnumCashDrawerErrors
ePrinterNotFound = vbObjectError + 1024
End Enum
Public Type DOCINFO
pDocName As String
pOutputFile As String
pDatatype As String
End Type
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal _
hPrinter As Long) As Long
Private Declare Function EndDocPrinter Lib "winspool.drv" (ByVal _
hPrinter As Long) As Long
Private Declare Function EndPagePrinter Lib "winspool.drv" (ByVal _
hPrinter As Long) As Long
Private Declare Function OpenPrinter Lib "winspool.drv" Alias _
"OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, _
ByVal pDefault As Long) As Long
Private Declare Function StartDocPrinter Lib "winspool.drv" Alias _
"StartDocPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, _
pDocInfo As DOCINFO) As Long
Private Declare Function StartPagePrinter Lib "winspool.drv" (ByVal _
hPrinter As Long) As Long
Private Declare Function WritePrinter Lib "winspool.drv" (ByVal _
hPrinter As Long, pBuf As Any, ByVal cdBuf As Long, _
pcWritten As Long) As Long
Private Declare Function Escape Lib "Gdi32" (ByVal hDC As Long, ByVal
nEscape As Long, _
ByVal ncount As Long, ByVal indata As String, ByVal oudata As Any)
As Integer
Private Sub exec_POSCommand(sPrinter As String, sControlChar As String)
Dim lhPrinter As Long
Dim lReturn As Long
Dim lpcWritten As Long
Dim lDoc As Long
Dim sControlString As String
Dim DocInfo_Drawer As DOCINFO
On Error GoTo common_error
Select Case sControlChar
'Control char and Hexadeciaml ESC/POS printer codes
Case "A" ' \x1B \x07 \x05 \x05 \x07 --> &H1b &H07 &H05 &H05 &H07
sControlString = Chr(&H1B) & Chr(&H7) & Chr(&H5) & Chr(&H5) & Chr(&H7)
Case "B" '\x1B \x07 \x0A \x0A \x07 --> &H1b &H07 &H0A &H0A &H07
sControlString = Chr(&H1B) & Chr(&H7) & Chr(&HA) & Chr(&HA) & Chr(&H7)
Case "C" '\x1B \x07 \x0F \x0F \x07 --> &H1b &H07 &H0F &H0F &H07
sControlString = Chr(&H1B) & Chr(&H7) & Chr(&HF) & Chr(&HF) & Chr(&H7)
Case "D" '\x1B \x07 \x14 \x14 \x07 --> &H1b &H07 &H14 &H14 &H07
sControlString = Chr(&H1B) & Chr(&H7) & Chr(&H14) & Chr(&H14) & Chr(&H7)
Case "E" '\x1B \x07 \x19 \x19 \x07 -> &H1b &H07 &H19 &H19 &H07
sControlString = Chr(&H1B) & Chr(&H7) & Chr(&H19) & Chr(&H19) & Chr(&H7)
Case "d" '\x1A --> &H1A
sControlString = Chr(&H1A)
End Select
lReturn = OpenPrinter(sPrinter, lhPrinter, 0)
If lReturn = 0 Then
Err.Raise ePrinterNotFound, Err.Source, Err.Description
Exit Sub
End If
With DocInfo_Drawer
.pDocName = "CashPop"
.pOutputFile = vbNullString
.pDatatype = vbNullString
End With
lDoc = StartDocPrinter(lhPrinter, 1, DocInfo_Drawer)
lDoc = StartPagePrinter(lhPrinter)
'Preparate for the ESC/POS command.
lReturn = WritePrinter(lhPrinter, ByVal sControlString,
Len(sControlString), lpcWritten)
lReturn = EndPagePrinter(lhPrinter)
lReturn = EndDocPrinter(lhPrinter)
lReturn = ClosePrinter(lhPrinter)
common_exit:
Exit Sub
common_error:
Err.Raise Err.Number, THIS_MODULE, Err.Description
End Sub
'---------------------------------------------------------------------------
----
' Retrieves the cash drawer in XML format
'---------------------------------------------------------------------------
----
Private Function XML_CashDrawers_RetrieveForPop(ByVal CashDrawerID As Long)
As String
Const THIS_METHOD = "XML_CashDrawers_RetrieveForPop"
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim oStream As ADODB.Stream
Dim oParam As ADODB.Parameter
On Error GoTo common_error
Set cmd = New ADODB.Command
Set oStream = New ADODB.Stream
Set oParam = New ADODB.Parameter
Set conn = New ADODB.Connection
With oParam
.Name = "ID"
.Direction = adParamInput
.Value = CashDrawerID
.Type = adInteger
.Size = 4
End With
conn.Open sBravoTempConnect
oStream.Open
With cmd
.ActiveConnection = conn
.Properties("Output Stream") = oStream
.CommandType = adCmdStoredProc
.CommandText = "XML_CashDrawers_RetrieveForPop"
.Parameters.Append oParam
.Execute , , adExecuteStream
End With
XML_CashDrawers_RetrieveForPop = oStream.ReadText()
oStream.Close
conn.Close
GetObjectContext.SetComplete
common_exit:
Set cmd = Nothing
Set oParam = Nothing
Set oStream = Nothing
Set conn = Nothing
Exit Function
common_error:
Set cmd = Nothing
Set oParam = Nothing
Set oStream = Nothing
Set conn = Nothing
Err.Raise Err.Number, THIS_MODULE, Err.Description
End Function
'---------------------------------------------------------------------------
----
'Pops open the cash drawer specified by vCashDrawerID
'---------------------------------------------------------------------------
----
Public Sub CashDrawer_PopDrawer(ByVal CashDrawerID As Long)
Const THIS_METHOD = "CashDrawer_PopDrawer"
Dim DOMDOC As DOMDocument
Dim oCashDrawerNode As IXMLDOMNode
Dim sXML As String
Dim sControlCode As String
Dim sPrinter As String
On Error GoTo common_error
Set DOMDOC = New DOMDocument
sXML = XML_CashDrawers_RetrieveForPop(CLng(CashDrawerID))
DOMDOC.loadXML sXML
Set oCashDrawerNode = DOMDOC.documentElement.childNodes(0)
With oCashDrawerNode.Attributes
sPrinter = .getNamedItem("sPrinter").nodeValue
sControlCode = .getNamedItem("sControlChar").nodeValue
End With
exec_POSCommand sPrinter, sControlCode
common_exit:
Set DOMDOC = Nothing
Set oCashDrawerNode = Nothing
Exit Sub
common_error:
GetObjectContext.SetAbort
App.LogEvent vbNewLine & THIS_MODULE & CStr(Err.Number) & vbTab &
Err.Source & vbTab & Err.Description & " Final Method: " & THIS_METHOD,
vbLogEventTypeError
Resume common_exit
End Sub