Link to home
Start Free TrialLog in
Avatar of David Schmalzer
David SchmalzerFlag for United States of America

asked on

Printing in Landscape

I have seen many entries about this question, but am not convinced that a solution has been posted or exists.  I want to print a form in landscape every time from a button. I am running Windows 2000(Soon going to XP) and Notes Client 5.0.11 (soon to go to 6.5). If there is any script to do this please post with detailed importing or pasting instructions.  Thanks.

PS.
Need asap.
Avatar of mbonaci
mbonaci
Flag of Croatia image

Hi schmad01,

Create new ScriptLibrary and paste this code in Declarations:

'Script Library

Type DIVT
     quot As Long
     remain As Long
End Type

Private Type PRINTER_DEFAULTS
     pDatatype As Long
     pDevmode As Long
     DesiredAccess 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

Type DEVMODE
     dmDeviceName As String * 32
     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 * 32
     dmUnusedPadding As Integer
     dmBitsPerPel As Integer
     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

Declare Function ClosePrinter Lib "winspool.drv" (Byval hPrinter As Long) As Long

Declare Function DocumentProperties Lib "winspool.drv"_
Alias "DocumentPropertiesA" (Byval hwnd As Long, _
Byval hPrinter As Long, Byval pDeviceName As String, _
pDevModeOutput As Long, pDevModeInput As Long, _
Byval fMode As Long) As Long

Declare Function GetPrinter Lib "winspool.drv" Alias _
"GetPrinterA" (Byval hPrinter As Long, Byval Level As Long, _
pPrinter As Long, Byval cbBuf As Long, pcbNeeded As Long) As Long

Declare Function OpenPrinter Lib "winspool.drv" Alias _
"OpenPrinterA" (Byval pPrinterName As String, phPrinter As Long, _
pDefault As PRINTER_DEFAULTS) As Long

Declare Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" (Byval hPrinter As Long,_
Byval Level As Long, pPrinter As Long, Byval commandl As Long) As Long

Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" _
(pDest As DEVMODE, pSource As Long, Byval cbLength As Long)

Declare Sub CopyMemoryBack Lib "Kernel32" Alias "RtlMoveMemory" _
(pDest As Long, pSource As DEVMODE, Byval cbLength As Long)

Declare Sub CopyMemoryPI Lib "Kernel32" Alias "RtlMoveMemory" _
(pDest As PRINTER_INFO_2, pSource As Long, Byval cbLength As Long)

Declare Sub CopyMemoryBackPI Lib "Kernel32" Alias "RtlMoveMemory" _
(pDest As Long, pSource As PRINTER_INFO_2, Byval cbLength As Long)

Declare Function labs Lib "msvcrt.dll" Alias "labs"_
(param As Long) As Long

Declare Function ldiv Lib "msvcrt.dll" (Byval q As Long, divisor As Long) As Long

