Click here to Skip to main content
15,039,319 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everyone,

I'm have problems to control a ID-Card Printer (HiTi CS-200e) in VB.NET (VS 2013).
It comes with a dll "PavoApi.dll" (seems to be an unmanaged dll).

Referring to the printers SDK docs I have to use
C++
DWORD __stdcall PAVO_GetDeviceInfo(char* szPrinter, DWORD dwInfoType, BYTE *lpInfoData, DWORD *lpdwDataLen);

to get different return values.
dwInfoType determines, what information is returned in lpInfoData
1 for serial number (data type in lpInfoData is 'char array' in this case)
6 for number of printed cards (a DWORD is returned)

lpdwDataLen returns the size of lpInfoData.

I tried to call the function this way
VB
<DllImport("PavoApi.dll")> _
Public Shared Function PAVO_GetDeviceInfo(ByVal szPrinter As String, ByVal dwInfoType As Integer, ByRef lpInfoData As IntPtr, ByRef lpdwDataLen As Integer) As Integer

End Function

Public Function GetDeviceInfo(ByVal PrinterName As String) As Integer
    Dim resPtr As IntPtr
    Dim resLen As Integer
    PAVO_GetDeviceInfo(PrinterName, 1, resPtr, resLen)


    Return 0 'TODO: return something serious
End Function


The VB6 samplecode used "Any" for lpInfoData.
VB
Public Declare Function PAVO_GetDeviceInfo Lib "PavoApi.DLL" (ByVal szPrinter As String, ByVal dwInfoType As Long, lpInfoData As Any, ByRef lpdwDataLen As Long) As Long

I tried to use Object for lpInfoData, but recieved errors.

But how can I access the Information at resPtr?
Posted
Comments
Richard Deeming 13-Jan-15 8:40am
   
Do you have an example of calling the function in VB6? Based on the function signature, I suspect the you need to allocate the memory to store the result before calling the function.
Philipp fgi 13-Jan-15 9:06am
   
I posted the VB6 code below (better text format).

In VB6 the function is called this way
VB
Private Sub CommandGetDeviceInfo_Click()

    Dim dwError As Long
        
    Dim dwInfoType As Long
    Dim dwSize As Long
    Dim byteBuf(64) As Byte
    Dim longBuf(16) As Long

    Dim szString As String

    Dim dwCardPos As Long
    Dim szCardPosDesc As String

    Dim szPrinter As String

    Select Case g_nConnectType
        Case 0
            szPrinter = Printer.DeviceName
        Case 1
            szPrinter = TextIP.Text
    End Select

    dwInfoType = ComboDeviceInfo.ListIndex

    If dwInfoType = 0 Then
        dwSize = 64
        dwError = PAVO_GetDeviceInfo(szPrinter, PAVO_DEVINFO_MFG_SERIAL, byteBuf(0), dwSize)
        szString = StrConv(byteBuf, vbUnicode)
        MsgBox "Serial = " & szString, vbOKOnly, "Get Device Info"
    
    ElseIf dwInfoType = 1 Then
        dwSize = 64
        dwError = PAVO_GetDeviceInfo(szPrinter, PAVO_DEVINFO_MODEL_NAME, byteBuf(0), dwSize)
        szString = StrConv(byteBuf, vbUnicode)
        MsgBox "Model = " & szString, vbOKOnly, "Get Device Info"

    ElseIf dwInfoType = 2 Then
        dwSize = 64
        dwError = PAVO_GetDeviceInfo(szPrinter, PAVO_DEVINFO_FIRMWARE_VERSION, byteBuf(0), dwSize)
        szString = StrConv(byteBuf, vbUnicode)
        MsgBox "FW version = " & szString, vbOKOnly, "Get Device Info"

    ElseIf dwInfoType = 3 Then
        dwSize = 64
        dwError = PAVO_GetDeviceInfo(szPrinter, PAVO_DEVINFO_RIBBON_INFO, longBuf(0), dwSize)
        MsgBox "Ribbon Type = " & vbLf & vbLf & longBuf(0) & "Remain ribbon = " & longBuf(1), vbOKOnly, "Get Device Info"

    ElseIf dwInfoType = 4 Then
        dwSize = 64
        dwError = PAVO_GetDeviceInfo(szPrinter, PAVO_DEVINFO_PRINT_COUNT, longBuf(0), dwSize)
        MsgBox "Printed card = " & longBuf(0), vbOKOnly, "Get Device Info"

    ElseIf dwInfoType = 5 Then
        dwSize = 4
        dwError = PAVO_GetDeviceInfo(szPrinter, PAVO_DEVINFO_CARD_POSITION, dwCardPos, dwSize)

        Select Case dwCardPos
            Case 0
                    szCardPosDesc = "Out of printer"
            Case 1
                    szCardPosDesc = "Start printing position"
            Case 2
                    szCardPosDesc = "Mag out position"
            Case 3
                    szCardPosDesc = "Mag in position"
            Case 4
                    szCardPosDesc = "Contact encoder position"
            Case 5
                    szCardPosDesc = "Contactless encoder position"
            Case 6
                    szCardPosDesc = "Flipper position"
            Case 7
                    szCardPosDesc = "Card jam"
            Case 8
                    szCardPosDesc = "Standby position"
        End Select

        MsgBox "Card position = " & dwCardPos & vbLf & vbLf & szCardPosDesc, vbOKOnly, "Get Device Info"
    End If

