ICI logo

Intersystem Concepts, Inc.

VB6 Print Labels

Windows has made difficult the former easy task of printing a non-full page, for example mailing labels on a dot matrix printer. If in VB6 you use Printer.Print then when the print job ends Windows inserts a form feed, which destroys label alignment.

To avoid the form feed you can use the WritePrinter() API, but Windows strips out escape sequences that control the printer.

Yes, there is a solution that requires no third-party add-ons: the old (but still supported through at least Windows XP) Escape() API function. To summarize, send the printer the escape sequences via Escape() and print the text via WritePrinter().

Basically you want to combine the instructions of the following two Knowledgebase articles:

The Knowledgebase link above for Passthrough Escape covers 16-bit, but the 32-bit version of the same API exists, and will be shown below.

To illustrate the combination, let's start with the example VB programming from second Knowledgebase article linked above, and insert a sample of possible Escape programming that makes bold text on Epson and IBM Proprinter dot-matrix printers. Note there are two insertions, one to declare the function plus a constant, and the other to send the Escape sequence before sending text.

Option Explicit

' --------------- begin insertion for handling Escape -------------------
Declare Function Escape Lib "Gdi32" (ByVal lHdc As Long, ByVal lEscape As Long, ByVal lcount As Long, ByVal indata As Any, ByVal outdata As Any) As Long
Public Const cPASSTHROUGH = 19
' --------------- end insertion for handling Escape -------------------

Private 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 Sub Command1_Click()
  Dim lhPrinter As Long
  Dim lReturn As Long
  Dim lpcWritten As Long
  Dim lDoc As Long
  Dim sWrittenData As String
  Dim MyDocInfo As DOCINFO

  ' --------------- begin insertion for handling Escape -------------------
  ' find the presumed dot matrix printer on port LPT1:
  ' and make it the default printer
  Dim P As Object
  Dim sEscape As String
  For Each P In Printers
    If P.Port = "LPT1:" Then
      Set Printer = P
      Exit For
    End If
  Next P

  ' send Escape sequence E - turns on emphasized for text bolding
  sEscape = Chr$(27) + "E"
  sEscape = Chr$(Len(sEscape) Mod 256) + Chr$(Len(sEscape) \ 256) + sEscape
  lReturn = Escape(Printer.Hdc, cPASSTHROUGH, 0, PCL_Escape$, 0&)
  Select Case lReturn
  Case Is < 0
    Debug.Print "The PASSTHROUGH Escape is not supported by this printer driver."
  Case 0
    Debug.Print "An error occurred sending the escape sequence."
  Case Is > 0
    Debug.Print "Escape Successfully sent. Sending test printout to printer."
  End Select
  ' --------------- end insertion for handling Escape -------------------

  lReturn = OpenPrinter(Printer.DeviceName, lhPrinter, 0)
  If lReturn = 0 Then
    MsgBox "The Printer Name you typed wasn't recognized."
    Exit Sub
  End If

  MyDocInfo.pDocName = "AAAAAA"
  MyDocInfo.pOutputFile = vbNullString
  MyDocInfo.pDatatype = vbNullString
  lDoc = StartDocPrinter(lhPrinter, 1, MyDocInfo)
  Call StartPagePrinter(lhPrinter)
  sWrittenData = "How's that for Magic !!!!" & vbFormFeed
  lReturn = WritePrinter(lhPrinter, ByVal sWrittenData, Len(sWrittenData), lpcWritten)
  lReturn = EndPagePrinter(lhPrinter)
  lReturn = EndDocPrinter(lhPrinter)
  lReturn = ClosePrinter(lhPrinter)
End Sub
Though not tested, any of the Epson ESC/P printer escape sequences should be sendable via the method above.
Other VB tips