Function SetPrinterOrientation(Byval sPrinterName As String,Byval orientation As Integer) As Long
     
     Const DM_IN_BUFFER = 8
     Const DM_OUT_BUFFER = 2
     Const PRINTER_ACCESS_ADMINISTER = &H4
     Const PRINTER_ACCESS_USE = &H8
     Const STANDARD_RIGHTS_REQUIRED = &HF0000
     Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
     PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
     
     
     Dim hPrinter As Long
     Dim pd As PRINTER_DEFAULTS
     Dim pinfo As PRINTER_INFO_2
     Dim dm As DEVMODE
     Dim dm2 As DEVMODE
     Dim yDevModeData() As Long
     Dim yPInfoMemory() As Long
     Dim nBytesNeeded As Long
     Dim nRet As Long, nJunk As Long
     Dim q As Long
     
     On Error Goto cleanup
     
 'Open printer with all access to be able to modify settings
     pd.DesiredAccess = PRINTER_ALL_ACCESS
     nRet = OpenPrinter(sPrinterName, hPrinter, pd)
     nRet = DocumentProperties(0, hPrinter, sPrinterName, 0, 0, 0)
     If (nRet < 0) Then
          Msgbox "Cannot get the size of the DEVMODE structure."
          Goto cleanup
     End If
     
     Redim yDevModeData(nRet + 100) As Long
     
     nRet = DocumentProperties(0, hPrinter, sPrinterName, yDevModeData(0), 0, DM_OUT_BUFFER)
     If (nRet < 0) Then
          Msgbox "Cannot get the DEVMODE structure."
          Goto cleanup
     End If
     
     Call CopyMemory(dm, yDevModeData(0), Len(dm))
     dm.dmOrientation = orientation
     Call CopyMemoryBack(yDevModeData(0), dm, Len(dm))
     nRet = DocumentProperties(0, hPrinter, sPrinterName, _
     yDevModeData(0), yDevModeData(0), _
     DM_IN_BUFFER Or DM_OUT_BUFFER)
     
     If (nRet < 0) Then
          Msgbox "Unable to set some settings to this printer."
          Goto cleanup
     End If
     
     Call GetPrinter(hPrinter, 2, 0, 0, nBytesNeeded)
     If (nBytesNeeded = 0) Then Goto cleanup
     
     Redim yPInfoMemory(nBytesNeeded + 100) As Long
     
     nRet = GetPrinter(hPrinter, 2, yPInfoMemory(0), nBytesNeeded, nJunk)
     If (nRet = 0) Then
          Msgbox "Unable to get shared printer settings."
          Goto cleanup
     End If
     
     Call CopyMemoryPI(pinfo, yPInfoMemory(0), Len(pinfo))
     pinfo.pDevmode = labs(yDevModeData(0))
     pinfo.pSecurityDescriptor = 0
     Call CopyMemoryBackPI(yPInfoMemory(0), pinfo, Len(pinfo))
     
     nRet = SetPrinter(hPrinter, 2, yPInfoMemory(0), 0)
     If (nRet = 0) Then
          Msgbox "Unable to set shared printer settings."
     End If
     
     SetPrinterOrientation = nRet
     
cleanup:
     If (hPrinter <> 0) Then Call ClosePrinter(hPrinter)
     
End Function





In the form (view) where the action button is place this in Globals - Declarations:


'Declarations
Declare Function GetProfileString Lib "Kernel32" Alias "GetProfileStringA" (Byval lpAppName As String, Byval lpKeyName As String, _
Byval lpDefault As String, Byval lpReturnedString As String, Byval nSize As Long) As Long




This is the action button's Click event:


Sub Click(Source As Button)
    Dim result As Variant
    Dim printerName As String
    Dim nPos As String
   
'Get the printer name
    printerName = String(128, 0)
    result = GetProfileString("WINDOWS", "DEVICE", "", printerName, 127)
    nPos = Instr(printerName, ",")
    printerName = Left(printerName, nPos - 1)
'Set the default printer to landscape (printer name, landscape orientation)
    result = SetPrinterOrientation(printerName, 2)


    'Here call print or do other stuff you need before printing

End Sub



Taken from:
https://www.experts-exchange.com/questions/21235390/Trying-to-print-parent-child-documents-landscape-without-print-setup-dialog-coming-up-at-each-document-that-prints.html


Hope this helps,
Marko
schmad01,
I forgot:
in Globals - Options of form/view where the action is place this:

    Use "TheNameOfScriptLibraryYouCreatedInDoubleQuotes"


Marko
Avatar of David Schmalzer

ASKER

Ok, will try this afternoon.
Avatar of marilyng
marilyng

Could be wrong, but the code may not work on NT or XP, or on Shared Network Printers.
Pasted everything where you said. Put my name of the script library in quotes, but when I click the button, nothing happens. I tried debugging, no errors. Tried moving the click script to intialize, still nothing. Ideas?
Ok, works in XP local printer.. sorry, can't test on network printer.

Name your script library "PrintUtilities"

Open your form and create a new action.


In the OPTIONS section add:
Use "PrintUtilities"

In the Declarations put:
Declare Function GetProfileString Lib "Kernel32" Alias "GetProfileStringA" (Byval lpAppName As String, Byval lpKeyName As String, _
Byval lpDefault As String, Byval lpReturnedString As String, Byval nSize As Long) As Long

In the CLICK event put:
Dim result As Variant
      Dim printerName As String
      Dim nPos As String
      
     'Get the printer name
      printerName = String(128, 0)
      result = GetProfileString("WINDOWS", "DEVICE", "", printerName, 127)
      nPos = Instr(printerName, ",")
      printerName = Left(printerName, nPos - 1)
                 'Set the default printer to landscape (printer name, landscape orientation)
      result = SetPrinterOrientation(printerName, 2)
      'Last chance to quit before printing
      Dim answer As Integer
      answer = Msgbox ("Last chance to quit.  Yes to Continue or No to Exit",36,"Continue with printing?")
      If answer <>6 Then Exit Sub

                 'Here call print or do other stuff you need before printing << Marko said you needed to add stuff
      'So I added a print call for the currently open document.  This will not work in a view action.
      Dim ws As New NotesUIWorkspace
      Dim uidoc As Notesuidocument
      Set uidoc = ws.currentdocument
      uidoc.Print
