Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    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 As String * CCHFORMNAME
    dmLogPixels As Integer
    dmBitsPerPel As Long
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
    dmICMMethod As Long                ' // Windows 95 only
    dmICMIntent As Long                ' // Windows 95 only
    dmMediaType As Long                ' // Windows 95 only
    dmDitherType As Long               ' // Windows 95 only
    dmReserved1 As Long                ' // Windows 95 only
    dmReserved2 As Long                ' // Windows 95 only
End TypePublic Sub SetOrientationOrPageSize(ByVal dwOwnHwnd As Long, chng As tagToward, ByVal vPageSize As PrinterObjectConstants)
Dim PrinterHandle As Long
Dim PrinterName As String
Dim pd As PRINTER_DEFAULTS
Dim MyDevMode As DEVMODE
Dim Result As Long
Dim Needed As Long
Dim pFullDevMode As Long
Dim pi2_buffer() As Long                ' // This is a block of memory for the Printer_Info_2 structure
    PrinterName = Printer.DeviceName
    If PrinterName = "" Then
        Exit Sub
    End If
    
    On Error Resume Next
    pd.pDatatype = vbNullString
    pd.pDevMode = 0&
    pd.DesiredAccess = PRINTER_ALL_ACCESS
    
    Result = OpenPrinter(PrinterName, PrinterHandle, pd)
    Result = GetPrinter(PrinterHandle, 2, ByVal 0&, 0, Needed)
    ReDim pi2_buffer((Needed \ 4))
    Result = GetPrinter(PrinterHandle, 2, pi2_buffer(0), Needed, Needed)
    pFullDevMode = pi2_buffer(7)
    Call CopyMemory(MyDevMode, ByVal pFullDevMode, Len(MyDevMode))
    MyDevMode.dmDuplex = DMDUP_SIMPLEX
    MyDevMode.dmFields = DM_DUPLEX Or DM_ORIENTATION Or DM_PAPERSIZE
    MyDevMode.dmOrientation = chng
    MyDevMode.dmPaperSize = vPageSize
    Call CopyMemory(ByVal pFullDevMode, MyDevMode, Len(MyDevMode))
    Result = DocumentProperties(dwOwnHwnd, PrinterHandle, PrinterName, ByVal pFullDevMode, ByVal pFullDevMode, DM_IN_BUFFER Or DM_OUT_BUFFER)
    Result = SetPrinter(PrinterHandle, 2, pi2_buffer(0), 0&)
    Call ClosePrinter(PrinterHandle)
    Dim P As Printer
    For Each P In Printers
        If P.DeviceName = PrinterName Then
            Set Printer = P
            Exit For
        End If
    Next P
    Printer.Duplex = MyDevMode.dmDuplex
End Sub
一運行到 Call CopyMemory(MyDevMode, ByVal pFullDevMode, Len(MyDevMode))程序就自動退出,試了其它的程序(在別的2000SP4系統上能正常運行)也是一樣的,系統是2000的SP4,請問是不是有什麼系統組沒有裝好,

解决方案 »

  1.   

    估计是你的pFullDevMode为0,看看 Result = GetPrinter(PrinterHandle, 2, pi2_buffer(0), Needed, Needed) 
    这句执行后所返回的Result是不是0,如果是0的话,那就是GetPrinter函数没有调用成功。你可以在Result = GetPrinter(PrinterHandle, 2, pi2_buffer(0), Needed, Needed) 后面加上个Debug.Print Err.LastDllError,看看是什么错误
      

  2.   

    '这才是取地址操作!你拿数组的字节值做指针算什么意思?
    pFullDevMode = VarPtr(pi2_buffer(7))
      

  3.   

       NT系统 尽量用NTDLL API 代替 CopyMemory  必要时最好是声明成2个byval long   然后varptr   
      

  4.   

    Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal hpvDest As Long, ByVal hpvSource As Long, ByVal cbCopy As Long)
    Private Type DEVMODE
        dmDeviceName As String * CCHDEVICENAME
        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 As String * CCHFORMNAME
        dmLogPixels As Integer
        dmBitsPerPel As Long
        dmPelsWidth As Long
        dmPelsHeight As Long
        dmDisplayFlags As Long
        dmDisplayFrequency As Long
        dmICMMethod As Long                ' // Windows 95 only
        dmICMIntent As Long                ' // Windows 95 only
        dmMediaType As Long                ' // Windows 95 only
        dmDitherType As Long              ' // Windows 95 only
        dmReserved1 As Long                ' // Windows 95 only
        dmReserved2 As Long                ' // Windows 95 only
    End TypePublic Sub SetOrientationOrPageSize(ByVal dwOwnHwnd As Long, chng As tagToward, ByVal vPageSize As PrinterObjectConstants)
        Dim PrinterHandle As Long
        Dim PrinterName As String
        Dim pd As PRINTER_DEFAULTS
        Dim MyDevMode As DEVMODE
        Dim Result As Long
        Dim Needed As Long
        Dim pFullDevMode As Long
        Dim pi2_buffer() As Long                ' // This is a block of memory for the Printer_Info_2 structure
        
        PrinterName = Printer.DeviceName
        If PrinterName = "" Then
            Exit Sub
        End If
        
        On Error Resume Next
        
        pd.pDatatype = vbNullString
        pd.pDevMode = 0&
        pd.DesiredAccess = PRINTER_ALL_ACCESS
        
        Result = OpenPrinter(PrinterName, PrinterHandle, pd)
        Result = GetPrinter(PrinterHandle, 2, ByVal 0&, 0, Needed)
        
        ReDim pi2_buffer((Needed \ 4))
        
        Result = GetPrinter(PrinterHandle, 2, pi2_buffer(0), Needed, Needed)
        pFullDevMode = VarPtr(pi2_buffer(7))
        
        Call CopyMemory(VarPtr(MyDevMode), ByVal pFullDevMode, Len(MyDevMode))
        
        MyDevMode.dmDuplex = DMDUP_SIMPLEX
        MyDevMode.dmFields = DM_DUPLEX Or DM_ORIENTATION Or DM_PAPERSIZE
        MyDevMode.dmOrientation = chng
        MyDevMode.dmPaperSize = vPageSize
        
        Call CopyMemory(ByVal pFullDevMode, VarPtr(MyDevMode), Len(MyDevMode))
        
        Result = DocumentProperties(dwOwnHwnd, PrinterHandle, PrinterName, ByVal pFullDevMode, ByVal pFullDevMode, DM_IN_BUFFER Or DM_OUT_BUFFER)
        Result = SetPrinter(PrinterHandle, 2, pi2_buffer(0), 0&)
        
        Call ClosePrinter(PrinterHandle)
        
        Dim P As Printer
        
        For Each P In Printers
            If P.DeviceName = PrinterName Then
                Set Printer = P
                Exit For
            End If
        Next P
        Printer.Duplex = MyDevMode.dmDuplex
    End Sub
    试下.结合了上面的方案
      

  5.   

      老马 还是四处灌水啊 哈哈  好久没看见你了啊 偶闭关回来了。。  
       楼上的朋友  换成NTAPI试试