Search code examples
vb.netvb6-migration

VB6 StrPtr Function to VB.NET


Trying to convert VB6 line of code to VB.net. Code will serve as identification if printer is OFF or ON Thanks

"PRINTERFOUND = OpenPrinterW(StrPtr(PrinterName), hPrinter)" Particular StrPtr function...

Can't get OpenPrinter to work - Tries to print I simply want to to know if printer is OFF or ON

changing line to

PRINTERFOUND = OpenPrinterW(PrinterName.Normalize(), hPrinter, Nothing)

does not work, thanks

Tried to convert VB6 declaration to VB.net per previous suggestions but it still a same error cant convert String to Integer please see below

'Private Declare Function GetPrinterApi Lib "winspool.drv" Alias "GetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, ByRef BUFFER As  Long, ByVal pbSize As Long, ByRef pbSizeNeeded As Long) As Long     
 <DllImport("winspool.Drv", EntryPoint:="GetPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Function GetPrinterApi(<MarshalAs(UnmanagedType.LPStr)> ByVal hPrinter As String, ByVal Level As IntPtr, ByVal BUFFER As IntPtr, ByVal pbSize As IntPtr, ByRef pbSizeNeeded As IntPtr) As Boolean
End Function

'Private Declare Function OpenPrinterW Lib "winspool.drv" (ByVal pPrinterName As Long, ByRef phPrinter As Long, Optional ByVal pDefault As Long = 0) As Long  
 <DllImport("winspool.Drv", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Function OpenPrinterW(ByVal pPrinterName As IntPtr, ByVal phPrinter As Int32, <[In](), MarshalAs(UnmanagedType.LPStruct)> ByVal pDefault As IntPtr) As Boolean
End Function

'Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
 <DllImport("winspool.Drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function

'Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Long, ByRef Source As Long, ByVal Length As Long)  
 <DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="RtlMoveMemory")> _
Public Function CopyMemory(ByRef Destination As Long, ByVal Source As IntPtr, ByVal Length As String) As IntPtr
End Function

Full code Below

'Acknowledgements : This program has been written making extensive use of the
'Merrion article http://www.merrioncomputing.com/Programming/PrintStatus.htm
'It has also benefited from the contributors to VBForums thread # 733849
'http://www.vbforums.com/showthread.php?t=733849&goto=newpost - especially the code
'suggested by "Bonnie West"

'Program written 14 Sept. 2013 by C.A. Moore

Option Explicit

Dim PRINTERFOUND As Long
Dim GETPRINTER As Long
Dim BUFFER() As Long
Dim pbSizeNeeded As Long
Dim PRINTERINFO As PRINTER_INFO_2
Dim N As Integer
Dim M As Integer
Dim CHAR As String
Dim prnPrinter As Printer
Dim BUF13BINARY As String

' Note : PRINTERREADY as an Integer variable is Dim'd
'"Public PRINTERREADY As Integer" at Form1 Option Explicit

Private Type PRINTER_INFO_2
    pServerName As String
    pPrinterName As String
    pShareName As String
    pPortName As String
    pDriverName As String
    pComment As String
    pLocation As String
    pDevMode As Long
    pSepFile As String
    pPrintProcessor As String
    pDatatype As String
    pParameters As String
    pSecurityDescriptor As Long
    Attributes As Long
    Priority As Long
    DefaultPriority As Long
    StartTime As Long
    UntilTime As Long
    Status As Long
    JobsCount As Long
    AveragePPM As Long
End Type

Private Declare Function GetPrinterApi Lib "winspool.drv" Alias "GetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, BUFFER As Long, ByVal pbSize As Long, pbSizeNeeded As Long) As Long
Private Declare Function OpenPrinterW Lib "winspool.drv" (ByVal pPrinterName As Long, ByRef phPrinter As Long, Optional ByVal pDefault As Long) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Function StringFromPointer(lpString As Long, lMaxLength As Long) As String
    'this service function extracts a string (sRet) when fed with a pointer (lpstring)
    'from a buffer
    Dim sRet As String
    Dim lret As Long

    If lpString = 0 Then
        StringFromPointer = ""
        Exit Function
    End If

    '\\ Pre-initialise the return string...
    sRet = Space$(lMaxLength)
    CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet)
    If Err.LastDllError = 0 Then
        If InStr(sRet, Chr$(0)) > 0 Then
            sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1)
        End If
    End If

    StringFromPointer = sRet
End Function

