Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    New Lounger
    Join Date
    Oct 2001
    Location
    Essex, UK
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Finding printers (Word 2000)

    Hi, apologising in advance if this has a simple answer ... Is there a way for me to get a list of all the printers I could print to - I'd like to write a macro to select a printer from a drop-down list on a toolbar as I change networks/printers a lot, however I've fallen at the first hurdle!

    Thanks,

    Stephan

  2. #2
    Silver Lounger
    Join Date
    Mar 2001
    Location
    Springfield, Ohio, USA
    Posts
    2,136
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Finding printers (Word 2000)

    It should be simple: VBA should have a Printers collection like VB, but it doesn't. Instead you have to use an API call to EnumPrinters. http://www.allapi.net/. Even though it is a VB project, it looks like you can change the name of Private Sub Form_Load() to Private Sub Macro1() and just copy all of the code into a macro module. If you can post your final code back here, I know others will appreciate it. --Sam
    <font face="Comic Sans MS">Sam Barrett, CACI </font face=comic>
    <small>And the things that you have heard... commit these to faithful men who will be able to teach others also. 2 Timothy 2:2</small>

  3. #3
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: Finding printers (Word 2000)

    Not sure if <A target="_blank" HREF=http://www.wopr.com/cgi-bin/w3t/showflat.pl?Cat=&Board=vb&Number=59514>this earlier thread</A> is any help, but it includes a macro for getting additional information about the printers the user has set up.

  4. #4
    Gold Lounger
    Join Date
    Dec 2000
    Location
    Hollywood (sorta), California, USA
    Posts
    2,759
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    I've been trying to get SHBrowseForFolder API function to
    work for displaying and selecting a printer. I can get the list of
    printers, but the Ok button stays grayed out after clicking a
    printer in the list.

    Jeff's reference (and code) is pretty good. But you've still got
    to write the UI after getting the printers from the registry.

    Sam's idea to use Enumprinters API call is good too, but if
    SHBrowseForFolder works, then the UI is a done deal.

    The code's a bit embarrassing right now, but if it helps try it:

    <pre>Function GetFileFolderOrPrinterList(Optional strType$) As
    String
    Dim hWnd As Long
    Dim bInfo As BROWSEINFO
    Dim path As String
    Dim r As Long, x As Long, pos As Integer
    Dim IDL As ITEMIDLIST
    Const BIF_RETURNONLYFSDIRS = &H1
    Const BIF_BROWSEFORPRINTER = &H2000
    Const BIF_NEWDIALOGSTYLE = &H40
    Const BIF_EDITBOX = &H10
    Const BIF_STATUSTEXT = &H4
    Const CSIDL_PRINTERS = &H4
    Const CSIDL_PRINTHOOD = &H1B

    path = String$(260, 0)

    'Call OleInitialize(ByVal 0&)

    bInfo.hOwner = GetActiveWindow 'Get the window handle for the calling form
    hWnd = GetActiveWindow
    If strType = "Printers" Then
    r = SHGetSpecialFolderLocation(hWnd, CSIDL_PRINTERS, IDL)
    bInfo.pidlRoot = IDL.mkid.cb
    bInfo.ulFlags = BIF_BROWSEFORPRINTER Or BIF_EDITBOX
    bInfo.lpszTitle = "Select one of your installed printers:"
    Else
    bInfo.pidlRoot = 0& ' Root folder = Desktop
    bInfo.ulFlags = BIF_RETURNONLYFSDIRS 'Or BIF_NEWDIALOGSTYLE
    bInfo.lpszTitle = "Select a Folder:"
    End If

    x = SHBrowseForFolder(bInfo) ' Display the dialog
    r = SHGetPathFromIDList(ByVal x, ByVal path)

    'Call OleUninitialize
    If r Then
    pos = InStr(path, Chr$(0))
    GetFileFolderOrPrinterList = Left(path, pos - 1)
    Else
    GetFileFolderOrPrinterList = ""
    End If


    End Function
    </pre>

    Kevin <IMG SRC=http://www.wopr.com/w3tuserpics/Kevin_sig.gif alt="Keep the change, ya filthy animal...">
    <img src=/w3timages/blackline.gif width=33% height=2><img src=/w3timages/redline.gif width=33% height=2><img src=/w3timages/blackline.gif width=33% height=2>

  5. #5
    Gold Lounger
    Join Date
    Dec 2000
    Location
    Hollywood (sorta), California, USA
    Posts
    2,759
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    I put together Enumprinters and SHBrowseForFolder examples from wisdom gleaned from VBNet: <A target="_blank" HREF=http://www.mvps.org/vbnet/index.html?code/browse/browseadv.htm>http://www.mvps.org/vbnet/index.html?code/...e/browseadv.htm</A>

    The instructional material at this site is excellent.

    If anyone is interested, I'd be glad to post.
    Kevin <IMG SRC=http://www.wopr.com/w3tuserpics/Kevin_sig.gif alt="Keep the change, ya filthy animal...">
    <img src=/w3timages/blackline.gif width=33% height=2><img src=/w3timages/redline.gif width=33% height=2><img src=/w3timages/blackline.gif width=33% height=2>

  6. #6
    Silver Lounger
    Join Date
    Mar 2001
    Location
    Springfield, Ohio, USA
    Posts
    2,136
    Thanks
    0
    Thanked 1 Time in 1 Post

    Re: Finding printers (Word 2000)

    Please! <img src=/S/grovel.gif border=0 alt=grovel width=31 height=23>
    <font face="Comic Sans MS">Sam Barrett, CACI </font face=comic>
    <small>And the things that you have heard... commit these to faithful men who will be able to teach others also. 2 Timothy 2:2</small>

  7. #7
    Gold Lounger
    Join Date
    Dec 2000
    Location
    Hollywood (sorta), California, USA
    Posts
    2,759
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Sam,

    It's not a finished work, but it should be far enough along to work with. If you have any questions post back.

    The form calls EnumPrintersWinNT to get the list. I like the enum solution better because the BrowseFor API only returns the "Display Name" of the printer which excludes the server name. I had a hard time getting the SHBrowseForFolder to work because it failed to sink in that you cannot get the actual path to a virtual folder -- which is what the Printers folder is.
    Attached Files Attached Files
    Kevin <IMG SRC=http://www.wopr.com/w3tuserpics/Kevin_sig.gif alt="Keep the change, ya filthy animal...">
    <img src=/w3timages/blackline.gif width=33% height=2><img src=/w3timages/redline.gif width=33% height=2><img src=/w3timages/blackline.gif width=33% height=2>

  8. #8
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: Finding printers (Word 2000)

    One way to get to special folders:

    Dim oShell As Object, strPrinterFolder As String
    Set oShell = CreateObject("WScript.Shell")
    strPrinterFolder = oShell.SpecialFolders("PrintHood")
    Set oShell = Nothing

    I don't know what version of Windows Script Host is required.

    But... this folder is empty! (Using Win2000)

  9. #9
    Gold Lounger
    Join Date
    Dec 2000
    Location
    Hollywood (sorta), California, USA
    Posts
    2,759
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Jeff,

    "PrintHood", of course, is very different from "Printers". But your point about using scripting host is a good one.
    Kevin <IMG SRC=http://www.wopr.com/w3tuserpics/Kevin_sig.gif alt="Keep the change, ya filthy animal...">
    <img src=/w3timages/blackline.gif width=33% height=2><img src=/w3timages/redline.gif width=33% height=2><img src=/w3timages/blackline.gif width=33% height=2>

  10. #10
    New Lounger
    Join Date
    Oct 2001
    Location
    Essex, UK
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Thank you for everyone's reply, there's nothing like a steep learning curve. Below I've pasted what I've got so far - macros to add a drop down box to the standard command bar, to deal with selecting a different printer and to remove the drop down box from the command bar. It works, but there are a couple of problems:

    <UL><LI>If you select a network printer when you're not connected to that network an error occurs (which is why I've put error capture in)
    <LI>If you use the printer dialogue and change the printer, the dropdown box isn't updated
    <LI>Is this a good way of doing it?[/list]Look forward to your comments

    Stephan

    <font face="Georgia"> <small>Private Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
    Private Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As Long) As Long
    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
    Const PRINTER_ENUM_LOCAL = &H2

    Private Sub SetPrinter()
    Dim Msg
    On Error GoTo ErrorHandler
    Set PrinterDropDown = CommandBars.FindControl(Tag:="Select printer")
    ActivePrinter = PrinterDropDown.Text
    On Error GoTo 0
    Exit Sub
    ErrorHandler:
    Msg = "Error # " & Str(Err.Number) & " was generated by " _
    & Err.Source & Chr(13) & Err.Description
    MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
    End Sub

    Sub AddPrinterDropDown()
    'Code based on example from:
    'KPD-Team 1999
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim longbuffer() As Long 'resizable array receives information from the function
    Dim pName As String
    Dim numbytes As Long 'size in bytes of longbuffer()
    Dim numneeded As Long 'receives number of bytes necessary if longbuffer() is too small
    Dim numprinters As Long 'receives number of printers found
    Dim c As Integer, retval As Long ' counter variable & return value

    'Get information about the local printers
    numbytes = 3076 ' should be sufficiently big, but it may not be
    ReDim longbuffer(0 To numbytes / 4) As Long ' resize array -- note how 1 Long = 4 bytes
    retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 1, longbuffer(0), numbytes, numneeded, numprinters)
    If retval = 0 Then ' try enlarging longbuffer() to receive all necessary information
    numbytes = numneeded
    ReDim longbuffer(0 To numbytes / 4) As Long ' make it large enough
    retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 1, longbuffer(0), numbytes, numneeded, numprinters)
    If retval = 0 Then ' failed again!
    Debug.Print "Could not successfully enumerate the printers."
    End ' abort program
    End If
    End If

    Set PrinterDropDown = CommandBars("Standard").Controls.Add(Type:=msoCont rolDropdown, ID:=1, Before:=6)
    PrinterDropDown.Tag = "Select printer"
    PrinterDropDown.Width = 100
    PrinterDropDown.DropDownWidth = -1
    PrinterDropDown.OnAction = "SetPrinter"
    For c = 0 To numprinters - 1
    'For each string, the string is first buffered to provide enough room, and then the string is copied.
    pName = Space(lstrlen(longbuffer(4 * c + 2)))
    retval = lstrcpy(pName, longbuffer(4 * c + 2))
    PrinterDropDown.AddItem pName
    If ActivePrinter Like pName & "*" Then
    PrinterDropDown.ListIndex = c + 1 'Need to set as current active printer
    End If
    Next c

    End Sub

    Sub RemovePrinterDropDown()
    Set PrinterDropDown = CommandBars.FindControl(Tag:="Select printer")
    PrinterDropDown.Delete
    End Sub</font face=georgia>

  11. #11
    Gold Lounger
    Join Date
    Feb 2001
    Location
    Dublin, Ireland, Republic of
    Posts
    2,697
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Does <pre>Application.Dialogs(wdDialogFilePrintSetup).S how </pre>

    It provides a list of installed printers and allows you to select the default printer.

  12. #12
    New Lounger
    Join Date
    Oct 2001
    Location
    Essex, UK
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Andrew, it's absolutely fine, works, is one line and it never occurred to me. My thoughts of a solution were along the lines of a drop-down list to select from a command bar, which I still prefer for my use - mind you I know which solution is quickest!

    Thanks,

    Stephan

  13. #13
    Gold Lounger
    Join Date
    Dec 2000
    Location
    Hollywood (sorta), California, USA
    Posts
    2,759
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Looks to me like the code you posted enumerates only local printers. Your toolbar button Onaction prop calls SetPrinter which I don't see either.

    Did you look at the code I posted?
    Kevin <IMG SRC=http://www.wopr.com/w3tuserpics/Kevin_sig.gif alt="Keep the change, ya filthy animal...">
    <img src=/w3timages/blackline.gif width=33% height=2><img src=/w3timages/redline.gif width=33% height=2><img src=/w3timages/blackline.gif width=33% height=2>

  14. #14
    New Lounger
    Join Date
    Oct 2001
    Location
    Essex, UK
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    Kevin, the SetPrinter macro is in the code I posted, it's the first of the 3 macros. What I've written does let me select network printers I've set up. Is this something to do with the way Win 98 handles them? I do get that error if I select a printer on a network I'm not connected to as I mentioned before.

    I had a quick look at your code, excuse my ignorance, but because you call EnumPrintersWinNT I presumed it wouldn't work on Win 98 which is what is on my laptop - as I said this is a steep learning curve to me.

    Thanks

    Stephan

  15. #15
    Star Lounger
    Join Date
    Jan 2001
    Posts
    71
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Finding printers (Word 2000)

    The following works, even on NT/2000 (which don't have a win.ini file). The routine also returns network printers.

    Private Declare Function GetProfileSection Lib "kernel32" _
    Alias "GetProfileSectionA" (ByVal lpAppName As String, _
    ByVal lpReturnedString As String, ByVal nSize As Long) As Long

    Function Printers() As Collection

    On Error Resume Next
    Dim Prn As New Collection
    Dim sBuff As String, nRet As Long, i As Long
    sBuff = Space$(1000) 'String(1000, 0)
    nRet = GetProfileSection("devices", sBuff, Len(sBuff))
    If nRet Then
    Dim AllPrinters() As String, Printer() As String, Port() As String
    AllPrinters = Split(Left$(sBuff, nRet - 1), vbNullChar)
    For i = LBound(AllPrinters) To UBound(AllPrinters)
    Printer = Split(AllPrinters(i), "=")
    Port = Split(Printer(1), ",")
    Prn.Add Printer(0) & " on " & Port(0)
    Next
    End If
    Set Printers = Prn

    End Function

    Sub GetPrinters()
    Dim P As New Collection, i As Long
    Set P = Printers
    For i = 1 To P.Count
    Debug.Print P(i)
    Next
    End Sub

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •