Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Setting Devmode?!.......

Status
Not open for further replies.

cturland

Programmer
Sep 25, 2000
66
GB
Hi all,

Has anyone else had trouble using the settings in Devmode? I'm trying to set some of the values for printing but the program doesn't seem to take much notice of them and its really frustrating!!!! I'm using windows NT incase that has anything to do with it?

I've declared Devmode as a type with all its attributes in a module and then this is a bit of the code I am using,

dim prtset as Devmode

prtset.dmuserdefault = 1
prtset.dmorientation = DMORIEN_LANDSCAPE

prtset.fields = DM_USERDEFAULT OR DM_ORIENTATION

Any help would be really appreciated! I've seen the topic in the FAQ's but that doesn't seem to work either!

Regards,
Carl
 
What's not working? I am having the same problem, i think (trying to set tray, also, and it doesn't work for me either)
Thanks,
James
[shadeshappy] [evil]
 
which bit of the devmode structure does this line refer too

>prtset.dmuserdefault =1

If somethings hard to do, its not worth doing - Homer Simpson
 
the following is an app to retrieve devmode info (in debug), you should be able to alter the code as necessary to check the values you are assigning have actually been assigned!

(the code is based around code found in "win32 API programming with visual basic" but cut from an old project-apologies if there are any glitches)

Code:
Private Declare Function EnumPrinters Lib "winspool.drv" _
    Alias "EnumPrintersA" ( _
    ByVal flags As Long, _
    ByVal name As String, _
    ByVal Level As Long, _
    pPrinterEnum As Long, _
    ByVal cdBuf As Long, _
    pcbNeeded As Long, _
    pcReturned As Long _
) As Long

Private Declare Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" ( _
    Destination As Any, _
    Source As Any, _
    ByVal Length As Long _
)

Private Declare Function lstrlenA Lib "kernel32" ( _
    ByVal lpsz As Long _
) As Long

Const PRINTER_ENUM_LOCAL = &H2

Const CCHDEVICENAME As Integer = 32
Const CCFORMNAME As Integer = 32

Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Integer
    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 * CCFORMNAME
    dmUnusedPadding 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
End Type

Private Type PRINTER_INFO_2
    pServerName As Long
    pPrinterName As Long
    pShareName As Long
    pPortName As Long
    pDriverName As Long
    pComment As Long
    pLocation As Long
    pDevMode As Long
    pSepFile As Long
    pPrintProcessor As Long
    pDatatype As Long
    pParameters As Long
    pSecurityDescriptor As Long
    Attributes As Long
    Priority As Long
    DefaultPriority As Long
    StartTime As Long
    UntilTime As Long
    Status As Long
    cJobs As Long
    AveragePPM As Long
End Type

Private Sub ListPrinters()
    Dim lNeeded As Long
    Dim lReturned As Long
    Dim lData() As Long
    Dim pi2 As PRINTER_INFO_2
    Dim dm As DEVMODE
    Dim i As Integer
    
    ReDim lData(0 To 4000)
    
    EnumPrinters PRINTER_ENUM_LOCAL, vbNullString, 2, _
        lData(0), 4000, lNeeded, lReturned
    Debug.Print "Needed:" & lNeeded
    Debug.Print "Returned:" & lReturned
    
    If lNeeded > 4000 Then MsgBox "increase buffer size"
    
    For i = 0 To lReturned - 1
        Debug.Print "** Printer " & i
        
        CopyMemory ByVal VarPtr(pi2), ByVal VarPtr(lData(i * LenB(pi2) / 4)), LenB(pi2)
        
        Debug.Print "Name: " & LPSTRtoBSTR(pi2.pPrinterName)
        Debug.Print "Port: " & LPSTRtoBSTR(pi2.pPortName)
        Debug.Print "Driver: " & LPSTRtoBSTR(pi2.pDriverName)
        Debug.Print "Comment: " & LPSTRtoBSTR(pi2.pComment)
        
        CopyMemory ByVal VarPtr(dm), ByVal pi2.pDevMode, LenB(dm)
        Debug.Print "Driver Ver: " & dm.dmDriverVersion
        'etc etc etc

    Next
    
End Sub

Private Sub Form_Load()
ListPrinters
End Sub

Function LPSTRtoBSTR(ByVal lpsz As Long) As String

' Input: a valid LPSTR pointer lpsz
' Output: a sBSTR with the same character array

Dim cChars As Long

