Results 1 to 24 of 24

Thread: [RESOLVED] PrintDlgEx API failed to return full name of printer

Threaded View

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Resolved [RESOLVED] PrintDlgEx API failed to return full name of printer

    I used Krool's OpenPrinterEx function in CommonDialog class. The function failed to return the full name of the chosen printer. The printer name is "\\192.4.4.143\Canon iR2002/2202 UFRII LT(1)" showing on the Printer Dialog. But I watched the return printer name (NewPrinterName) is "\\192.4.4.143\Canon iR2002/220" which is 30 characters length. what is the reason?

    When a Microsoft Windows application prints, it must identify the target printer by its full name. The DEVMODE structure that was introduced in 16-bit Windows version 3.1 has a limitation of 32 characters for a printer name. However, printer names in Win32 operating systems can be much longer.
    Look like the string is being truncated. I tried to changed CCHDEVICENAME =32 to 128 to increase the buffer but still no luck. Maybe the DMDeviceName in DEVMODE structure should be defined to Pointer?

    Code:
    Private Type PRINTDLGEX
        lStructSize As Long
        hWndOwner As Long
        hDevMode As Long
        hDevNames As Long
        hDC As Long
        Flags As Long
        Flags2 As Long
        ExclusionFlags As Long
        nPageRanges As Long
        nMaxPageRanges As Long
        lpPageRanges As Long
        nMinPage As Long
        nMaxPage As Long
        nCopies As Long
        hInstance As Long
        lpPrintTemplateName As Long
        lpCallback As Long
        nPropertyPages As Long
        lphPropertyPages As Long
        nStartPage As Long
        dwResultAction As Long
    End Type
    
    Private Const CCHDEVNAMESEXTRA As Long = 100
    Private Type DEVNAMES
        wDriverOffset As Integer
        wDeviceOffset As Integer
        wOutputOffset As Integer
        wDefault As Integer
        wExtra(0 To ((CCHDEVNAMESEXTRA * 2) - 1)) As Byte
    End Type
    Private Const CCHDEVICENAME As Long = 128 '32
    Private Const CCHFORMNAME As Long = 32
    Private Const DM_ORIENTATION As Long = &H1
    Private Const DM_PAPERSIZE As Long = &H2
    Private Const DM_COPIES As Long = &H100
    Private Const DM_DEFAULTSOURCE As Long = &H200
    Private Const DM_PRINTQUALITY As Long = &H400
    Private Const DM_COLOR As Long = &H800
    Private Const DM_DUPLEX As Long = &H1000
    Private Const DM_COLLATE As Long = &H8000&
    Private Type DEVMODE
        DMDeviceName(0 To ((CCHDEVICENAME * 2) - 1)) As Byte
        DMSpecVersion As Integer
        DMDriverVersion As Integer
        DMSize As Integer
        DMDriverExtra As Integer
        DMFields As Long
        DMOrientation As Integer
        DMPaperSize As Integer
        DMPaperLength As Integer
        DMPaperWidth As Integer
        DMScale As Integer
        DMCopies As Integer
        DMDefaultSource As Integer
        DMPrintQuality As Integer
        DMColor As Integer
        DMDuplex As Integer
        DMYResolution As Integer
        DMTTOption As Integer
        DMCollate As Integer
        DMFormName(0 To ((CCHFORMNAME * 2) - 1)) As Byte
        DMLogPixels As Integer
        DMBitsPerPel As Long
        DMPelsWidth As Long
        DMPelsHeight As Long
        DMDisplayFlags As Long
        DMDisplayFrequency As Long
        DMICMMethod As Long
        DMICMIntent As Long
        DMMediaType As Long
        DMDitherType As Long
        DMReserved1 As Long
        DMReserved2 As Long
        DMPanningWidth As Long
        DMPanningHeight As Long
    End Type
    
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
    Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
    Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
    Private Declare Function PrintDialogEx Lib "comdlg32" Alias "PrintDlgExW" (ByRef lpPrintDlgEx As PRINTDLGEX) As Long
    
    Private PropFlags As Long
    Private PropMin As Long, PropMax As Long
    Private PropFromPage As Long, PropToPage As Long
    Private PropPrinterDefault As Boolean
    Code:
    Public Function ShowPrinterEx() As CdlPDResultConstants
    Dim PDLGEX As PRINTDLGEX, PPAGERANGE As PRINTPAGERANGE, DMODE As DEVMODE, DNAMES As DEVNAMES
    Dim lpDevMode As Long, lpDevNames As Long
    Dim ObjPrinter As VB.Printer, NewPrinterName As String, Buffer As String
    With PDLGEX
    .lStructSize = LenB(PDLGEX)
    If Not Screen.ActiveForm Is Nothing Then
        .hWndOwner = Screen.ActiveForm.hWnd
    Else
        .hWndOwner = GetActiveWindow()
    End If
    .Flags = PropFlags
    .nPageRanges = 1
    .nMaxPageRanges = 1
    PPAGERANGE.nFromPage = PropFromPage
    PPAGERANGE.nToPage = PropToPage
    .nMinPage = PropMin
    .nMaxPage = PropMax
    .lpPageRanges = VarPtr(PPAGERANGE)
    Const START_PAGE_GENERAL As Long = &HFFFFFFFF
    .nStartPage = START_PAGE_GENERAL
    End With
    If VB.Printers.Count > 0 And (PDLGEX.Flags And CdlPDReturnDefault) = 0 Then
        With VB.Printer
        DMODE.DMSize = LenB(DMODE)
        Buffer = Left$(.DeviceName, CCHDEVICENAME)
        CopyMemory DMODE.DMDeviceName(0), ByVal StrPtr(Buffer), LenB(Buffer)
        DMODE.DMFields = DM_ORIENTATION Or DM_PAPERSIZE Or DM_COPIES Or DM_DEFAULTSOURCE Or DM_PRINTQUALITY Or DM_COLOR Or DM_DUPLEX Or DM_COLLATE
        DMODE.DMOrientation = .Orientation
        DMODE.DMPaperSize = .PaperSize
        DMODE.DMCopies = .Copies
        DMODE.DMDefaultSource = .PaperBin
        DMODE.DMPrintQuality = .PrintQuality
        DMODE.DMColor = .ColorMode
        DMODE.DMDuplex = .Duplex
        DMODE.DMCollate = IIf((PDLGEX.Flags And CdlPDCollate) <> 0, 1, 0)
        DNAMES.wDriverOffset = 4
        DNAMES.wDeviceOffset = DNAMES.wDriverOffset + Len(.DriverName) + 1
        DNAMES.wOutputOffset = DNAMES.wDeviceOffset + Len(.DeviceName) + 1
        DNAMES.wDefault = 0
        Buffer = Left$(.DriverName & vbNullChar & .DeviceName & vbNullChar & .Port & vbNullChar, CCHDEVNAMESEXTRA)
        CopyMemory DNAMES.wExtra(0), ByVal StrPtr(Buffer), LenB(Buffer)
        PDLGEX.nCopies = .Copies
        PDLGEX.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DMODE))
        lpDevMode = GlobalLock(PDLGEX.hDevMode)
        CopyMemory ByVal lpDevMode, DMODE, LenB(DMODE)
        GlobalUnlock PDLGEX.hDevMode
        PDLGEX.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DNAMES))
        lpDevNames = GlobalLock(PDLGEX.hDevNames)
        CopyMemory ByVal lpDevNames, DNAMES, LenB(DNAMES)
        GlobalUnlock PDLGEX.hDevNames
        End With
    End If
    Dim ErrVal As Long
    If PropHookEvents = False Then
        ErrVal = PrintDialogEx(PDLGEX)
    Else
        Call ComCtlsCdlPDEXSetHook(Me)
        ErrVal = PrintDialogEx(PDLGEX)
        Call ComCtlsCdlPDEXRemoveHook
    End If
    If ErrVal = S_OK Then
        If PDLGEX.dwResultAction <> CdlPDResultCancel Then
            lpDevMode = GlobalLock(PDLGEX.hDevMode)
            CopyMemory DMODE, ByVal lpDevMode, LenB(DMODE)
            GlobalUnlock PDLGEX.hDevMode
            GlobalFree PDLGEX.hDevMode
            lpDevNames = GlobalLock(PDLGEX.hDevNames)
            CopyMemory DNAMES, ByVal lpDevNames, LenB(DNAMES)
            GlobalUnlock PDLGEX.hDevNames
            GlobalFree PDLGEX.hDevNames
            NewPrinterName = Left$(DMODE.DMDeviceName(), InStr(DMODE.DMDeviceName(), vbNullChar) - 1)
            Dim PrinterFound As Boolean
            If StrComp(VB.Printer.DeviceName, NewPrinterName, vbTextCompare) <> 0 Then
                For Each ObjPrinter In VB.Printers
                    If StrComp(ObjPrinter.DeviceName, NewPrinterName, vbTextCompare) = 0 Then
                        Set VB.Printer = ObjPrinter
                        PrinterFound = True
                        Exit For
                    End If
                Next ObjPrinter
            Else
                PrinterFound = True
            End If
            If PropPrinterDefault = True Then Call SetPrinterDefault(NewPrinterName)
            If PrinterFound = True Then
                On Error Resume Next
                With VB.Printer
                .Copies = DMODE.DMCopies
                .Duplex = DMODE.DMDuplex
                .Orientation = DMODE.DMOrientation
                .PaperSize = DMODE.DMPaperSize
                .PrintQuality = DMODE.DMPrintQuality
                .ColorMode = DMODE.DMColor
                .PaperBin = DMODE.DMDefaultSource
                End With
                On Error GoTo 0
            End If
            PropFlags = PDLGEX.Flags
            If (PropFlags And CdlPDUseDevModeCopiesAndCollate) <> 0 Then
                If DMODE.DMCollate = 1 And (PropFlags And CdlPDCollate) = 0 Then PropFlags = PropFlags Or CdlPDCollate
            End If
            PropFromPage = PPAGERANGE.nFromPage
            PropToPage = PPAGERANGE.nToPage
            PropMin = PDLGEX.nMinPage
            PropMax = PDLGEX.nMaxPage
            If (PropFlags And (CdlPDReturnDC Or CdlPDReturnIC)) <> 0 Then PropDC = PDLGEX.hDC
            ShowPrinterEx = PDLGEX.dwResultAction
        Else
            If PropCancelError = True Then Err.Raise Number:=CdlCancel, Description:="Cancel was selected."
        End If
    Else
        If PDLGEX.hDevMode <> 0 Then GlobalFree PDLGEX.hDevMode
        If PDLGEX.hDevNames <> 0 Then GlobalFree PDLGEX.hDevNames
        Const E_OUTOFMEMORY As Long = &H8007000E, E_INVALIDARG As Long = &H80070057, E_POINTER As Long = &H80004003, E_HANDLE As Long = &H80070006, E_FAIL As Long = &H80004005
        Select Case ErrVal
            Case E_OUTOFMEMORY, E_INVALIDARG, E_POINTER, E_HANDLE, E_FAIL
                Err.Raise Number:=CdlInitFailure, Description:="The PrintDlgEx function failed during initialization."
            Case Else
                Err.Raise Number:=ErrVal, Description:="Unexpected error."
        End Select
    End If
    End Function
    Name:  OpenPrinterEx_2.jpg
Views: 2655
Size:  35.6 KB



    Name:  OpenPrinterEx_Dialog.png
Views: 2690
Size:  29.8 KB
    Last edited by Jonney; Apr 12th, 2015 at 07:31 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width