64 bit Word VBA DEVMODE.dmDuplex returns 4

拟墨画扇 提交于 2020-08-06 05:31:12

问题


I am currently in the process of converting the VBA code from the old 32bit Office to 64bit Office.

We have a printing functionality that allows the user to change the default printers setting from duplex to simplex and vice versa.

I have gone though the majority of my code replacing Long with LongPTR and adding PtrSafe when declaring functions.

The issue I am having is that when calling the CopyMemory function, the returned DEVMODE contains different values in 64 bit and 32 bit. See below:

Private Type DEVMODE
  dmDeviceName As String * 32
  dmSpecVersion As Integer
  dmDriverVersion As Integer
  dmSize As Integer
  dmDriverExtra As Integer
  dmFields As LongPtr
  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 As String * 32
  dmUnusedPadding As Integer
  dmBitsPerPel As Integer
  dmPelsWidth As LongPtr
  dmPelsHeight As LongPtr
  dmDisplayFlags As LongPtr
  dmDisplayFrequency As LongPtr
  dmICMMethod As LongPtr
  dmICMIntent As LongPtr
  dmMediaType As LongPtr
  dmDitherType As LongPtr
  dmReserved1 As LongPtr
  dmReserved2 As LongPtr
End Type

Private Function GetPrinterProperty(ByVal psPrinterName As String, ByVal 
iPropertyType As LongPtr) As LongPtr

Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal cbLength As LongPtr)

 Dim hPrinter As LongPtr
 Dim pd As PRINTER_DEFAULTS
 Dim dm As DEVMODE

 Dim yDevModeData() As Byte
 Dim iRet As LongPtr

 On Error GoTo cleanup

 'pd.DesiredAccess = PRINTER_NORMAL_ACCESS
 pd.DesiredAccess = PRINTER_ACCESS_USE

 'Get the printer handle
 iRet = OpenPrinter(psPrinterName, hPrinter, pd)
 If (iRet = 0) Or (hPrinter = 0) Then
    'Couldn't access the printer
     Exit Function
 End If

 'Find out how many bytes needed for the printer properties
 iRet = DocumentProperties(0, hPrinter, psPrinterName, 0, 0, 0)
 If (iRet < 0) Then
    'Couldn't access printer properties
     GoTo cleanup
 End If

 'Make sure the byte array is large enough, including the
 '100 bytes extra in case the printer driver is lying.
 ReDim yDevModeData(0 To CLng(iRet) * 24) As Byte

 'Load the printer properties into the byte array
 iRet = DocumentProperties(0, hPrinter, psPrinterName, 
 VarPtr(yDevModeData(0)), 0, DM_OUT_BUFFER)
 If (iRet < 0) Then
    'Couldn't access printer properties
    GoTo cleanup
 End If

 'Copy the byte array to the DEVMODE structure
 Call CopyMemory(dm, yDevModeData(0), Len(dm))

 If Not dm.dmFields And iPropertyType = 0 Then
    'Requested property not available on this printer.
    GoTo cleanup
 End If

 'Get the value of the requested property
 Select Case iPropertyType
 Case DM_ORIENTATION
    GetPrinterProperty = dm.dmOrientation
 Case DM_PAPERSIZE
    GetPrinterProperty = dm.dmPaperSize
 Case DM_PAPERLENGTH
    GetPrinterProperty = dm.dmPaperLength
 Case DM_PAPERWIDTH
    GetPrinterProperty = dm.dmPaperWidth
 Case DM_DEFAULTSOURCE
    GetPrinterProperty = dm.dmDefaultSource
 Case DM_PRINTQUALITY
    GetPrinterProperty = dm.dmPrintQuality
 Case DM_COLOR
    GetPrinterProperty = dm.dmColor
 Case DM_DUPLEX
    GetPrinterProperty = dm.dmDuplex
 End Select

 cleanup:
   'Release the printer handle
  If (hPrinter <> 0) Then Call ClosePrinter(hPrinter)

End Function

The value that I am most concerned about is the dmDuplex is returning 4 (for 64bit) and 2 (for 32bit). I am currently assuming that it is the CopyMemory function that is the issue but I do not have any valid reason to assume this.

Any help would be appriciated. If I have missed some information please let me know.

Thanks

来源:https://stackoverflow.com/questions/49560317/64-bit-word-vba-devmode-dmduplex-returns-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!