qbasic to vb.net conversion help. please.

G

Guest

Here is the short story of what i'm trying to do. I have a 4 sided case
labeling printer setting out on one of our production lines. Now then i have
a vb.net application that sends data to this printer using a RawPrinterHelper
class that i found I believe in the msdn. the class works wonderfully when I
send stright text data (in the correctly formated string that the sato
printer requires.) but when i go to send a image nothing is happening. The
sato book that came with the printer shows me examples how to send a image to
this printer but the only problem is that the examples are in Qbasic. Here
is the example that the book gives me on how to send the job.
OPEN "WIZ.PCX" FOR INPUT AS #2
DA$ = INPUT$(15706,#2)
C$ = chr(27)
WIDTH "LPT1:", 255
LPRINT C$; "A";
LPRINT C$ "V150"; C$; "H100"; C$; "GP15706,"; DA$
LPRINT C$; "Q1"; C$; "Z";
CLOSE #2
so basicly it opens up a pcx image file, and reads its contents into the var
DA and sends it to the printer. all great and fine. but now onward to
converting it to vb.net code. Here is what i have done with it so far.

Dim fs As FileStream = New FileStream("C:\Kosher.pcx", FileMode.Open)
Dim imgData(fs.Length) As Byte
Dim pos As Integer
Dim b As Byte
Dim fileLen As String 'used because file size has to be 5 chars long
my pcx file size occurding to dos is 15464 which is 5 char in len so no
problems
len = fs.Length.ToString

While fs.Length > pos
b = fs.ReadByte
imgData(pos) = b
pos = pos + 1
End While
fs.Close()

'my file is now loaded as a byte array because i can not send a byte array
stright to the printer i have to convert it to a string so i can appened it
to my header information.


'problems start here. I have tried these subs and none seem to work.
Private Function ByteArrayToStringa(ByVal arrInput() As Byte) As String
Dim i As Integer
Dim sOutput As New System.Text.StringBuilder(arrInput.Length)
For i = 0 To arrInput.Length - 1
sOutput.Append(arrInput(i).ToString("X2"))
Next
Return sOutput.ToString()
End Function
Private Function BinaryToString(ByVal bNumber As Byte()) As String
Dim enc As System.Text.ASCIIEncoding
' Have also tried System.Text.UTF8Encoding and UnicodeEncoding
Return enc.GetEncoding("iso-8859-1").GetString(bNumber)
End Function

Public Function ByteArrayToString(ByVal bytArray() As Byte) As String
Dim UTF8 As New System.Text.UTF8Encoding
Return UTF8.GetString(bytArray)
End Function

'after the conversion has taken place create my string to send to the
printer class
dim satoPrintData as string
satoPrintData = Chr(27) & "A" & Chr(27) & "%3" & Chr(27) & _
"H0500" & Chr(27) & "V0500" & Chr(27) & _
"GP" & len & "," & sT & Chr(27) & "Q999999" & Chr(27) & "Z" 'qty to
print and end line

'i get the printer name from a wmi sub when the program first starts up.
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName,
satoPrintData )

can someone please tell me where i'm going wrong.
cheers.
 
N

Nick Malik [Microsoft]

Hi John,

You state:
'my file is now loaded as a byte array because i can not send a byte array
stright to the printer i have to convert it to a string so i can appened
it
to my header information.

Your header data can probably be sent as characters and then the binary data
can be sent to the printer seperately. I'm having trouble downloading the
RawPrinterHelper class at the moment (my internet connection is getting
flakey...) but if you dig into the code, I'm guessing that you can pass
binary data as well.

Your conversion routines will change the binary for the image file. You
don't want to do that.

You need to send the binary to the printer. That's what the QBasic app
does.
--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
G

Guest

here is the raw printer helper class

now I can't just send the image file to the printer cause i need that header
data to make my label (item number etc.) and I don't think i can just append
my header data to the byte array in the sendFileToPrinter class because i
need that as ansi text or can i?
thanks so much for the reply i'm stumped on this problem and i have to get
something working here soon.

