?
Solved

Printing in Landscape

Posted on 2006-04-13
27
Medium Priority
?
656 Views
Last Modified: 2013-12-18
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.
0
Comment
Question by:schmad01
  • 11
  • 9
  • 7
27 Comments
 
LVL 22

Expert Comment

by:mbonaci
ID: 16445844
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:
http://www.experts-exchange.com/Applications/Email/Lotus_Notes_Domino/Q_21235390.html


Hope this helps,
Marko
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16445869
schmad01,
I forgot:
in Globals - Options of form/view where the action is place this:

    Use "TheNameOfScriptLibraryYouCreatedInDoubleQuotes"


Marko
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16445901
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:schmad01
ID: 16446439
Ok, will try this afternoon.
0
 
LVL 18

Expert Comment

by:marilyng
ID: 16447337
Could be wrong, but the code may not work on NT or XP, or on Shared Network Printers.
0
 

Author Comment

by:schmad01
ID: 16448091
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?
0
 
LVL 18

Expert Comment

by:marilyng
ID: 16451029
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
0
 

Author Comment

by:schmad01
ID: 16471706
Well, now it calls up the print dialog, and I still have to set landscape manually.
0
 
LVL 18

Expert Comment

by:marilyng
ID: 16472959
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.
0
 

Author Comment

by:schmad01
ID: 16497578
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.
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16497625
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
0
 

Author Comment

by:schmad01
ID: 16497678
Ok, found out that it is not even calling the script from the script library.
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16497703
Debugger is great, isn't it :)
0
 

Author Comment

by:schmad01
ID: 16497806
Yeah, if would only tell me how to fix the situation.
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16497890
schmad01,
where does it break? Which error?


Marko
0
 

Author Comment

by:schmad01
ID: 16498207
It doesn't pause anywhere , the debug screen pops when I open the form, then when I click continue, it just goes to printing.
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16498324
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
0
 

Author Comment

by:schmad01
ID: 16498357
Ok, will try.
0
 
LVL 18

Expert Comment

by:marilyng
ID: 16503754
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.
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16505399
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
0
 
LVL 22

Expert Comment

by:mbonaci
ID: 16505464
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
0
 

Author Comment

by:schmad01
ID: 16510932
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?
0
 
LVL 18

Accepted Solution

by:
marilyng earned 2000 total points
ID: 16512706
yup, like I said, it usually doesn't work on network printers...  this will ask you for the new default printer.  Barebones, windows scripting, so will only work on W2k and XP.  Usually what I do is collect the default printer and save the value, change to the new printer, and then after I'm done printing, change back to the default.  I usually use this for PDF processing.

Option Public
Option Declare

Const SW_MINIMIZE = 11
' constants
Const HWND_BROADCAST = &HFFFF&
Const WM_WININICHANGE = &H1A

Declare Sub Sleepx Lib "kernel32.dll" Alias "Sleep" (Byval milliseconds As Long)
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (Byval hwnd As Long, Byval wMsg As Long, _
Byval wParam As Long, lparam As Long) As Long
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
Declare Function WriteProfileString Lib "kernel32" Alias "WriteProfileStringA" (Byval lpszSection As String, _
Byval lpszKeyName As String, Byval lpszString As String) As Long
Declare Function GetLastError Lib "kernel32" () As Long

Const PRINTER_ATTRIBUTE_DEFAULT = 4
Dim p_strBuffer As String * 254
Dim p_iRetValue As Long

Dim p_printerNames As Variant
Dim p_prnCount As Long
Dim pCount  As Long

'//has any locally installed printers

      '//Get Printer Information and Path
