borderAndreaVB free resources for Visual Basic developersborder

borderAndreaVB Visual Basic and VB.NET source code resources - Copyright © 1999-2007 Andrea Tincaniborder

AndreaVB | Forum | News | Downloads | Register | Help | Member List | Statistics | Search | PM | Profile

Print This Topic
Next Topic (Change Windows Taskbar Color) New Topic New Poll Post Reply
AndreaVB Forum : API : DocumentProperties and SetPrinter problem
Poster Message
Schimmel
Level: Trainee

Registered: 24-09-2007
Posts: 1

icon DocumentProperties and SetPrinter problem

Hi

I wrote a function that copies a print queue. The function successfully creates the printer but it does not apply the printer settings with DocumentProperties and SetPrinter on the newly created queue - err.lastDllError 122 (ERROR_INSUFFICIENT_BUFFER). Does anyone has already expirience with the printer api or knows what error I did?

Public Function fMovePrinter( _
                                ByVal sSource As String, _
                                ByVal sDestination As String, _
                                ByVal sPrinter As String, _
                                ByVal lvSource As ListView, _
                                ByVal lvDestination As ListView, _
                                ByVal bDelete As Boolean _
                                ) As Boolean

        'first open the source printer to get the handle
        Dim hSource As IntPtr
        Dim pd As New PRINTER_DEFAULTS

        pd.DesiredAccess = PrinterAccessRights.PRINTER_ALL_ACCESS
        If Not OpenPrinter(sPrinter, hSource, pd) Then
            Throw New Exception(Err.LastDllError & " unable to OpenPrinter " & sPrinter)
            Return False
        End If

        'now call the GetPrinter API to get the PRINTER_INFO_2 structure
        Dim BytesWritten As Int32 = 0
        Dim ptBuf As IntPtr
        Dim pi2 As New PRINTER_INFO_2
        Dim dmOut As New DEVMODE

        ptBuf = Marshal.AllocHGlobal(1)

        'Get the number of bytes needed
        If Not GetPrinter(hSource, 2, ptBuf, 1, BytesWritten) Then
            If BytesWritten > 0 Then
                Marshal.FreeHGlobal(ptBuf)
                ptBuf = Marshal.AllocHGlobal(BytesWritten)
                'Get the PRINTER_INFO_2 structure
                If GetPrinter(hSource, 2, ptBuf, BytesWritten, BytesWritten) Then
                    Marshal.PtrToStructure(ptBuf, pi2)
                    If pi2.lpDeviceMode > 0 Then
                        'Get the DEVMODE structure
                        Dim ptrDevMode As New IntPtr(pi2.lpDeviceMode)
                        Marshal.PtrToStructure(ptrDevMode, dmOut)
                    End If
                Else
                    Marshal.FreeHGlobal(ptBuf)
                    ClosePrinter(hSource)
                    Throw New Exception(Err.LastDllError & " unable to GetPrinter #2 " & sPrinter)
                    Return False
                End If
                'free ptBuf
                Marshal.FreeHGlobal(ptBuf)
                'ClosePrinter(hSource)
            Else
                Throw New Exception(Err.LastDllError & " BytesWritten #1 " & BytesWritten)
                Return False
            End If

        Else
            Throw New Exception(Err.LastDllError & " unable to GetPrinter #1 " & sPrinter)
            Return False
        End If

        'modify the pi2 structure with the needed parameters
        Dim strPrinter As String
        strPrinter = sPrinter
        If strPrinter.LastIndexOf("\") > 0 Then
            strPrinter = strPrinter.Remove(strPrinter.IndexOf("\"), strPrinter.LastIndexOf("\") + 1)
        End If

        With pi2
            .pPrinterName = strPrinter
            .pServerName = sDestination
            .pPortName = "LPT1:"
            '.Attributes = PrinterAttributes.PRINTER_ATTRIBUTE_SHARED Or PrinterAttributes.PRINTER_ATTRIBUTE_PUBLISHED
        End With

        'change the DEVMODE structure with the needed parameters
        Dim strFullPrinterPath As String = "\\" & sDestination & "\" & strPrinter
        With dmOut
            .pDeviceName = strFullPrinterPath
        End With

        'copy the devmode structure back into the PRINTER_INFO_2 structure
        'Dim hdmIn As IntPtr
        pi2.lpDeviceMode = Marshal.AllocHGlobal(Marshal.SizeOf(dmOut))
        Marshal.StructureToPtr(dmOut, pi2.lpDeviceMode, False)

        If bDelete = True Then
            Call DeletePrinter(hSource)
            hSource = IntPtr.Zero
        End If

        'create the printer on the destination
        Dim hDestination As IntPtr
        hDestination = AddPrinter("\\" & sDestination, 2, pi2)
        If hDestination = 0 Then
            If Err.LastDllError = 1802 Then
                Call DeletePrinter(hSource)
                Debug.Print(Err.LastDllError.ToString)
                hDestination = AddPrinter("\\" & sDestination, 2, pi2)
                If hDestination = 0 Then
                    Throw New Exception(Err.LastDllError & " unable to AddPrinter, tried twice because printer allready exists on " & sDestination)
                    Return False
                End If
            Else
                Throw New Exception(Err.LastDllError & " unable to AddPrinter")
                Return False
            End If
        End If

        If hSource <> 0 Then
            ClosePrinter(hSource)
            hSource = IntPtr.Zero
        End If

        'dmOut = Nothing

        Dim intRet As Int32
        'get size of the DEVMODE structure
        intRet = DocumentProperties(IntPtr.Zero, hDestination, strFullPrinterPath, IntPtr.Zero, IntPtr.Zero, DocumentPropertiesModes.DM_GETSIZE)
        If intRet < 0 Then
            Throw New Exception(Err.LastDllError & " unable to get DocumentProperties #1")
            Return False
        End If

        'create a new instance of the DEVMODE structure with size returned
        Dim hdmIn As IntPtr
        hdmIn = Marshal.AllocHGlobal(intRet)

        intRet = DocumentProperties(IntPtr.Zero, hDestination, strFullPrinterPath, hdmIn, IntPtr.Zero, DocumentPropertiesModes.DM_OUT_BUFFER)
        If intRet < 0 Then
            Throw New Exception(Err.LastDllError & " unable to get DocumentProperties #2")
            Return False
        End If

        'get the structure from the pointer
        Dim dmIn As New DEVMODE
        dmIn = Marshal.PtrToStructure(hdmIn, dmIn.GetType)

        'modify the structure with the settings from the source printer
        With dmIn
            .dmCollate = dmOut.dmCollate
            .dmColor = dmOut.dmColor
            .dmCopies = dmOut.dmCopies
            .dmDefaultSource = dmOut.dmDefaultSource
            .dmDuplex = dmOut.dmDuplex
            .dmFormName = dmOut.dmFormName
            .dmMediaType = dmOut.dmMediaType
            .dmOrientation = dmOut.dmOrientation
            .dmPaperLength = dmOut.dmPaperLength
            .dmPaperSize = dmOut.dmPaperSize
            .dmPaperWidth = dmOut.dmPaperWidth
            .dmPrintQuality = dmOut.dmPrintQuality
            .dmScale = dmOut.dmScale
            .dmTTOption = dmOut.dmTTOption
            .dmFields = DEVMODEFields.DM_COLLATE Or DEVMODEFields.DM_COLOR Or _
                        DEVMODEFields.DM_COPIES Or DEVMODEFields.DM_DEFAULTSOURCE Or _
                        DEVMODEFields.DM_DUPLEX Or DEVMODEFields.DM_FORMNAME Or _
                        DEVMODEFields.DM_MEDIATYPE Or DEVMODEFields.DM_ORIENTATION Or _
                        DEVMODEFields.DM_PAPERLENGTH Or DEVMODEFields.DM_PAPERSIZE Or _
                        DEVMODEFields.DM_PAPERWIDTH Or DEVMODEFields.DM_PRINTQUALITY Or _
                        DEVMODEFields.DM_SCALE Or DEVMODEFields.DM_TTOPTION
            .dmSize = Marshal.SizeOf(dmIn)
        End With

        'copy the structure back in the pointer
        Marshal.StructureToPtr(dmIn, hdmIn, False)

        'set the new settings on the destination printer
        intRet = DocumentProperties(IntPtr.Zero, hDestination, strFullPrinterPath, hdmIn, hdmIn, DocumentPropertiesModes.DM_IN_BUFFER Or DocumentPropertiesModes.DM_OUT_BUFFER)
        Debug.Print(Err.LastDllError.ToString & vbCrLf)
        If intRet < 0 Then
            Throw New Exception(Err.LastDllError & " unable to set DocumentProperties #1")
            Return False
        End If

        'reget the PRINTER_INFO_2 structure from the destination printer
        Dim PI2In As New PRINTER_INFO_2
        'Dim hPI2In As IntPtr
        BytesWritten = 0
        ptBuf = Marshal.AllocHGlobal(1)
        If Not GetPrinter(hDestination, 2, ptBuf, 1, BytesWritten) Then
            If BytesWritten > 0 Then
                Marshal.FreeHGlobal(ptBuf)
                ptBuf = Marshal.AllocHGlobal(BytesWritten)
                'reget the PRINTER_INFO_2 structure
                If GetPrinter(hDestination, 2, ptBuf, BytesWritten, BytesWritten) Then
                    Marshal.PtrToStructure(ptBuf, PI2In)
                    PI2In.lpDeviceMode = hdmIn
                    Dim hPI2In As IntPtr
                    hPI2In = Marshal.AllocHGlobal(Marshal.SizeOf(PI2In))
                    Marshal.StructureToPtr(PI2In, hPI2In, False)
                    intRet = SetPrinter(hDestination, 2, hPI2In, PrinterControlCommands.PRINTER_CONTROL_SETPRINTERINFO)
                    Debug.Print(Err.LastDllError)
                    If intRet = 0 Then
                        Throw New Exception(Err.LastDllError & " unable to SetPrinter #1")
                        Return False
                    End If
                Else
                    Marshal.FreeHGlobal(ptBuf)
                    ClosePrinter(hDestination)
                    Throw New Exception(Err.LastDllError & " unable to GetPrinter #3 " & strFullPrinterPath)
                    Return False
                End If
            Else
                Throw New Exception(Err.LastDllError & " BytesWritten #2 " & BytesWritten)
                Return False
            End If
        End If
        Call ClosePrinter(hDestination)
        Marshal.FreeHGlobal(hdmIn)
        Dim lvItem As New ListViewItem
        lvItem = lvDestination.Items.Add(sPrinter)
        lvItem.SubItems.Add(PI2In.pDriverName)
        lvItem.SubItems.Add(PI2In.pShareName)
        lvDestination.Refresh()
        Me.Refresh()
        pi2 = Nothing
        PI2In = Nothing
        dmIn = Nothing
        dmOut = Nothing
        Return True
    End Function

24-09-2007 at 08:10 AM
View Profile Send Email to User Show All Posts | Quote Reply
AndreaVB Forum : API : DocumentProperties and SetPrinter problem
Next Topic (Change Windows Taskbar Color) New Topic New Poll Post Reply
Surf To:


Not Logged In? Username: Password: Lost your password?
Partners: Download Actual Software | Free Software Download
borderAndreaVB free resources for Visual Basic developersborder

borderAndreaVB Visual Basic and VB.NET source code resources - Copyright © 1999-2007 Andrea Tincaniborder