Results 1 to 14 of 14

Thread: [RESOLVED]BROWSEINFO or common dialog?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2005
    Posts
    103

    Resolved [RESOLVED]BROWSEINFO or common dialog?

    I've inherited a set of macros, one of which allows the running of one or more macros on a batch of files. The main dialog has a browse button on it which opens up a little browse dialog to allow the user to choose the path to the folder containing the files on which to run the macro(s). The thing is, this browser window is kind of annoying as it always defaults to the my computer view (the one in this page) and the user has to click down through the tree structure to the directory (s)he wants, which is rather tedious. I'd like to replace this dialog with one which allows the user to paste a path into the text-box at the bottom of the dialog and hit OK - a more modern Windows dialog. I'm not very experienced in VB (about 5 weeks if the truth be told) and don't understand the code fully, but have narrowed it down to two possible places where I have to make the change.
    Is there much of a change needed in the following code, just the addition of a few lines, or do I need to use a completely different dialog and rewrite the code (I assume it's been done before, but attempts to find the code I need have been a bit confusing)?
    When I open the form corresponding to the main dialog of the multimacrorunner, I can see that the name of the selected folder is lbFolder, and clicking browse activates this code:
    VB Code:
    1. Private Sub btnBrowse_Click()
    2.      lblFolder.Caption = BrowseFolder
    3. End Sub

    Not much info there, but further on in the code there's the bit that corresponds to the opened folder:
    VB Code:
    1. Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
    2. Private Declare Function SHBrowseForFolder Lib "shell32.dll" ( _
    3.                 ByRef lpbi As BROWSEINFO) As Long
    4. Private Declare Function SHGetPathFromIDList Lib "shell32.dll" ( _
    5.                 pidl As Any, ByVal pszPath As String) As Long
    6.  
    7. '======= .bas wrapper for ShBrowseForFolder  =======
    8. Private Const BIF_RETURNONLYFSDIRS As Long = &H1&
    9. Private Const BIF_DONTGOBELOWDOMAIN = &H2&
    10. Private Const BIF_STATUSTEXT = &H4&
    11. Private Const BIF_RETURNFSANCESTORS = &H8&
    12. Private Const BIF_EDITBOX = &H10&
    13. Private Const BIF_VALIDATE = &H20& ' insist on valid result (or CANCEL)
    14. Private Const BIF_BROWSEFORCOMPUTER = &H1000&  ' Browsing for Computers.
    15. Private Const BIF_BROWSEFORPRINTER = &H2000&   ' Browsing for Printers
    16. Private Const BIF_BROWSEINCLUDEFILES = &H4000& ' Browsing for Everything
    17.  
    18. Private Const MAX_PATH = 260
    19.  
    20. Private Const CSIDL_DRIVES As Long = &H11&
    21.  
    22. Private Type BROWSEINFO
    23.     hwndOwner As Long ' HWND
    24.     pidlRoot As Long '* pointer to: LPCITEMIDLIST (opens at ID)
    25.     sDisplayName As String 'buffer for result
    26.     sTitle As String 'prompt string
    27.     ulFlags As Long ' UINT
    28.     lpfn As Long '* pointer to: BFFCALLBACK
    29.     lParam As Long ' LPARAM
    30.     iImage As Long ' int
    31. End Type
    32.  
    33. Private Declare Function FindWindow Lib "user32" Alias _
    34. "FindWindowA" (ByVal lpClassName As String, _
    35.           ByVal lpWindowName As Long) As Long
    36.  
    37. Public Function BrowseFolder(Optional sPrompt As String = "Select a folder..") As String
    38.     'returns "" if Cancel selected, else Path
    39.     Dim BINF As BROWSEINFO
    40.     Dim lpItem As Long
    41.     Dim sDir As String
    42.  
    43.     With BINF
    44.         .hwndOwner = FindWindow("ThunderXFrame", 0)
    45.         '.pidlRoot = 0& 'open at desktop
    46.         .pidlRoot = 0 'CSIDL_DRIVES 'skips desktop <*> changed to 0 to show network folders
    47.         .sDisplayName = Space$(MAX_PATH + 1)
    48.         .sTitle = sPrompt
    49.         .ulFlags = BIF_RETURNONLYFSDIRS
    50.         .lpfn = 0
    51.         .lParam = 0
    52.         .iImage = 0
    53.     End With
    54.     lpItem = SHBrowseForFolder(BINF)
    55.  
    56.     If lpItem Then
    57.         sDir = Space$(MAX_PATH)
    58.         If SHGetPathFromIDList(ByVal lpItem, sDir) Then
    59.             BrowseFolder = FixPath(Left(sDir, InStr(1, sDir, Chr(0)) - 1))
    60.         End If
    61.     End If
    62.  
    63.  
    64. ' The following step is most important. Neither Windows or VB will
    65. 'automatically release the memory consume by lpItem
    66.  'so its up to the programmer to it.
    67.  
    68. GlobalFree lpItem
    69.  
    70. End Function
    Last edited by pickarooney; Jun 8th, 2005 at 05:47 AM.

  2. #2
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: BROWSEINFO or common dialog?

    have a look here
    for more information and a list of the constants you can use for the start folders to browse from
    .pidlRoot = 0 'CSIDL_DRIVES 'skips desktop <*> changed to 0 to show network folders
    this line is the one that sets the starting directory
    0 is CSIDL_DESKTOP (0x0000)
    The virtual folder representing the Windows desktop, the root of the namespace.
    CSIDL_DRIVES is 11
    CSIDL_DRIVES (0x0011)
    The virtual folder representing My Computer, containing everything on the local computer: storage devices, printers, and Control Panel. The folder may also contain mapped network drives.
    pete

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Apr 2005
    Posts
    103

    Re: BROWSEINFO or common dialog?

    Cheers pete. I messed about with that, trying different values, and I now (I don't know why as as far as I can see the code is back to the way it was!) get the last-opened folder as the default, which is the value I want at least half the time.
    Now, will I be able to enable this style of dialog with the input boxes at the bottom for file and type replaced by a pth to a directory?
    I have to try rephrase that... I'd like to have a dialog like the one in the screenshot open instead of the current browser but with no option to select a file or filetype, only a directory.

  4. #4
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: BROWSEINFO or common dialog?

    i have used the common dialog box like that to select a folder only by setting the filetitle to "Select folder to save to", before showning the dialog

    the path you want to save to then is

    left(filename,len(filename) - len(filetitle))

    even if they do select a file name in the dialog it doesn't matter, as long as they select it in the right folder.

    pete

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Apr 2005
    Posts
    103

    Re: BROWSEINFO or common dialog?

    OK, sounds good. How to display the common dialog then?

    I tried this

    VB Code:
    1. Dim dlgFileOpen As New Dialog
    2.        
    3.     dlgFileOpen.Display

    but it's not right

  6. #6
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171

    Re: BROWSEINFO or common dialog?

    You need to add the Microsoft Common Dialog Control component (Project -> Components) to your form. Then you can use :

    VB Code:
    1. CommonDialog1.ShowOpen


    Has someone helped you? Then you can Rate their helpful post.

  7. #7
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: BROWSEINFO or common dialog?

    If I understand you correctly you want to set an initial path for the BrowseForFolder dialog box. To be able to do that you need to create a callback function for the BrowseForFolder dialog box to call. You then have to check for the BFFM_INITIALIZED message and set the initial path you want to have selected when the dialog appears on screen.

    Copy the below code to a regular BAS module (that's the only place a callback function can exist in).
    VB Code:
    1. Private Declare Function SendMessageString _
    2.  Lib "user32" Alias "SendMessageA" ( _
    3.  ByVal hWnd As Long, _
    4.  ByVal wMsg As Long, _
    5.  ByVal wParam As Long, _
    6.  ByVal lParam As String) As Long
    7.  
    8. Private Const WM_USER = &H400
    9. Private Const BFFM_SETSELECTIONA = (WM_USER + 102)
    10. Private Const BFFM_INITIALIZED = 1
    11. Private m_thePath As String
    12.  
    13. Public Property Let Path(ByVal sNewVal As String)
    14.     m_thePath = sNewVal
    15. End Property
    16.  
    17. 'This function will be our callback function
    18. Public Function ShowFolderCallback( _
    19.  ByVal hWnd As Long, _
    20.  ByVal uMsg As Long, _
    21.  ByVal lParam As Long, _
    22.  ByVal lpData As Long) As Long
    23.    
    24.     If uMsg = BFFM_INITIALIZED Then
    25.         If Len(m_Path) > 0 Then
    26.             SendMessageString hWnd, BFFM_SETSELECTIONA, 1&, m_thePath
    27.         End If
    28.     End If
    29.     ShowFolderCallback = 0
    30. End Function
    Now let's say you've named this module FolderCallback you need to set the following code in your existing BrowseForFolder code.
    VB Code:
    1. With BINF
    2.    [b] FolderCallback.Path [/b]= [i]sThePathYouWantToUse[/i]
    3.    [b] .lpfn [/b]= ReturnParam(AddressOf FolderCallback.ShowFolderCallback)
    4.     'set other BROWSEINFO members here
    5. End With
    6. '... call the SHBrowseForFolder function here...
    7. '... and the rest of the code to determent the selected folder
    As you can see above I make a call to a ReturnParam function, this is just a dummy function that returns the AddressOf the function. It looks like this:
    VB Code:
    1. Private Function ReturnParam(ByVal nParam As Long) As Long
    2.     'This function is a dummy function that only returns
    3.     'the argument passed to it.
    4.     ReturnParam = nParam
    5. End Function
    You need this function simply because you can't assign the AddressOf ShowFolderCallback directly to the structure member.
    Last edited by Joacim Andersson; Jun 7th, 2005 at 04:25 PM.

  8. #8

    Thread Starter
    Lively Member
    Join Date
    Apr 2005
    Posts
    103

    Re: BROWSEINFO or common dialog?

    Thanks for all the answers, but I'm in way over my head. I did a terrible job of trying to explain what I wanted, partially because I wasn't sure what I wanted. I'm going to read through the code in these replies and try and understand it, as it's bound to be useful to know.
    This is going to sound stupid now, but I think what I want to do is simply replace the entire BrowseFolder function with something that simply opens a common dialog and returns a path to a directory.

    Also, I plan to completely rewrite the multimacrorunner macro some day, as I think it's needlessly complicated for something that simply runs a selection of macros on a selection of files (hear the sound of an idiot underestimating work!)

  9. #9
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: BROWSEINFO or common dialog?

    add a project component to commondialog, then

    commondialog.showopen or commondialog1.showsave

    the folder path is the filename less the filetitle (see my previous reply)

    pete

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Apr 2005
    Posts
    103

    Re: BROWSEINFO or common dialog?

    I don't understand. I have no Project menu in my VB IDE, and don't know how I can add a component.

  11. #11
    Banned dglienna's Avatar
    Join Date
    Jun 2004
    Location
    Center of it all
    Posts
    17,901

    Re: BROWSEINFO or common dialog?

    Press Control-T to bring up the Components screen. You can also call if from the Projects menu.

  12. #12
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: BROWSEINFO or common dialog?

    I think I misunderstood your request in my earlier reply since I thought you wanted to be able to set an initial directory when the BrowseForFolder dialog box opened. But after reading it again I suspect what you're after is the dialog shown in the attached image.

    That's easily fixed with the code you had. You only need to add on flag constant, marked as red in the code. You already had the flag constant for the edit box declared but you didn't use it so I added that to and marked it yellow below. Besides these changes the code is the same as you posted it. So there is no need to show an Open File dialog box when you want the user to select a folder.
    VB Code:
    1. Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
    2. Private Declare Function SHBrowseForFolder Lib "shell32.dll" ( _
    3.                 ByRef lpbi As BROWSEINFO) As Long
    4. Private Declare Function SHGetPathFromIDList Lib "shell32.dll" ( _
    5.                 pidl As Any, ByVal pszPath As String) As Long
    6.  
    7. '======= .bas wrapper for ShBrowseForFolder  =======
    8. Private Const BIF_RETURNONLYFSDIRS As Long = &H1&
    9. Private Const BIF_DONTGOBELOWDOMAIN = &H2&
    10. Private Const BIF_STATUSTEXT = &H4&
    11. Private Const BIF_RETURNFSANCESTORS = &H8&
    12. Private Const [color="#CECE00"][b]BIF_EDITBOX[/b][/color] = &H10&
    13. Private Const BIF_VALIDATE = &H20& ' insist on valid result (or CANCEL)
    14. Private Const BIF_BROWSEFORCOMPUTER = &H1000&  ' Browsing for Computers.
    15. Private Const BIF_BROWSEFORPRINTER = &H2000&   ' Browsing for Printers
    16. Private Const BIF_BROWSEINCLUDEFILES = &H4000& ' Browsing for Everything
    17. Private Const [color=red][b]BIF_USENEWUI = &H40[/b][/color]
    18.  
    19. Private Const MAX_PATH = 260
    20.  
    21. Private Const CSIDL_DRIVES As Long = &H11&
    22.  
    23. Private Type BROWSEINFO
    24.     hwndOwner As Long ' HWND
    25.     pidlRoot As Long '* pointer to: LPCITEMIDLIST (opens at ID)
    26.     sDisplayName As String 'buffer for result
    27.     sTitle As String 'prompt string
    28.     ulFlags As Long ' UINT
    29.     lpfn As Long '* pointer to: BFFCALLBACK
    30.     lParam As Long ' LPARAM
    31.     iImage As Long ' int
    32. End Type
    33.  
    34. Private Declare Function FindWindow Lib "user32" Alias _
    35. "FindWindowA" (ByVal lpClassName As String, _
    36.           ByVal lpWindowName As Long) As Long
    37.  
    38. Public Function BrowseFolder(Optional sPrompt As String = "Select a folder..") As String
    39.     'returns "" if Cancel selected, else Path
    40.     Dim BINF As BROWSEINFO
    41.     Dim lpItem As Long
    42.     Dim sDir As String
    43.  
    44.     With BINF
    45.         .hwndOwner = FindWindow("ThunderXFrame", 0)
    46.         '.pidlRoot = 0& 'open at desktop
    47.         .pidlRoot = 0 'CSIDL_DRIVES 'skips desktop <*> changed to 0 to show network folders
    48.         .sDisplayName = Space$(MAX_PATH + 1)
    49.         .sTitle = sPrompt
    50.         .ulFlags = BIF_RETURNONLYFSDIRS Or [color=red][b]BIF_USENEWUI[/b][/color] Or [color="#CECE00"][b]BIF_EDITBOX[/b][/color]
    51.         .lpfn = 0
    52.         .lParam = 0
    53.         .iImage = 0
    54.     End With
    55.     lpItem = SHBrowseForFolder(BINF)
    56.  
    57.     If lpItem Then
    58.         sDir = Space$(MAX_PATH)
    59.         If SHGetPathFromIDList(ByVal lpItem, sDir) Then
    60.             BrowseFolder = Left(sDir, InStr(1, sDir, Chr(0)) - 1)
    61.         End If
    62.     End If
    63. ' The following step is most important. Neither Windows or VB will
    64. 'automatically release the memory consume by lpItem
    65.  'so its up to the programmer to it.
    66.  
    67.     GlobalFree lpItem
    68.  
    69. End Function
    Attached Images Attached Images  

  13. #13
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: BROWSEINFO or common dialog?

    Quote Originally Posted by dglienna
    You can also call if from the Projects menu.
    I think he's using VBA in which there is no Project menu, the Component dialog box is called Additional Controls and can be reach from the Tools menu.

  14. #14

    Thread Starter
    Lively Member
    Join Date
    Apr 2005
    Posts
    103

    Re: BROWSEINFO or common dialog?

    Haha, thanks a million Joacim A picture's worth 1000 words - next time I'll just post two images: what I have and what I want to make

Posting Permissions

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



Click Here to Expand Forum to Full Width