[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Print international charaters in Epson Tm-T70

Posted on 2013-05-16
9
Medium Priority
?
2,973 Views
Last Modified: 2013-05-17
When I print international characters on Epson POS Tm-T20 i have no problem using the class RawPrinterHelper. However when printing on Epson Tm-T70 does not print international characters. But using eg. Chr(128) prints the "Ç" character on TM-T70, correctly.
0
Comment
Question by:rflorencio
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
9 Comments
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 39171562
Can you show us code you use to send strings to printer?
0
 

Author Comment

by:rflorencio
ID: 39171625
This is the code:

In Dim b1 As String = "ÇÇÇÇÇÇÇÇÇ" & Chr(128) code, "ÇÇÇÇÇÇÇÇÇ" prints a odd character  and Chr(128) prints correctly.


Call RawPrinterClass

      Dim b As Integer = 50

        Dim b1 As String = "ÇÇÇÇÇÇÇÇÇ" & Chr(128)

        Dim s As String
        ''-------------------------------------------------
        s = sess_PT_CHAR1
        s &= "  .: Example :. " & vbCrLf
        s &= "================================" & vbCrLf
        s &= "   EXAMPLE    " & vbCrLf
        s &= b1 & Space(1) & b.ToString & vbCrLf
        s &= sess_EPSON_BOLD_ON
        s &= "* * * END * * *"
        s &= sess_EPSON_BOLD_OFF
        s &= "" & vbCrLf
        s &= "" & vbCrLf
        s &= "" & vbCrLf
        s &= "" & vbCrLf
        s &= "" & vbCrLf
        s &= "" & vbCrLf
        s &= sess_CUT_PAPER
        s &= sess_OPEN_CASH
        Dim xPrintText As New RawPrinterHelper(s)

'-----------------------------------------------------------------------------------


RawPrinterClass
'-----------------------------------------------------------------------------------
Imports System.IO
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices

Public Class RawPrinterHelper
    Public Shared ESC As String = Convert.ToString(ChrW(27))
    Public Shared sess_ESC As String = ChrW(27) + "!"
    Public Shared sess_EPSON_BOLD_ON As String = sess_ESC + Chr(16) + sess_ESC + Chr(32)
    Public Shared sess_EPSON_BOLD_OFF As String = sess_ESC + Chr(0) + sess_ESC + Chr(0)
    Public Shared sess_CUT_PAPER As String = ESC & "@" & ChrW(29) & "V" & ChrW(1)
    Public Shared sess_OPEN_CASH As String = Chr(27) & Chr(112) & Chr(48) & Chr(64) & Chr(64)

Public Shared sess_PT_CHAR As String = Chr(27) & Chr(116) & Chr(0)
'--------------------------------------------------



    ' 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 Integer, ByVal pd As Integer) As Boolean
    End Function
    ' Este código estava a dar um erro foi actualizado nas na framework 4.0 e posterior
    'Public Shared Function OpenPrinter(ByVal src As String, ByRef hPrinter As Integer, 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 Boolean
    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

    ' SendBytesToPrinter()
    ' When the function is given a printer name and an unmanaged array of
    ' bytes, the function sends those bytes to the print queue.
    ' Returns True on success or False on failure.
    Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
        Dim hPrinter As IntPtr      ' The printer handle.
        Dim dwError As Int32        ' Last error - in case there was trouble.
        Dim di As DOCINFOW          ' Describes your document (name, port, data type).
        Dim dwWritten As Int32      ' The number of bytes written by WritePrinter().
        Dim bSuccess As Boolean     ' Your success code.

        ' Set up the DOCINFO structure.
        With di
            .pDocName = "My Visual Basic .NET RAW Document"
            .pDataType = "RAW"
        End With
        ' Assume failure unless you specifically succeed.
        bSuccess = False
        If OpenPrinter(szPrinterName, hPrinter, 0) Then
            If StartDocPrinter(hPrinter, 1, di) Then
                If StartPagePrinter(hPrinter) Then
                    ' Write your printer-specific bytes to the printer.
                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
                    EndPagePrinter(hPrinter)
                End If
                EndDocPrinter(hPrinter)
            End If
            ClosePrinter(hPrinter)
        End If
        ' If you did not succeed, GetLastError may give more information
        ' about why not.
        If bSuccess = False Then
            dwError = Marshal.GetLastWin32Error()
        End If
        Return bSuccess
    End Function ' SendBytesToPrinter()

    ' SendFileToPrinter()
    ' When the function is given a file name and a printer name,
    ' the function reads the contents of the file and sends the
    ' contents to the printer.
    ' Presumes that the file contains printer-ready data.
    ' Shows how to use the SendBytesToPrinter function.
    ' Returns True on success or False on failure.
    Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean
        ' Open the file.
        Dim fs As New FileStream(szFileName, FileMode.Open)
        ' Create a BinaryReader on the file.
        Dim br As New BinaryReader(fs)
        ' Dim an array of bytes large enough to hold the file's contents.
        Dim bytes(fs.Length) As Byte
        Dim bSuccess As Boolean
        ' Your unmanaged pointer.
        Dim pUnmanagedBytes As IntPtr

        ' Read the contents of the file into the array.
        bytes = br.ReadBytes(fs.Length)
        ' Allocate some unmanaged memory for those bytes.
        pUnmanagedBytes = Marshal.AllocCoTaskMem(fs.Length)
        ' Copy the managed byte array into the unmanaged array.
        Marshal.Copy(bytes, 0, pUnmanagedBytes, fs.Length)
        ' Send the unmanaged bytes to the printer.
        bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, fs.Length)
        ' Free the unmanaged memory that you allocated earlier.
        Marshal.FreeCoTaskMem(pUnmanagedBytes)
        Return bSuccess
    End Function ' SendFileToPrinter()

    ' When the function is given a string and a printer name,
    ' the function sends the string to the printer as raw bytes.
    Public Shared Function SendStringToPrinter(ByVal szPrinterName As String, ByVal szString As String)
        Dim pBytes As IntPtr
        Dim dwCount As Int32
        ' How many characters are in the string?
        dwCount = szString.Length()
        ' Assume that the printer is expecting ANSI text, and then convert
        ' the string to ANSI text.
        pBytes = Marshal.StringToCoTaskMemAnsi(szString)
        ' Send the converted ANSI string to the printer.
        SendBytesToPrinter(szPrinterName, pBytes, dwCount)
        Marshal.FreeCoTaskMem(pBytes)
    End Function
    Public Sub New(TextToPrint As String)
        ' TextToPrint - Sequencia de Escape a enviar para impressora ou texto a imprimir
        Dim pd As New PrintDialog()
        ' Open the printer dialog box, and then allow the user to select a printer.
        pd.PrinterSettings = New PrinterSettings()
        If (pd.ShowDialog() = DialogResult.OK) Then
            RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, TextToPrint)
        End If
    End Sub
