Problems performing API class from VB.NET

Posted on 2005-04-26
Last Modified: 2008-01-09
ok, i have the following code performing API calls:

Imports System.Runtime.InteropServices

<DllImport("BCXL32.dll")> Shared Function BC_FontTranslate(ByVal nSymtype As Integer, ByRef sHRA As String, ByRef nCheckFlag As Integer, ByRef sOutString As String, ByVal nAllocSize As Integer, ByRef nReturnSize As Integer) As Integer

    End Function

    <DllImport("BCXL32.dll")> Shared Function BC_StrErr(ByRef nErrNum As Integer, ByVal sOutString As String, ByVal nAllocSize As Integer) As Integer

    End Function

    Function GenerateBarcodeFunction()

        Dim errorc As Integer
        Dim sTrans As String        'translated string
        Dim nLen As Integer         'length of translated string
        Dim sInput As String        'selected (input) string
        Dim sSetString As String    'returned string
        Dim nErr As Integer         'error code returned from DLL
        Dim sErrDesc As String      'error description
        Dim lg As New OMNI.LabelGenerator

        Dim rowCounter As Integer, colCounter As Integer
        Dim locLabelData As String
        Dim objWord As Word.Application
        Dim objDoc0 As Word.Document, objDoc1 As Word.Document
        Dim objTable As Word.Table
        Dim objShape As Word.InlineShape

        sTrans = New String(CChar("*"), 128)
        nErr = 0

        locLabelData = "0123456789"

        'Start Word and open the document template.
        objWord = CreateObject("Word.Application")
        objWord.Visible = True
        objDoc0 = objWord.Documents.Add

        objWord.MailingLabel.DefaultPrintBarCode = False
        objDoc1 = objWord.MailingLabel.CreateNewDocument(Name:="5162", Address:=locLabelData)

        objDoc1.Tables.Item(1).Range.ParagraphFormat.SpaceAfter = 0

        sInput = objDoc1.Tables.Item(1).Cell(1, 1).Range.Text
        nErr = BC_FontTranslate(11, sInput, 0, sTrans, 128, nLen)

        If nErr <> 0 Then
            errorc = BC_StrErr(nErr, sErrDesc, 128) --> ERROR ON THIS LINE
            MsgBox("Error translating bar code: " & sErrDesc)
            'Apply font name and size to the selection
            objDoc1.Tables.Item(1).Cell(1, 1).Range.Font.Name = "WASP 128 MC"
            objDoc1.Tables.Item(1).Cell(1, 1).Range.Font.Size = 36

            sSetString = Mid$(sTrans, 1, nLen)

            objDoc1.Tables.Item(1).Cell(1, 1).Range.Text = sSetString
        End If

    End Function

I am getting this error on line "errorc = BC_StrErr(nErr, sErrDesc, 128)":

 "An unhandled exception of type 'System.NullReferenceException' occurred

Additional information: Object reference not set to an instance of an object."

However, if I change the function declaration like so:

<DllImport("BCXL32.dll")> Shared Function BC_StrErr(ByRef nErrNum As Integer, ByRef sOutString As String, ByVal nAllocSize As Integer) As Integer

    End Function

What I changed here was parameter "sOutString" is now passed by reference, i.e. ByRef,  instead of by value, i.e. ByVal.

I get this error:

  "An unhandled exception of type 'System.ExecutionEngineException' occurred"

The DLL i am calling came with some WASP barcode fonts i installed on my machine. The fonts are about 4 years old so i am guessing they were meant to be used with VB6 and not VB.NET. I have Visual Studio .NET 2003 btw.

