Solved

Printing a word object - chainging printer

Posted on 2000-04-26
14
233 Views
Last Modified: 2010-05-02
Hi
I'm programmatically writing text into Word using a word object "CreateObject("Word.Application")".
I then print this document using ".ActiveDocument.PrintOut".I want to be able to change the default printer before printing. I want to avoid using the printer common dialogue.
I want to display a simple list of installed printers to the user. How do I do this ?
On selecting one, that should be made the default so that the word document gets printed to the specified printer. How do I go about this ?
Also is there a way to list paper types / printer trays so that the printer uses specified paper type or the specified tray ?
Code samples would be great. I use VB6.0.


Currently I am listing printers using
Private Sub Form_Load()
    text1 = Printer.DeviceName
    text2 = Printer.Port
    Dim X As Printer
    For Each X In Printers
        List1.AddItem X.DeviceName
    Next
End Sub

To change current printer can I use this ?
Private Sub Command1_Click()
    Set Printer = Printers(List1.ListIndex)
End Sub

But after this how do I ensure .ActiveDocument.PrintOut prints to the selected printer ?
I dont mind changing the default printer temporarily ...

0
Comment
Question by:tellis_george
  • 9
  • 5
14 Comments
 
LVL 28

Expert Comment

by:AzraSound
ID: 2753951
to select printer you can use the OpenPrinter API

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

Public Type PRINTER_DEFAULTS
        pDatatype As String
        pDevMode As DEVMODE
        DesiredAccess As Long
End Type


printername is name of the printer obviously.  if the function fails it will return zero, as most api functions do.  phPrinter is a variable you pass that will receive the printer handle.

see msdn about the printer_defaults data type and the devmode data type


0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2753962
actually you should be able to just set it the way you stated above. have you tried it out yet?
0
 

Expert Comment

by:tellis070898
ID: 2753982
I brought up the common dialogue box within the same form after I executed Set Printer = Printers(List1.ListIndex) just to check up ...
but the default printer in the common dialogue is still the old one ...
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2753990
i think using that method will just change the printer that will be used currently at that point, but doesnt actually alter the default printer.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2753994
http://support.microsoft.com/support/kb/articles/Q167/7/35.ASP

this used to be a problem until vb 5.0 sp2
see this article for details
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2754004
oh i think i see the issue now, i dont think the activedocument will recognize the current printer object that you specify.  you can always use the shell command or shellexecute commands to print as well.
0
 

Expert Comment

by:tellis070898
ID: 2754048
BTW. I am using Win 2000 Professional.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 28

Expert Comment

by:AzraSound
ID: 2754256
if youre interested this code will change the default printer on win2000.  you can set it back as needed when youre done printing your document:



****MODULE CODE******

Public Const HWND_BROADCAST As Long = &HFFFF
Public Const WM_WININICHANGE As Long = &H1A

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 SendMessage Lib "user32" _
   Alias "SendMessageA" _
  (ByVal hwnd As Long, _
   ByVal wMsg As Long, _
   ByVal wParam As Long, _
   lparam As Any) As Long



******FORM CODE******

Create a form containing a listbox and command button , using the default names. Add the following code to the form:

--------------------------------------------------------------------------------
 

Option Explicit

Private Sub Form_Load()
   
    ProfileLoadWinIniList List1, "PrinterPorts"
    Command1.Enabled = False
   
End Sub


Private Sub Command1_Click()

   Call SetDefaultPrinterWinNT

End Sub


Private Sub List1_Click()

   Command1.Enabled = List1.ListIndex > -1
   
End Sub


Private Sub SetDefaultPrinter(ByVal PrinterName As String, _
                              ByVal DriverName As String, _
                              ByVal PrinterPort As String)
   Dim DeviceLine As String
   
  'rebuild a valid device line string
   DeviceLine = PrinterName & "," & DriverName & "," & PrinterPort
   
  'Store the new printer information in the
  '[WINDOWS] section of the WIN.INI file for
  'the DEVICE= item
   Call WriteProfileString("windows", "Device", DeviceLine)
   
  'Cause all applications to reload the INI file
   Call SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, ByVal "windows")
   