Public Class RawPrinterHelper
' 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 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 = "label printer"
.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
End Class
 
N

Nick Malik [Microsoft]

Hi John,

Look at the routine: SendFileToPrinter. You can see that the routine will
open a file and send it in binary to the printer. Clearly, this is the kind
of thing you want to be doing as well.

Why not take that routine and modify it to send your header bytes and then
the contents of the file to the printer?

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
 
G

Guest

Thanks for the help Nick. heres what i have done thus far: but it still
doesn't seem to be working. windows sends the print job ok with no errs, but
my sato printer doesn't seem to do anything with the sent data. any
suggestions?

sending sub:
Dim header As String = Chr(27) & "A" & Chr(27) & "%3" & Chr(27) & _
"H0500" & Chr(27) & "V0500" & Chr(27) & _
"GP0" & len & ","

Dim footer As String = Chr(27) & "Q999999" & Chr(27) & "Z" 'qty to
print and end line
pd.PrinterSettings.PrinterName = _Printer1 'left printer
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName,
Chr(27) & "A" & Chr(27) & "*" & Chr(27) & "Z") 'clear printer
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName,
Chr(27) & "A" & Chr(27) & "CS12" & Chr(27) & "Z") 'increase print size

'NOT WORKING HERE.

RawPrinterHelper.SendSatoFileToPrinter(pd.PrinterSettings.PrinterName,
"C:\Kosher1.pcx", header, footer)

calling subs:
Public Shared Function SendSatoFileToPrinter(ByVal szPrinterName As
String, ByVal szFileName As String, ByVal header As String, ByVal footer 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


'create label header
Dim pBytes As IntPtr
Dim dwCount As Int32
' How many characters are in the string?
dwCount = header.Length()
' Assume that the printer is expecting ANSI text, and then convert
' the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(header)

'create label footer
Dim pBytes1 As IntPtr
Dim dwCount1 As Int32
' How many characters are in the string?
dwCount1 = header.Length()
' Assume that the printer is expecting ANSI text, and then convert
' the string to ANSI text.
pBytes1 = Marshal.StringToCoTaskMemAnsi(footer)

' 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)
SendBytesToPrinter(szPrinterName, pUnmanagedBytes, fs.Length,
pBytes, dwCount, pBytes1, dwCount1)

' Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes)

Marshal.FreeCoTaskMem(pBytes)
Marshal.FreeCoTaskMem(pBytes1)
Return bSuccess
End Function ' SendFileToPrinter()

Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String,
ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByVal pBytes0 As IntPtr,
ByVal dwCount0 As Int32, ByVal pBytes1 As IntPtr, ByVal dwCount1 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 dwWritten1 As Int32 ' The number of bytes written by
WritePrinter().
Dim dwWritten2 As Int32 ' The number of bytes written by
WritePrinter().
Dim bSuccess As Boolean ' Your success code.

' Set up the DOCINFO structure.
With di
.pDocName = "label printer"
.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, pBytes0, dwCount0,
dwWritten1) 'header data

bSuccess = WritePrinter(hPrinter, pBytes, dwCount,
dwWritten) 'image data

bSuccess = WritePrinter(hPrinter, pBytes1, dwCount1,
dwWritten2) 'footer data

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()
 
N

Nick Malik [Microsoft]

You have a minor logic error that may be hiding your error.

You set bSuccess three times in your inner IF stmt, and then, when you come
out, you check to see if it was false. If the first or second calls fail,
but the third call succeeds, you would never check your error code. Change
the lines:
bSuccess = WritePrinter(hPrinter, pBytes0, dwCount0, dwWritten1) 'header
data

bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten) 'image data

bSuccess = WritePrinter(hPrinter, pBytes1, dwCount1, dwWritten2) 'footer
data

to something along the lines of:
bSuccess = yadayada
bSuccess = bSuccess && yadayada
bSuccess = bSuccess && yadayada

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top