End Class

Open in new window

0
 
LVL 16

Expert Comment

by:DansDadUK
ID: 39174051
The "Ç" (capital C with cedilla accent) character is defined at Unicode code-point U+00C7.
Unicode is used on most modern operating systems as the "internal" character coding mechanism.

Most printers do not use Unicode directly (since it requires 16-bit character codes), but instead map various 8-bit coded character sets to different sets of (up to 256) glyphs.

The 8-bit coded character set which corresponds directly to the first 256 Unicode code-points is the ISO-8859-1 Latin-1 set, so in this set, the "Ç" character is represented by character-code (hexadecimal) 0xC7, or decimal 199.

The fact that you get the required character printed with a character-code of (decimal) 128 implies that the printer is assuming a coded-character set other than ISO-8859-1.

I'm not familiar with either VB or the Epson printer language, so I don't know how to advise you to select a different coded-character-set on the printer, but I think that this is what you need to do.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 16

Expert Comment

by:DansDadUK
ID: 39174066
The Tm-T70 manual (see http://www.juta-soft.hu/pdf/egyeb%20eszkozok/epson%20tm-t70%20felhasznaloi%20kezikonyv.pdf ) refers to use of different character code tables.

Appendix C.1 Page 0 (PC437: USA, Standard Europe (International character set: when “America” is selected)) maps 0x80 (decimal 128) to the "Ç" glyph.

Appendix C.7 Page 16 (WPC1252) maps 0xC7 (decimal 199) to the "Ç" glyph.

This 'code page' appears to be the equivalent of the Windows Latin-1 (codepage 1252) coded character set (which is a superset of ISO-8859-1 (in that graphic characters are assigned to code-points in the range 0x80-0x9F which (in ISO-8859-1) are assigned to the (rarely used) C1 control-code characters).
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 39174358
What happens if you change

pBytes = Marshal.StringToCoTaskMemAnsi(szString)

to

pBytes = Marshal.StringToCoTaskMemUni(szString)

Or

pBytes = Marshal.StringToCoTaskMemAuto(szString)
0
 

Author Comment

by:rflorencio
ID: 39174682
CodeCruiser,
If change code only first line is printed.

My problem is that I can do almost everything cut paper, put into expanded, etc.. I can not "say" to printer which is the character table to use. Do not accept this escape sequence
Chr(27) & Chr(116) & Chr(0).
0
 
LVL 16

Accepted Solution

by:
DansDadUK earned 2000 total points
ID: 39174768
Surely you need to send the Esc/Pos escape sequence:
Chr(27) & Chr(116) & Chr(16)
to select table 16 (cp1252); selecting table 0 (as per your sequence) will just reselect the American table, which appears to be the default.
0
 

Author Comment

by:rflorencio
ID: 39174931
DansDadUK one more thing,

In fact your sequence works in perfection. However if I put Chr(27) & Chr(116) & Chr(3), also should work with accented characters (or not)?
0
 
LVL 16

Expert Comment

by:DansDadUK
ID: 39175244
Table 3 appears to be code page 860 (Portuguese), which is one of the old National Language Variant sets; it does indeed contain a number of accented characters, but:

- C-cedilla is represented by 0x80 (so your back to the same problem as with the default table 0 character set.

- Code page 1252 (as represented by table 16) matches the 8-bit coded character set used by Windows systems and (apart from the C1 control-code range) that used by *n*x systems as well.
I.e. it matches the character encoding used on your workstation, so it doesn't really make sense to use any other 8-bit set if you want to use characters which are not in the 7-bit ASCII subset.
Of course, if you want to use non-Western languages (e.g. Cyrillic or Thai) then you'd need a different character set or (more likely these days) use Unicode (either UCS-2 or UTF-8 representations), but not all printers support Unicode directly (the Tm-T70 certainly doesn't appear to).
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
This article shows how to get a list of available printers for display in a drop-down list, and then to use the selected printer to print an Access report or a Word document filled with Access data, using different syntax as needed for working with …
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question