locked
Add Custom paze size to HP Printer RRS feed

  • Question

  • Hi,

      I am using Windows API to add a Custom Envelope size to the printer which is done successfully.Now when I use a HP printer the code does not seem to do anything. Please could you suggest a approach for this . Also I need to set the custom size as default size to the printer.

    I have this method for adding custom form other than HP printers :

    Public Shared Sub AddCustomPaperSize(ByVal printerName As String, ByVal paperName As String, ByVal widthMm As Single, ByVal heightMm As Single)

                If PlatformID.Win32NT = Environment.OSVersion.Platform Then
                    ' The code to add a custom paper size is different for Windows NT then it is
                    ' for previous versions of windows

                    Const PRINTER_ACCESS_USE As Integer = &H8
                    Const PRINTER_ACCESS_ADMINISTER As Integer = &H4
                    'Const FORM_PRINTER As Integer = &H2

                    Dim defaults As New structPrinterDefaults()
                    defaults.pDatatype = Nothing
                    defaults.pDevMode = IntPtr.Zero
                    defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE

                    Dim hPrinter As IntPtr = IntPtr.Zero

                    ' Open the printer.
                    If OpenPrinter(printerName, hPrinter, defaults) Then
                        Try
                            ' delete the form incase it already exists
                            DeleteForm(hPrinter, paperName)
                            ' create and initialize the FORM_INFO_1 structure
                            Dim formInfo As New FormInfo1()
                            formInfo.Flags = 0
                            'formInfo.pName = paperName
                            ' all sizes in 1000ths of millimeters
                            formInfo.Size.width = CInt(Math.Truncate(widthMm * 1000.0))
                            formInfo.Size.height = CInt(Math.Truncate(heightMm * 1000.0))
                            formInfo.ImageableArea.left = 0
                            formInfo.ImageableArea.right = formInfo.Size.width
                            formInfo.ImageableArea.top = 0
                            formInfo.ImageableArea.bottom = formInfo.Size.height

                            If Not AddForm(hPrinter, 1, formInfo) Then
                                Dim strBuilder As New StringBuilder()
                                strBuilder.AppendFormat("Failed to add the custom paper size {0} to the printer {1}, System error number: {2}", paperName, printerName, GetLastError())
                                Throw New ApplicationException(strBuilder.ToString())
                            End If

                            ' INIT
                            Const DM_OUT_BUFFER As Integer = 2
                            Const DM_IN_BUFFER As Integer = 8
                            Dim devMode As New structDevMode()
                            Dim hPrinterInfo As IntPtr, hDummy As IntPtr
                            Dim printerInfo As PRINTER_INFO_9
                            printerInfo.pDevMode = IntPtr.Zero
                            Dim iPrinterInfoSize As Integer, iDummyInt As Integer


                            ' GET THE SIZE OF THE DEV_MODE BUFFER
                            Dim iDevModeSize As Integer = DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0)

                            If iDevModeSize < 0 Then
                                Throw New ApplicationException("Cannot get the size of the DEVMODE structure.")
                            End If

                            ' ALLOCATE THE BUFFER
                            Dim hDevMode As IntPtr = Marshal.AllocCoTaskMem(iDevModeSize + 100)

                            ' GET A POINTER TO THE DEV_MODE BUFFER
                            Dim iRet As Integer = DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER)

                            If iRet < 0 Then
                                Throw New ApplicationException("Cannot get the DEVMODE structure.")
                            End If

                            ' FILL THE DEV_MODE STRUCTURE
                            devMode = CType(Marshal.PtrToStructure(hDevMode, devMode.[GetType]()), structDevMode)

                            ' SET THE FORM NAME FIELDS TO INDICATE THAT THIS FIELD WILL BE MODIFIED
                            devMode.dmFields = &H10000
                            ' DM_FORMNAME
                            ' SET THE FORM NAME
                            devMode.dmFormName = paperName

                            ' PUT THE DEV_MODE STRUCTURE BACK INTO THE POINTER
                            Marshal.StructureToPtr(devMode, hDevMode, True)

                            ' MERGE THE NEW CHAGES WITH THE OLD
                            iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, printerInfo.pDevMode, printerInfo.pDevMode, DM_IN_BUFFER Or DM_OUT_BUFFER)

                            If iRet < 0 Then
                                Throw New ApplicationException("Unable to set the orientation setting for this printer.")
                            End If

                            ' GET THE PRINTER INFO SIZE
                            GetPrinter(hPrinter, 9, IntPtr.Zero, 0, iPrinterInfoSize)
                            If iPrinterInfoSize = 0 Then
                                Throw New ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure")
                            End If

                            ' ALLOCATE THE BUFFER
                            hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100)

                            ' GET A POINTER TO THE PRINTER INFO BUFFER
                            Dim bSuccess As Boolean = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, iDummyInt)

                            If Not bSuccess Then
                                Throw New ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure")
                            End If

                            ' FILL THE PRINTER INFO STRUCTURE
                            printerInfo = CType(Marshal.PtrToStructure(hPrinterInfo, printerInfo.[GetType]()), PRINTER_INFO_9)
                            printerInfo.pDevMode = hDevMode

                            ' GET A POINTER TO THE PRINTER INFO STRUCTURE
                            Marshal.StructureToPtr(printerInfo, hPrinterInfo, True)

                            ' SET THE PRINTER SETTINGS
                            bSuccess = SetPrinter(hPrinter, 9, hPrinterInfo, 0)

                            If Not bSuccess Then
                                Throw New Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed.  Couldn't set the printer settings")
                            End If

                            ' Tell all open programs that this change occurred.
                            SendMessageTimeout(New IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, CustomPrintForm.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, _
                             hDummy)
                        Finally
                            ClosePrinter(hPrinter)
                        End Try
                    Else
                        Dim strBuilder As New StringBuilder()
                        strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}", printerName, GetLastError())
                        Throw New ApplicationException(strBuilder.ToString())
                    End If
                Else
                    Dim pDevMode As New structDevMode()
                    Dim hDC As IntPtr = CreateDC(Nothing, printerName, Nothing, pDevMode)
                    If hDC <> IntPtr.Zero Then
                        Const DM_PAPERSIZE As Long = &H2L
                        Const DM_PAPERLENGTH As Long = &H4L
                        Const DM_PAPERWIDTH As Long = &H8L
                        pDevMode.dmFields = CInt(DM_PAPERSIZE Or DM_PAPERWIDTH Or DM_PAPERLENGTH)
                        pDevMode.dmPaperSize = 256
                        pDevMode.dmPaperWidth = CShort(Math.Truncate(widthMm * 1000.0))
                        pDevMode.dmPaperLength = CShort(Math.Truncate(heightMm * 1000.0))
                        ResetDC(hDC, pDevMode)
                        DeleteDC(hDC)
                    End If
                End If
            End Sub

    Friday, November 2, 2012 8:23 AM

