64位Word VBA DEVMODE.dmDuplex返回4

时间:2018-03-29 15:53:06

标签: vba 64-bit ms-office word-vba

我目前正在将VBA代码从旧的32位Office转换为64位Office。

我们有一项打印功能,允许用户将默认打印机设置从双面打印更改为单面打印,反之亦然。

我已经通过大部分代码用LongPTR替换Long并在声明函数时添加PtrSafe。

我遇到的问题是,在调用CopyMemory函数时,返回的DEVMODE包含64位和32位的不同值。见下文:

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

我最关心的是dmDuplex返回4(64位)和2(32位)。我目前假设它是CopyMemory函数是问题,但我没有任何正当理由承担这一点。

任何帮助都会得到满足。如果我错过了一些信息,请告诉我。

由于

0 个答案:

没有答案