Any ideas?
Question by:Lou1
    LVL 96

    Expert Comment

    by:Bob Learned
    How are these API methods defined?  What type of DLLs are these?  COM, MFC, ATL?

    LVL 27

    Accepted Solution

    If you are trying to print a bar code then here  is a  sample you might want to look at....
    I use Free 3 of 9 font barcode (it is a free font look for on the web).

    'FORM 1

    Imports System.Drawing.Printing
    Public Class Form1
        Inherits System.Windows.Forms.Form
        Private WithEvents BarcodeDoc As BarcodingParts.TextPrint

    #Region " Windows Form Designer generated code "

        Public Sub New()

            'This call is required by the Windows Form Designer.

            'Add any initialization after the InitializeComponent() call

        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                End If
            End If
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents PrintDocument1 As System.Drawing.Printing.PrintDocument
        Friend WithEvents Button1 As System.Windows.Forms.Button
        Friend WithEvents PrintPreviewDialog1 As System.Windows.Forms.PrintPreviewDialog
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(Form1))
            Me.PrintDocument1 = New System.Drawing.Printing.PrintDocument
            Me.Button1 = New System.Windows.Forms.Button
            Me.PrintPreviewDialog1 = New System.Windows.Forms.PrintPreviewDialog
            Me.Button1.Location = New System.Drawing.Point(196, 224)
            Me.Button1.Name = "Button1"
            Me.Button1.TabIndex = 0
            Me.Button1.Text = "Button1"
            Me.PrintPreviewDialog1.AutoScrollMargin = New System.Drawing.Size(0, 0)
            Me.PrintPreviewDialog1.AutoScrollMinSize = New System.Drawing.Size(0, 0)
            Me.PrintPreviewDialog1.ClientSize = New System.Drawing.Size(400, 300)
            Me.PrintPreviewDialog1.Enabled = True
            Me.PrintPreviewDialog1.Icon = CType(resources.GetObject("PrintPreviewDialog1.Icon"), System.Drawing.Icon)
            Me.PrintPreviewDialog1.Location = New System.Drawing.Point(132, 132)
            Me.PrintPreviewDialog1.MinimumSize = New System.Drawing.Size(375, 250)
            Me.PrintPreviewDialog1.Name = "PrintPreviewDialog1"
            Me.PrintPreviewDialog1.TransparencyKey = System.Drawing.Color.Empty
            Me.PrintPreviewDialog1.Visible = False
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(292, 266)
            Me.Name = "Form1"
            Me.Text = "Form1"

        End Sub

    #End Region
        Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
            BarcodeDoc = New BarcodingParts.TextPrint("*00417955*", "Here is Second line")   '<----- Sample input
            BarcodeDoc.Font = New Font("Free 3 of 9", 30)
            '   PrintPreviewDialog1.Document = BarcodeDoc
            '  PrintPreviewDialog1.ShowDialog()

            'For Derict Printing
            Dim PrintDialog1 As New PrintDialog
            PrintDialog1.Document = BarcodeDoc
        End Sub
        Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
            BarcodeDoc.PrinterSettings.PrinterName = InitializeDefaultPrinter() '"Zebra" '<---can use regular printer or something like a zebra  code printer
            BarcodeDoc.DefaultPageSettings.Margins.Left = 10
            BarcodeDoc.DefaultPageSettings.Margins.Right = 10
            BarcodeDoc.DefaultPageSettings.Margins.Top = 40
        End Sub
    #Region " Initialize Default Printer "
        Public Function InitializeDefaultPrinter()
            ' Set the specified printer to the default printer for this program. Return
            ' true if the printer was found.

            Dim objprinter As PageSettings = New PageSettings
            Dim strname = objprinter.PrinterSettings.PrinterName

            InitializeDefaultPrinter = strname
        End Function
    #End Region
    End Class


    Imports System.Drawing.Graphics
    Public Class TextPrint
        ' Inherits all the functionality of a PrintDocument
        Inherits Printing.PrintDocument
        ' Private variables to hold default font and text
        Private fntPrintFont As Font
        Private strText As String
        Private strText2 As String
        Private PrintBarCodeText As String
        Public Sub New(ByVal Text As String, ByVal Text2 As String)
            ' Sets the file stream
            strText = Text
            strText2 = Text2
        End Sub
        Public Property Text() As String
                Return strText
            End Get
            Set(ByVal Value As String)
                strText = Value
            End Set
        End Property
        Public Property Text2() As String
                Return Trim(strText2)
            End Get
            Set(ByVal Value As String)
                strText2 = Trim(Value)
            End Set
        End Property
        Public Property CodeText() As String
                PrintBarCodeText = Trim(Replace(strText, "*", " "))
                Return PrintBarCodeText
            End Get
            Set(ByVal Value As String)
                If PrintBarCodeText = "" Then
                    PrintBarCodeText = Trim(Replace(Value, "*", " "))
                End If
                PrintBarCodeText = Value
            End Set
        End Property
        Protected Overrides Sub OnBeginPrint(ByVal ev As Printing.PrintEventArgs)
            ' Run base code
            ' Sets the default font
            If fntPrintFont Is Nothing Then
                fntPrintFont = New Font("Times New Roman", 12)
            End If
        End Sub
        Public Property Font() As Font
            ' Allows the user to override the default font
                Return fntPrintFont
            End Get
            Set(ByVal Value As Font)
                fntPrintFont = Value
            End Set
        End Property
        Protected Overrides Sub OnPrintPage(ByVal ev As Printing.PrintPageEventArgs)
            ' Provides the print logic for our document

            ' Run base code
            ' Variables
            Static intCurrentChar As Integer
            Dim intPrintAreaHeight, intPrintAreaWidth, intMarginLeft, intMarginTop As Integer
            ' Set printing area boundaries and margin coordinates
            With MyBase.DefaultPageSettings
                intPrintAreaHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
                intPrintAreaWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
                intMarginLeft = .Margins.Left 'X
                intMarginTop = .Margins.Top   'Y
            End With
            ' If Landscape set, swap printing height/width
            If MyBase.DefaultPageSettings.Landscape Then
                Dim intTemp As Integer
                intTemp = intPrintAreaHeight
                intPrintAreaHeight = intPrintAreaWidth
                intPrintAreaWidth = intTemp
            End If
            ' Calculate total number of lines
            Dim intLineCount As Int32 = CInt(intPrintAreaHeight / Font.Height)
            ' Initialise rectangle printing area
            Dim rectPrintingArea As New RectangleF(intMarginLeft, intMarginTop, intPrintAreaWidth, intPrintAreaHeight)
            ' Initialise StringFormat class, for text layout
            Dim objSF As New StringFormat(StringFormatFlags.LineLimit)
            ' Figure out how many lines will fit into rectangle
            Dim intLinesFilled, intCharsFitted As Int32
            Dim stringSize As New SizeF
            stringSize = ev.Graphics.MeasureString(Mid(strText, _
                        UpgradeZeros(intCurrentChar)), Font, New SizeF(intPrintAreaWidth, _
                        intPrintAreaHeight), objSF, intCharsFitted, intLinesFilled)
            ' Print the text to the page
            ev.Graphics.DrawString(Mid(strText, _
                UpgradeZeros(intCurrentChar)), Font, Brushes.Black, rectPrintingArea, objSF)

            ' Initialise rectangle printing area for the Barcode Text
            Dim stringFont As New Font("Arial", 12, FontStyle.Bold)
            Dim size As SizeF = ev.Graphics.MeasureString(CodeText, stringFont)
            Dim size2 As SizeF = ev.Graphics.MeasureString(strText2, stringFont)
            Dim BCPrintingArea As New RectangleF(stringSize.Width - size.Width / 2, intMarginTop + stringSize.Height, intPrintAreaWidth, intPrintAreaHeight)

            'Move Second line to center
            Dim moveStr As Integer
            moveStr = stringSize.Width - size2.Width / 2
            moveStr = intMarginLeft + (moveStr / intMarginLeft)
            Dim BCPrintingArea2 As New RectangleF(moveStr, intMarginTop + stringSize.Height + size2.Height, intPrintAreaWidth, intPrintAreaHeight)

            'ADD text Bottom of Barcode
            ev.Graphics.DrawString(CodeText, stringFont, Brushes.Black, BCPrintingArea)
            ev.Graphics.DrawString(strText2, stringFont, Brushes.Black, BCPrintingArea2)

            ' Increase current char count
            intCurrentChar += intCharsFitted
            ' Check whether we need to print more
            If intCurrentChar < strText.Length Then
                ev.HasMorePages = True
                ev.HasMorePages = False
                intCurrentChar = 0
            End If
        End Sub
        Public Function UpgradeZeros(ByVal Input As Integer) As Integer
            ' Upgrades all zeros to ones
            ' - used as opposed to defunct IIF or messy If statements
            If Input = 0 Then
                Return 1
                Return Input
            End If
        End Function

    End Class

    LVL 96

    Expert Comment

    by:Bob Learned

    Keith, what is BarcodingParts.TextPrint?

    LVL 27

    Expert Comment

    Sorry, BarcodingParts is just the name of my project   BarcodingParts.sln
    LVL 96

    Expert Comment

    by:Bob Learned
    Thanks, I didn't see the TextPrint class below through all that text.


    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Join & Write a Comment

    Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
    Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
    This video is in connection to the article "The case of a missing mobile phone (". It will help one to understand clearly the steps to track a lost android phone.
    Internet Business Fax to Email Made Easy - With eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

    754 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

    Need Help in Real-Time?

    Connect with top rated Experts

    24 Experts available now in Live!

    Get 1:1 Help Now