Dim SelectedPrinter As String, response As Integer      
Sub Initialize
      '//Get the Default Printer
      Dim ws As New notesuiWorkspace
      Dim defaultprinter As String
      If Not hasinstalledPrinter Then
            Msgbox "Sorry, you need to have an installed printer to run this agent"
            Exit Sub
      End If
      defaultprinter = getDefaultPrinter      
      Select Case defaultprinter
      Case Is<>""
            Msgbox "This is your default printer, so you might want to save this to an environment " + Chr(13) + _
            "value so you can change it back: " + _
            defaultprinter,,"Results"
      Case Else
            Msgbox "You have no default printer"
      End Select
      
      Dim response As String
      response = ws.Prompt(PROMPT_OKCANCELLIST, "Select Printer", "Select a printer to use", _
      defaultprinter, p_printerNames)
      If response <> defaultprinter Then
            'set the default printer here
            Dim result As Boolean
            result = setdefaultprinter(response)
            Select Case result
            Case True
                  Msgbox "The Default Printer is set to: " + response
            Case Else
                  Msgbox "Sorry, couldn't set default printer"
            End Select
      End If
End Sub
Function GetDefaultPrinter() As String
      GetDefaultPrinter=""
      On Error Resume Next
          ' Retrieve current default printer information
      p_iRetValue = GetProfileString("windows", "device", ",,,", p_strBuffer, 254)
      GetDefaultPrinter = Left(p_strBuffer, Instr(p_strBuffer, ",") - 1)                              
End Function
Function hasInstalledPrinter() As Integer
            'Checks for installed printers and builds a list of printers
      hasinstalledPrinter = False            
      Dim n As Integer, x As Integer
      Dim p_WshNetwork As Variant, p_wshPrinters As Variant
      Set p_WshNetwork = CreateObject("WScript.Network")
      Set p_WshPrinters = p_WshNetwork.EnumPrinterConnections()
      x = 0
      Redim p_PrinterNames(x)
            'Count the connected printers
      For n = 1 To p_WshPrinters.Count() Step 2
            If p_wshPrinters(n) <> "" Then
                  p_PrinterNames(x)=p_wshPrinters(n)
                  x = x+1
                  Redim Preserve p_PrinterNames(x)
                  p_prnCount=x
            End If
      Next
      If p_prnCount = 0 Then
                 'the user has no printers
            hasinstalledPrinter = False                  
      Else
            hasinstalledPrinter= True
            If x-1>=0 Then
                  If p_PrinterNames(x)="" Then
                        Redim Preserve p_PrinterNames(x-1)
                  End If
            End If      
      End If
      If Not p_wshNetwork Is Nothing Then Set p_wshNetwork = Nothing
      
End Function
Function SetDefaultPrinter(thisPrinterName) As Integer
      'For Windows 2000 & XP only does not work on earlier versions
      SetDefaultPrinter = False
      Dim lResult As Long
      If thisPrinterName = "" Then Exit Function      
      Dim WshNetwork As Variant, r As Long      
      Set WshNetwork =CreateObject("WScript.Network")
      r = WshNetwork.SetDefaultPrinter(thisPrinterName)
      If r<>0 Then
            Msgbox "Set Default Printer Command Failed. Error code: " + Cstr(GetLastError()), 16,"Unable to set the Default Printer"
            Exit Function
      End If
      lResult = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, 0)
      Call Sleepx(2000)
      SetDefaultPrinter = True
      Set wshNetwork = Nothing
      
End Function

0
 

Author Comment

by:schmad01
ID: 16534931
That'll do the trick.  Thanks, MarilynG,  thanks everyone!
0
 
LVL 18

Expert Comment

by:marilyng
ID: 16535067
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.
0
 

Author Comment

by:schmad01
ID: 16535215
Yes, that is exactly what I am doing. What do you think?
0
 
LVL 18

Expert Comment

by:marilyng
ID: 16535334
Clever!!  Good for you!  Fast, quick solution.  And you can roll out the printers to all users...
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I thought it will be a good idea to make a post as it will help in case someone else faces these issues. I trust this gives an idea how each entry in Notes.ini can mean a lot for the Domino Server to be functioning properly. This article discusses t…
Lack of Storage capacity is a common problem that exists in every field of life. Here we are taking the case of Lotus Notes Emails, as we all know that we are totally depend on e-communication i.e. Emails. This article is fully dedicated to resolvin…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Suggested Courses
Course of the Month16 days, 11 hours left to enroll

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question