Public Function IsPrinterReady(ByRef PrinterName As String)
    Form1.PRINTERREADY = 0

    'first select the named printer and check if it is installed
    For Each prnPrinter In Printers
        CHAR = prnPrinter.DeviceName
        If CHAR = PrinterName Then
            Set Printer = prnPrinter   'sets this as printer
            Form1.PRINTERREADY = 1
        End If
    Next

    If Form1.PRINTERREADY = 0 Then GoTo Line1000     'exit. printer not installed
        Dim hPrinter As Long
        Dim PI6 As PRINTER_INFO_2

        PRINTERFOUND = 0
        Form1.PRINTERREADY = 0
        PRINTERFOUND = OpenPrinterW(StrPtr(PrinterName), hPrinter)
        '(OpenPrinterW(ByVal pPrinterName As Long, ByRef phPrinter As Long) As Long)

        If PRINTERFOUND = 0 Then                'ie. printer not found
            Form1.PRINTERREADY = 0
            Debug.Assert ClosePrinter(hPrinter)
            GoTo Line100
        End If

        'If we get here named printer was found and accessed and its hPrinter handle is
        'known
         'Dim BUFFER() As Long
         'Dim pbSizeNeeded As Long

         ReDim Preserve BUFFER(0 To 1) As Long
         GETPRINTER = GetPrinterApi(hPrinter, 2&, BUFFER(0), UBound(BUFFER), pbSizeNeeded)
         ReDim Preserve BUFFER(0 To (pbSizeNeeded / 4) + 3) As Long
         GETPRINTER = GetPrinterApi(hPrinter, 2&, BUFFER(0), UBound(BUFFER) * 4, pbSizeNeeded)
         If GETPRINTER = 0 Then              'ie. some problem with printer access
             Form1.PRINTERREADY = 0
             GoTo Line100
         End If

         'If we get here then GETPRINTER = 1, ie. printer found and accessed OK
         With PRINTERINFO '\\ This variable is of type PRINTER_INFO_2
            'These quantities are defined here because the Merrion article
            'so specifies. However they are not used by this program, and most
            'have been found to be void

            .pServerName = StringFromPointer(BUFFER(0), 1024)
            .pPrinterName = StringFromPointer(BUFFER(1), 1024)
            .pShareName = StringFromPointer(BUFFER(2), 1024)
            .pPortName = StringFromPointer(BUFFER(3), 1024)
            .pDriverName = StringFromPointer(BUFFER(4), 1024)
            .pComment = StringFromPointer(BUFFER(5), 1024)
            .pLocation = StringFromPointer(BUFFER(6), 1024)
            .pDevMode = BUFFER(7)
            .pSepFile = StringFromPointer(BUFFER(8), 1024)
            .pPrintProcessor = StringFromPointer(BUFFER(9), 1024)
            .pDatatype = StringFromPointer(BUFFER(10), 1024)
            .pParameters = StringFromPointer(BUFFER(11), 1024)
            .pSecurityDescriptor = BUFFER(12)
            .Attributes = BUFFER(13)
            .Priority = BUFFER(14)
            .DefaultPriority = BUFFER(15)
            .StartTime = BUFFER(16)
            .UntilTime = BUFFER(17)
            .Status = BUFFER(18)
            .JobsCount = BUFFER(19)
            .AveragePPM = BUFFER(20)
        End With



        'This next code is for interest and program development only.
        'It writes into List1 the value of each buffer 1 - 20
        'To by-pass it, add a "Go To Line15" statement at this point.

        Form1.List1.Clear
        N = 0
Line5:
        On Error GoTo Line15
        Form1.List1.AddItem "Buffer No. " & N & "  Buffer Value " & BUFFER(N)
        N = (N + 1)
        If N = 21 Then GoTo Line15
        GoTo Line5

        'Now to convert the decimal value of Buffer(13) into a binary
        'bit pattern and store this in BUF13BINARY
Line15: 'and to show Buffer(13) as a binary bit pattern at Form1.Label1

        N = BUFFER(13)
        BUF13BINARY = ""
        M = 4196
Line16:
        If N < M Then
            BUF13BINARY = BUF13BINARY & "0"
            GoTo Line20
        End If

        BUF13BINARY = BUF13BINARY & "1"
        N = (N - M)
Line20:
        If M = 1 Then GoTo Line10
            M = M / 2
            GoTo Line16

Line10: 'BUF13BINARY is now the 13 bit binary value of Buffer(13)
        'eg. 0011000100010

        Form1.Label1.Caption = BUF13BINARY  'display this binary value at form 1

        'we now examine the value of the third binary bit in BUF13BINARY
        If Mid$(BUF13BINARY, 3, 1) = "0" Then Form1.PRINTERREADY = 1
        If Mid$(BUF13BINARY, 3, 1) = "1" Then Form1.PRINTERREADY = 0
Line100:
        ClosePrinter (hPrinter)
Line1000:
End Function

and

Option Explicit
Public PRINTERREADY As Integer

Private Sub Command1_Click()
    IsPrinterReady ("Brother QL-500")
    'IsPrinterReady ("EPSON Stylus CX5400")
    MsgBox PRINTERREADY                     '0 = Not Ready   1 = Ready
End Sub

Solution

  • Thanks Everyone, especially Drunken Code Monkey for all the information provided, I was able to finally achieve what I wanted after reading on https://msdn.microsoft.com/en-us/library/aa394363(v=vs.85).aspx figured need to is boolean WorkOffline; Pew... made it more simple then VB6 language even using that feels kinda hmm old. Also lucky me found codes that did the same thing as I wanted here is link to VB.NET "https://bytes.com/topic/visual-basic-net/answers/524957-detecting-if-printer-connected-pc" And my modification of this code below

    Imports System.Management
    Public Class Form1
    Public Class CheckPrinterStatus
        Public Function PrinterIsOnline(ByVal sPrinterName As String) As Boolean
            '// Set management scope
            Dim scope As ManagementScope = New ManagementScope("\root\cimv2")
            scope.Connect()
    
            '// Select Printers from WMI Object Collections
            Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT * FROM Win32_Printer")
    
            Dim printerName As String = String.Empty
            For Each printer As ManagementObject In searcher.Get()
                printerName = printer("Name").ToString() '.ToLower()
                If (printerName.Equals(sPrinterName)) Then
                    MsgBox(printerName)
                    If (printer("WorkOffline").ToString().ToLower().Equals("true")) Then
    
                        MsgBox("Offline")
                        ' Printer is offline by user
                        Return False
                    Else
                        ' Printer is not offline
                        MsgBox("Online")
                        Return True
                    End If
                End If
            Next
            Return False
        End Function ' PrinterIsOnline
    End Class
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim PrinterSatus As New CheckPrinterStatus
        PrinterSatus.PrinterIsOnline("Brother QL-500") 'Name of The printer HERE
    End Sub
    End Class