Answers

  • I understand that you want your code run with different printers. However, Printer driver can control this by itself. If we simply goto Page/Quality page of Printer property, we will be able to control the page size successfully. That is because the interface is customized by the HP.

    Generally, your code should work as expected. But if the printer driver has some compatibility issues, it may fail. As I said in my last reply, if you want to find out what is the root cause, you need to contact Microsoft support at http://support.microsoft.com . Then you can ask HP to fix issues in the driver. 


    Alan Yao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, November 6, 2012 2:08 AM
    Moderator

All replies

  • Hi Amrita,

    I'm involving some senior engineers into this thread, this may take a bit more time.

    Thanks for your patience.


    Shanks Zen
    MSDN Community Support | Feedback to us

    Monday, November 5, 2012 6:06 AM
    Moderator
  • Hi,

    Per my experience, this should be related to the Printer driver. I hanled one similar case last year, and the behavior is the customer's code was working well with some printers but not for others. Finnally, we found some exceptions occurred in memory dump and we were able to fix the issue by update the printer dirver.

    Let's do some tests about this:

    1. Try your code on different editions of HP Printers. And see if it works.

    2. Update the Printer driver to latest.

    If the code still does not work, I think you need to contact Microsoft Phone support http://support.micosoft.com to analyze memory dump.


    Alan Yao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Monday, November 5, 2012 6:07 AM
    Moderator
  • I have installed HP Universal Printer PCL5 drivers and my custom form is available for printing on it. However for HP DeskJet , I have uninstalled and reinstalled the latest drivers but it does not work. My code needs to run with different printers.
    Monday, November 5, 2012 9:52 AM
  • I understand that you want your code run with different printers. However, Printer driver can control this by itself. If we simply goto Page/Quality page of Printer property, we will be able to control the page size successfully. That is because the interface is customized by the HP.

    Generally, your code should work as expected. But if the printer driver has some compatibility issues, it may fail. As I said in my last reply, if you want to find out what is the root cause, you need to contact Microsoft support at http://support.microsoft.com . Then you can ask HP to fix issues in the driver. 


    Alan Yao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, November 6, 2012 2:08 AM
    Moderator