End Sub
   
From the VB6 code sample, it looks like you have three different return types:
  • A string;
  • An integer;
  • An array of integers;

The simplest way to handle that would be three overloads of the P/Invoke function. Something similar to this should work:
VB
' Integer:
<DllImport("PavoApi.dll")> _
Public Shared Function PAVO_GetDeviceInfo(ByVal szPrinter As String, ByVal dwInfoType As Integer, ByRef lpInfoData As Integer, ByRef lpdwDataLen As Integer) As Integer
End Function

Public Function GetDeviceInfoAsInteger(ByVal printerName As String, ByVal infoType As Integer) As Integer
    Dim resultLength As Integer = 4
    Dim result As Integer
    
    Dim returnCode As Integer = PAVO_GetDeviceInfo(printerName, infoType, result, resultLength)
    ' TODO: Check the return code
    
    Return result
End Function


' String:
<DllImport("PavoApi.dll")> _
Public Shared Function PAVO_GetDeviceInfo(ByVal szPrinter As String, ByVal dwInfoType As Integer, ByVal lpInfoData As StringBuilder, ByRef lpdwDataLen As Integer) As Integer
End Function

Public Function GetDeviceInfoAsString(ByVal printerName As String, ByVal infoType As Integer) As String
    Dim resultLength As Integer = 64
    Dim result As New StringBuilder(resultLength)
    
    Dim returnCode As Integer = PAVO_GetDeviceInfo(printerName, infoType, result, resultLength)
    ' TODO: Check the return code
    
    Return result.ToString()
End Function


' Integer array:
<DllImport("PavoApi.dll")> _
Public Shared Function PAVO_GetDeviceInfo(ByVal szPrinter As String, ByVal dwInfoType As Integer, <In, Out> ByVal lpInfoData As Integer(), ByRef lpdwDataLen As Integer) As Integer
End Function


Public Function GetDeviceInfoAsIntegerArray(ByVal printerName As String, ByVal infoType As Integer, ByVal resultLength As Integer) As Integer()
    Dim result As Integer() = New Integer(resultLength - 1) {}
    
    Dim returnCode As Integer = PAVO_GetDeviceInfo(printerName, infoType, result, resultLength)
    ' TODO: Check the return code
    
    Return result
End Function
   
Comments
Philipp fgi 13-Jan-15 11:09am
   
Dear Richard,
it works, you saved my day a second time. Thank you very much!

One necessary modification in the integer array overload: "In, Out Byval lpInfoData" brings up in an "unknown type" error. Removed it, done.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900