' Get number of characters in lpsz
cChars = lstrlenA(lpsz)

' Initialize string
LPSTRtoBSTR = String$(cChars, 0)

' Copy string
CopyMemory ByVal StrPtr(LPSTRtoBSTR), ByVal lpsz, cChars

' Convert to Unicode
LPSTRtoBSTR = Trim0(StrConv(LPSTRtoBSTR, vbUnicode))

End Function

Public Function Trim0(sName As String) As String

' Keep left portion of string sName up to first 0. Useful with Win API null terminated strings.

Dim X As Integer
X = InStr(sName, Chr$(0))
If X > 0 Then Trim0 = Left$(sName, X - 1) Else Trim0 = sName

End Function
not a solution but a step that may help!! If somethings hard to do, its not worth doing - Homer Simpson
 
now how do you set settings to the devmode structure? Thanks,
James
[shadeshappy] [evil]
 
at the moment i dont know exactly (its not the easiest thing ever to do) and i dont have any code handy but,

i think it requires using

1) enumprinters to get the pi2 data

2) openprinter api to retrieve the devmode data for the desired printer (in the printer_default structure)

3)copy returned devmode object to a new one (DM2, say)change your devmode values (in dm2) as you need

4)use documentproperties api to set printer

good luck!! If somethings hard to do, its not worth doing - Homer Simpson
 
could you elaborate on exactialy how to do this, this process works on my development machines (xp,me,2k), however, in the field, it works on none (os doesn't matter, xp, me, 2k). I am stumpted by this. Thanks,
James
[shadeshappy] [evil]
 
would it be possible for you to post the code that works on your dev machines (save me having to type it all out!) then ill see if i can help you more! If somethings hard to do, its not worth doing - Homer Simpson
 
Just checking the obvious here: is the user on the machines that the code does not work on a member of the requisite security groups? i.e. do they actually have permissions to modify printer settings?
 
You can check if changing DEVMODE settings will work successfully on your system by downloading an evaluation copy of PDXPro from my web site. It's an ActiveX DLL that wraps most of the printer API functions. It includes a test bench exe so you can check out the dll without writing code.

I might be able to dig out some source code but it won't be easy to pick out/put together the relevant bits as they're divided across various subs, functions and modules.

Paul Bent
Northwind IT Systems
 
to elaborate more, it is working on 2 machines now (since sat) those two are on an hp. the others are on a lexmark. And by all outward appreacnces it is changeing (modified it over the weekend to work) however, i think i am doing some thing wrong because it seems to be setting the 'default' settings first, the code is long but i'll post it. Thanks,
James
[shadeshappy] [evil]
 
Code:
Public Sub SetPrinterJob(PrinterName As String, PrinterQuality As Long, PrinterQuantaty As Long, PrinterOrentation As Long, PrinterTray As Long)
'On Error Resume Next
    Dim PrinterHandle As Long
    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
    Dim i As Long
    
    If PrinterName = "" Then
  Exit Sub
    End If
    
    OldPrinterName = Printer.DeviceName
    OldPrinterTray = Printer.PaperBin
    OldPrinterOrentation = Printer.Orientation
    OldPrinterQuality = Printer.PrintQuality
    OldPrinterQuantaty = Printer.Copies
For i = 0 To 2
    DoEvents
    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.dmDeviceName = Printer.DeviceName
    MyDevMode.dmDuplex = DMDUP_SIMPLEX
    MyDevMode.dmFields = DM_DUPLEX Or DM_ORIENTATION Or DM_COPIES Or DM_PRINTQUALITY Or DM_DEFAULTSOURCE
    MyDevMode.dmOrientation = PrinterOrentation
    MyDevMode.dmCopies = PrinterQuantaty
    MyDevMode.dmDefaultSource = PrinterTray
    MyDevMode.dmPrintQuality = PrinterQuality
    

    
    Call CopyMemory(ByVal pFullDevMode, MyDevMode, Len(MyDevMode))
    Result = DocumentProperties(FrmPreview.hwnd, 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
    DoEvents
    Next i
    Exit Sub

    Call ErrorTracking("SetOrenatation", CStr(Err.Number), Err.Description, 1)

End Sub
the settings i am passing to this sub are straight from the new common dialog for printers from microsoft. It works on my hp laserjet 4000t, but not my lexmark t520 (non-development machines)
thanks for all the help Thanks,
James
[shadeshappy] [evil]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top