If your printer supports PCL5 (or higher) you can also use the RAW interface on port 9100 and send direct print commands including double/single sided
But it's a lot more work, so only go that path when you need to
Example code I've used:
Code: (Select All)
$Console:Only
'---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
Const FF = Chr$(12), CR = Chr$(13), LF = Chr$(10), CRLF = CR + LF
ip$ = "10.0.0.11"
Type tfType
fnr As Long
fspacing As _Unsigned _Byte
fname As String
End Type
ReDim Shared tf(100) As tfType
tfs% = loadTypeFaces%
tfs% = printFonts(ip$)
System
content$ = _ReadFile$("printer.bas") ': content$ = Left$(content$, 2376)
'Print printer%(ip$, content$, 80, 69, 2, 2, 2, 2); "pages printed"
Print printer%(ip$, content$, 220, 102, 0, 0, 0, 0); "pages printed"
'testPCL ip$, content$
Function printer% (ip$, content$, pgWidth%, pgHeight%, topMargin%, bottomMargin%, leftMargin%, rightMargin%)
'Print printer%(ip$, content$, 80, 69, 2, 2, 2, 2); "pages printed"
'Print printer%(ip$, content$, 220, 102, 0, 0, 0, 0); "pages printed" 'HP4102dw CPI=16.67
Const FF = Chr$(12)
If pgWidth% = 0 Then pgWidth% = 80
If pgHeight% = 0 Then pgHeight% = 69
If ip$ = "" Then
lpt& = FreeFile
Open "printer.txt" For Output As #lpt&: Close #lpt&
Open "printer.txt" For Binary As #lpt&
Else
lpt& = _OpenClient("TCP/IP:9100:" + ip$)
End If
If lpt& = 0 Then printer% = 0: Exit Function
If ip$ <> "" Then
' https://www.pclviewer.com/resources/reference/
cmd$ = pctrl$("~%-12345X"): Put #lpt&, , cmd$ 'Universal Printer Reset (Escape Sequence)
'cmd$ = pctrl$("~&l0O"): Put #lpt&, , cmd$ 'Portrait
'cmd$ = pctrl$("~&l1O"): Put #lpt&, , cmd$ 'Landscape
'cmd$ = pctrl$("~&l0S"): Put #lpt&, , cmd$ 'Simplex
cmd$ = pctrl$("~&l1S"): Put #lpt&, , cmd$ 'Duplex
'cmd$ = pctrl$("~(<10u>"): Put #lpt&, , cmd$ 'Set Symbol Set PCL PC-8, Code Page 437
'cmd$ = pctrl$("~(s0P"): Put #lpt&, , cmd$ 'Fixed
'cmd$ = pctrl$("~(s1P"): Put #lpt&, , cmd$ 'Proportional
'cmd$ = pctrl$("~(s0p0T"): Put #lpt&, , cmd$ 'font: Line Printer
'cmd$ = pctrl$("~(s1p3T"): Put #lpt&, , cmd$ 'font: Courier
'cmd$ = pctrl$("~(s1p4T"): Put #lpt&, , cmd$ 'font: Helvetica
'cmd$ = pctrl$("~(s0p6T"): Put #lpt&, , cmd$ 'font: Letter Gothic (fixed)
'cmd$ = pctrl$("~(s1p4113T"): Put #lpt&, , cmd$ 'font: CG Omega
'cmd$ = pctrl$("~(s1p4127T"): Put #lpt&, , cmd$ 'font: ITC Avant Garde
'cmd$ = pctrl$("~(s1p4148T"): Put #lpt&, , cmd$ 'font: Universe
'cmd$ = pctrl$("~(s1p4168T"): Put #lpt&, , cmd$ 'font: Antiqua Olive
'cmd$ = pctrl$("~(s1p4197T"): Put #lpt&, , cmd$ 'font: Garamond Antiqua
'cmd$ = pctrl$("~(s1p4297T"): Put #lpt&, , cmd$ 'font: Marigold
'cmd$ = pctrl$("~(s1p16602T"): Put #lpt&, , cmd$ 'font: Arial
'cmd$ = pctrl$("~(s1p16901T"): Put #lpt&, , cmd$ 'font: Times New Roman
'cmd$ = pctrl$("~(s10H~&l8C"): Put #lpt&, , cmd$ ' CPI=10 / VMI=8/48"
cmd$ = pctrl$("~(s16.67H~&l5C"): Put #lpt&, , cmd$ ' CPI=16.67 / VMI=5/48"
'cmd$ = pctrl$("~&k2S~&l5C"): Put #lpt&, , cmd$ ' CPI=16.67 / VMI=5/48"
'cmd$ = pctrl$("~(s20H~&l4C"): Put #lpt&, , cmd$ ' CPI=20 / VMI=4/48"
'cmd$ = pctrl$("~&k0S"): Put #lpt&, , cmd$ 'Font Pitch 10.00 cpi
'cmd$ = pctrl$("~&k2S"): Put #lpt&, , cmd$ 'Font Pitch 16.66 cpi
'cmd$ = pctrl$("~&k4S"): Put #lpt&, , cmd$ 'Font Pitch 12.00 cpi
End If
PRINTWIDTH% = pgWidth% - leftMargin% - rightMargin%
prnt$ = String$(topMargin%, LF): pages% = 1: linePos% = 1 + topMargin%
lineEndPos& = -1
Do 'get line segments
lineStartPos& = lineEndPos& + 2: lineEndPos& = InStr(lineStartPos&, content$, CRLF)
If lineEndPos& > 0 Then
lin$ = Mid$(content$, lineStartPos&, lineEndPos& - lineStartPos&)
Else
lin$ = Mid$(content$, lineStartPos&)
End If
Do 'split in printlines when too long
If Len(lin$) >= PRINTWIDTH% Then
prnt$ = prnt$ + RTrim$(Space$(leftMargin%) + Left$(lin$, PRINTWIDTH%))
If rightMargin% > 0 Then prnt$ = prnt$ + CRLF
lin$ = Mid$(lin$, PRINTWIDTH% + 1)
Else
prnt$ = prnt$ + Space$(leftMargin%) + RTrim$(lin$) + CRLF
lin$ = ""
End If
If linePos% < (pgHeight% - bottomMargin%) Then 'still fits the page
linePos% = linePos% + 1
ElseIf lineEndPos& > 0 Then 'page full & not last
lenPrn& = Len(prnt$) 'clean end of page
Do While lenPrn& > 0 _AndAlso Asc(prnt$, lenPrn&) <= 32
lenPrn& = lenPrn& - 1
Loop
If lenPrn& > 0 Then prnt$ = Left$(prnt$, lenPrn&) + CR + FF: Put #lpt&, , prnt$ 'print page
prnt$ = String$(topMargin%, LF): pages% = pages% + 1: linePos% = 1 + topMargin%
End If
Loop Until lin$ = ""
Loop Until lineEndPos& = 0
lenPrn& = Len(prnt$) 'clean end of page
Do While lenPrn& > 0 _AndAlso Asc(prnt$, lenPrn&) <= 32
lenPrn& = lenPrn& - 1
Loop
If lenPrn& > 0 Then 'print last page
prnt$ = Left$(prnt$, lenPrn&) + FF: Put #lpt&, , prnt$
Else
pages% = pages% - 1
End If
If ip$ <> "" Then
cmd$ = pctrl$("~%-12345X"): Put #lpt&, , cmd$ 'End of job / Printer reset
End If
Close #lpt&
printer% = pages%
End Function
Function printFonts% (ip$)
If ip$ = "" Then printFonts% = 0: Exit Function
lpt& = _OpenClient("TCP/IP:9100:" + ip$)
If lpt& = 0 Then printFonts% = 0: Exit Function
' https://www.pclviewer.com/resources/reference/
cmd$ = pctrl$("~%-12345X"): Put #lpt&, , cmd$ 'Universal Printer Reset (Escape Sequence)
cmd$ = pctrl$("~&l1O"): Put #lpt&, , cmd$ 'Landscape
cmd$ = pctrl$("~&l1S"): Put #lpt&, , cmd$ 'Duplex
cmd$ = pctrl$("~(<10u>"): Put #lpt&, , cmd$ 'Set Symbol Set PCL PC-8, Code Page 437
prnt$ = CRLF + "Internal PCL6 Fonts" + CRLF: Put #lpt&, , prnt$ 'Print fontname
chars$ = "abcdefghijklmnopqrstuvwxyz 1234567890 "
For f% = 1 To UBound(tf)
ctrl$ = Left$(" ~(s" + _ToStr$(tf(f%).fspacing) + "p" + _ToStr$(tf(f%).fnr) + "T ", 14)
prnt$ = Right$(" " + Str$(f%), 2) + Right$(Space$(6) + Str$(tf(f%).fnr), 6) + ctrl$: Put #lpt&, , prnt$ 'Print code
cmd$ = pctrl$(ctrl$): Put #lpt&, , cmd$ 'Set Font
prnt$ = chars$ + tf(f%).fname + CRLF: Put #lpt&, , prnt$ 'Print fontname
cmd$ = pctrl$("~(s0p0T"): Put #lpt&, , cmd$ 'Set Line Printer font
Next f%
cmd$ = pctrl$("~%-12345X"): Put #lpt&, , cmd$ 'End of job / Printer reset
Close #lpt&
printFonts% = f% - 1
End Function
Function pctrl$ (in$)
o$ = in$
esc% = InStr(o$, "~")
Do While esc%
Asc(o$, esc%) = 27
esc% = InStr(o$, "~")
Loop
pctrl$ = _Trim$(o$)
End Function
Function loadTypeFaces%
'Primary typeface family 'Ec(s#T
Restore typefacesData
tfs% = 1
Read tf(tfs%).fnr
Do While tf(tfs%).fnr >= 0
Print tfs%; tf(tfs%).fnr;
Read tf(tfs%).fspacing
Print tf(tfs%).fspacing;
Read tf(tfs%).fname
Print "|"; tf(tfs%).fname; "|"
tfs% = tfs% + 1
Read tf(tfs%).fnr
Loop
ReDim _Preserve tf(tfs% - 1) As tfType
loadTypeFaces% = UBound(tf)
Exit Function
typefacesData:
'fontnr, proportional, fontname
Data 0,0,"Line Printer or Line Draw"
Data 3,1,"Courier"
Data 4,1,"Helvetica"
'Data 5,1,"Times Roman"
Data 6,0,"Letter Gothic"
'Data 7,1,"Script"
'Data 8,1,"Prestige"
'Data 4099,1,"Courier"
'Data 4101,1,"CG Times"
'Data 4102,0,"Letter Gothic"
Data 4113,1,"CG Omega"
'Data 4116,1,"Coronet"
'Data 4119,1,"CG Century Schoolbook"
Data 4127,1,"ITC Avant Garde"
'Data 4140,1,"Clarendon"
Data 4148,1,"Univers"
Data 4168,1,"Antiqua Olive"
Data 4197,1,"Garamond Antiqua"
Data 4297,1,"Marigold"
'Data 4362,1,"Albertus"
'Data 6826,1,"Wingdings"
Data 16602,1,"Arial"
Data 16901,1,"Times New Roman"
'Data 16686,1,"Symbol"
'Data 24579,1,"CourierPS"
'Data 24580,1,"Helvetica"
'Data 24607,1,"ITC Avant Garde Gothic"
'Data 24623,1,"ITC Bookman"
'Data 24703,1,"Century Schoolbk"
'Data 24591,1,"Palatino"
'Data 25093,1,"Times Roman"
'Data 28752,1,"MS Mincho"
'Data 28825,1,"MS Gothic"
'Data 31402,1,"Wingdings"
'Data 37058,1,"SimSun"
'Data 37110,1,"Sim Hei"
'Data 37357,1,"GW-Kai"
'Data 45099,1,"ITC Zapf Chancery"
'Data 45101,1,"ITC Zapf Dingbats"
'Data 45358,1,"SymbolPS"
Data -1
End Function