End Sub

Private Sub GetDriverAndPort(ByVal Buffer As String, DriverName As String, PrinterPort As String)

   Dim posDriver As Long
   Dim posPort As Long
   DriverName = ""
   PrinterPort = ""

  'The driver name is first in the string
  'terminated by a comma
   posDriver = InStr(Buffer, ",")
   
   If posDriver > 0 Then

     'Strip out the driver name
      DriverName = Left(Buffer, posDriver - 1)

     'The port name is the second entry after
     'the driver name separated by commas.
      posPort = InStr(posDriver + 1, Buffer, ",")

      If posPort > 0 Then
     
        'Strip out the port name
         PrinterPort = Mid(Buffer, posDriver + 1, posPort - posDriver - 1)
         
       End If
   End If
   
End Sub


Public Function ProfileLoadWinIniList(lst As ListBox, lpSectionName As String) As Long

'Load the listbox data from win.ini.

   Dim success As Long
   Dim nSize As Long
   Dim lpKeyName As String
   Dim ret As String
 
  'call the API passing null as the parameter
  'for the lpKeyName parameter. This causes
  'the API to return a list of all keys under
  'that section. Pad the passed string large
  'enough to hold the data. Adjust to suit.
   ret = Space$(8102)
   nSize = Len(ret)
   success = GetProfileString(lpSectionName, vbNullString, "", ret, nSize)
   
  'The returned string is a null-separated
  'list terminated by a pair of null characters.
   If success Then
   
     'trim terminating null and trailing spaces
      ret = Left$(ret, success)
     
        'with the resulting string,
        'extract each element
         Do Until ret = ""
     
           'strip off an item and
           'add the item to the listbox
            lpKeyName = StripNulls(ret)
            lst.AddItem lpKeyName
     
         Loop
 
   End If
 
  'return the number of items as an
  'indicator of success
   ProfileLoadWinIniList = lst.ListCount

End Function


Private Function StripNulls(startstr As String) As String

 'Take a string separated by chr$(0)
 'and split off 1 item, shortening the
 'string so next item is ready for removal.
  Dim pos As Long

  pos = InStr(startstr$, Chr$(0))
 
  If pos Then
     
      StripNulls = Mid$(startstr, 1, pos - 1)
      startstr = Mid$(startstr, pos + 1, Len(startstr))
   
  End If

End Function


Private Sub SetDefaultPrinterWinNT()

   Dim Buffer As String
   Dim DeviceName As String
   Dim DriverName As String
   Dim PrinterPort As String
   Dim PrinterName As String
   Dim r As Long
   
   If List1.ListIndex > -1 Then
       
     'Get the printer information for the currently selected
     'printer in the list. The information is taken from the
     'WIN.INI file.
      Buffer = Space(1024)
      PrinterName = List1.Text
     
      Call GetProfileString("PrinterPorts", _
                             PrinterName, "", _
                             Buffer, Len(Buffer))
 
     'Parse the driver name and port name out of the buffer
      GetDriverAndPort Buffer, DriverName, PrinterPort

      If DriverName <> "" And PrinterPort <> "" Then
         SetDefaultPrinter List1.Text, DriverName, PrinterPort
      End If
       
    End If
   
End Sub

0
 

Expert Comment

by:tellis070898
ID: 2754285
hi I've got it ...
word has an activeprinter property so i just say
Set Printer = Printers(List1.ListIndex)
application.activeprinter = printer.devicename ...
It works fine .....


0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2754288
i assumed there had to be some property such as that one, just didnt know what it was.  congrats!
0
 

Expert Comment

by:tellis070898
ID: 2764930
Hi azrasound,  thanks for the code sections .. I could use it sometime ... could you post a reply as an answer .. I can give you the points then ...
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2764934
you make it hard for me to post an answer when you yourself posted an answer  =)
0
 

Expert Comment

by:tellis070898
ID: 2764938
tellis changed the proposed answer to a comment
0
 
LVL 28

Accepted Solution

by:
AzraSound earned 50 total points
ID: 2764942
posting comment as answer
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

743 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now