Well, now it calls up the print dialog, and I still have to set landscape manually.
this is the uidoc.print properties (available in the Notes Developer Help.)

Without parameters, then the print dialog will display.

With parameters, then it will just print:

Call notesUIDocument.Print( [ numCopies%, [, fromPage%, [, toPage%, [,draft ]]]] )

So,

call uidoc.print(1) << will print without displaying the dialog box.
Ok, it is printing now without dialog box. But it still prints whatever the last mode was set to.  If the last mode was portrait it stays with portrait, if it was landscape it prints in landscape. So, for some reason it is not changing the orientation.
schmad01,
you can try executing the code I first posted to figure out is it working on your system.

Create an action and paste the code in it.
Then turn on debugger (optional, to see the code execution line by line), preview the form in Notes client and click on your action.
After that go to default printer settings and see if it was changed by the action's code.

Hope this helps,
Marko
Ok, found out that it is not even calling the script from the script library.
Debugger is great, isn't it :)
Yeah, if would only tell me how to fix the situation.
schmad01,
where does it break? Which error?


Marko
It doesn't pause anywhere , the debug screen pops when I open the form, then when I click continue, it just goes to printing.
schmad01,
don't click on Continue, use Step into.
The code I posted doesn't print.
If you're using your code with print - comment (put ' in the begining - it turns green) that line until you solve the problem (to avoid wasting the paper).

In the lower window you can see the state of your variables. By examining vars and using Step Into (Step Over doesn't go into the function) you can figure it out.

Marko
Ok, will try.
Also, just so you know, the only way I could get the orientation to change was on a local printer using windows XP.  When last I tested, the code doesn't work in 2000 because Notes caches the printer settings.   To see if this is the case, then run the first part without sending anything to a printer, exit and reopen notes and then print something..

To stop the debugger in places, write STOP in the code.  That is the same as double-clicking and putting a breakpoint on a line.
schmad01,

These are MS comments for the code (in bas module of downloadable exe (unzip, unrar it) from this link: http://support.microsoft.com/default.aspx?scid=kb;EN-US;q198901)

For use on NT:
'  When adding a printer icon to the printer folder (when you double-
'  click on "Add Printer"), it is important to choose to save printer
'  settings on "My Computer" rather than on "Network Printer Server".
'  If "Network Printer Server" is used, then SetPrinter will fail
'  unless the user has privileges on the network printer server to
'  change the network server's global settings - in which case ALL
'  users of that printer are affected.  Whereas, when "My Computer"
'  is selected, the user only needs privileges on the local NT machine
'  and no one else is affected.

'HP LaserJet 5si
'  As of 3/2/98,  The HP LaserJet 5si printer driver does not work
'  properly with the SetPrinter API call.  After using this code,
'  the 5si properties in the Printer folder are unaffected.
'  3/2/98  --  The current workaround is to use the HP 4si driver.


Marko
If you have problems with the code:
    http://support.microsoft.com/download/support/mslfiles/PageSet.exe
The exe (self extracting archive) file contains Readme.txt which explains how to use dll to change printer orientation.

Marko
Ok, that's not working, still but it sparked an idea. All I did was set up a new printer in Windows(same physical printer as my default printer) and changed the printer settings to landscape. Just to verify, I printed the form to my default printer and it printed in portrait. I printed the form to the newly created printer and it printed in landscape. Great!

Now, how can I program a button to always print this form to that specific printer? I do not want to set that printer as my default obviously because I don't want to print everything in landscape.  Any ideas?
ASKER CERTIFIED SOLUTION
Avatar of marilyng
marilyng

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That'll do the trick.  Thanks, MarilynG,  thanks everyone!
You know.. and I haven't tried this, what happens if you configure multiple instances of your network printer.. i.e. networkLANDSCAPE, networkLEGAL, with different default printer specifications,  and just call those printers?

Or is that what you're doing?  Cool!  glad it worked.
Yes, that is exactly what I am doing. What do you think?
Clever!!  Good for you!  Fast, quick solution.  And you can roll out the printers to all users...