Re: shBrowseForFolder procedure run issue

From: Randy Birch (rgb_removethis_at_mvps.org)
Date: 07/13/04

  • Next message: iela: "How to send IP address automatically to the server in every 5 minutes?"
    Date: Mon, 12 Jul 2004 22:43:49 -0400
    
    

    The browse dialog seems to remember previous setting once it has
    successfully navigated to a folder - that is, it has no problem selecting
    that folder the second time. However, as I said earlier I can not reproduce
    your problem with either version of the code, in VB or as a standalone exe.
    What happens if you compile the modified setup exe as pcode, rather than
    native code which I suspect you are using?

    -- 
    Randy Birch
    MVP Visual Basic
    http://vbnet.mvps.org/
    Please respond only to the newsgroups so all can benefit.
    "Arbormead" <Arbormead@discussions.microsoft.com> wrote in message 
    news:2EDBDF63-8FF3-458F-BFD1-A4F8FC9B6C13@microsoft.com...
    : I've noticed something else.  When the program is first run from within 
    VB, it behaves as described previously where My Computer is the start point. 
    After the first time a folder is returned it bahves just like it should.  I 
    tried this a few times and each time it worked after the first returned 
    folder was selected.  I then packaged it up and installed it.  On each 
    successive execution the initial start location was My Computer, but after 
    that it was fine.
    :
    : Rather than the program itself, could this be something to do with 
    installing something in to memory, perhaps something that isn't happening on 
    first startup.  I am not hot on memory issues so I am clutching at staws a 
    little now.
    :
    :
    :
    :
    : "Randy Birch" wrote:
    :
    : > Frankly I can not reproduce your problem using either the original code 
    or
    : > the modified version. What OS is this failing on?
    : >
    : > You stated earlier that "I have used the VB6 Package and deployment 
    Wizard
    : > and also the Visual Studio Installer, both do the same thing."  What 
    does
    : > this mean? ... that the browse dialog in those applications also 
    incorrectly
    : > show My Computer when a valid drive is specified?
    : >
    : > Test this for me ... with your drive C:\ specified as the initial 
    directory
    : > place a breakpoint on the IsValidDrive function and step through (via 
    F8)
    : > the procedure and continue into the calling routine (FixPath) to see 
    what
    : > part of the If..Then condition executes.  (The function is actually 
    wrong,
    : > but it works - the fix is below).
    : >
    : > As coded IsValidDrive should return the string "5" assuming you have an 
    A:
    : > drive on your box, and no B: drive. Because "5" is not false, the If 
    portion
    : > of the If..Then test in Fixpath executes and the drive is tested to 
    ensure
    : > it has a trailing slash . If IsValidDrive fails the If...Then in FixPath
    : > will execute the Else condition and remove the trailing slash from the 
    drive
    : > letter. For drives this alone is sufficient to prevent proper selection 
    of
    : > the string, with the default 'My Computer' selected instead.
    : >
    : >
    : > Once you see what's going on with this, make this mod to the 
    IsValidDrive
    : > function ...
    : >
    : > - change the function declaration to As Boolean from As String
    : >
    : >    Private Function IsValidDrive(sPath As String) As Boolean
    : >
    : > - and modify the IsValidDrive = line to include a boolean test:
    : >
    : >    IsValidDrive = InStr(1, buff, sPath, vbTextCompare) > 0
    : >
    : > -- 
    : >
    : > Randy Birch
    : > MVP Visual Basic
    : > http://vbnet.mvps.org/
    : > Please respond only to the newsgroups so all can benefit.
    : >
    : >
    : > "Arbormead" <Arbormead@discussions.microsoft.com> wrote in message
    : > news:D012D7E6-96DF-498A-AB05-D20D40FBEFC1@microsoft.com...
    : > : Randy
    : > :
    : > : I must be missing something.  I have checked the ammendments you 
    suggest
    : > and still it starts at My Computer, even if I bypass looking at a 
    textbox
    : > and type in C:\ directly rather than use fixpath.  I have included the 
    code
    : > below that has been changed, all the rest is original.   Maybe you can
    : > something obvious.
    : > :
    : > : When the folder is selected it performs as expected, it is just the 
    start
    : > up location is not using the textbox path even though I can trace the
    : > procedure uses the path right through to  the BrowseCallbackProcStr 
    function
    : > where sBrowseDlgInitialPath becomes empty [should this procedure loop 3
    : > times?].
    : > :
    : > : Private Function BrowseForFolderByPath(sSelPath As String) As String 
    ''in
    : > the form code
    : > :
    : > :    Dim BI As BROWSEINFO
    : > :    Dim pidl As Long
    : > :    Dim lpSelPath As Long
    : > :    Dim spath As String * MAX_PATH
    : > :
    : > :    With BI
    : > :       .hOwner = Me.hWnd
    : > :       .pidlRoot = 0
    : > :       .lpszTitle = "Pre-selecting folder using the folder's string."
    : > :       .lpfn = FARPROC(AddressOf BrowseCallbackProcStr)
    : > :
    : > :       'lpSelPath = LocalAlloc(LPTR, Len(sSelPath) + 1)
    : > :       'CopyMemory ByVal lpSelPath, ByVal sSelPath, Len(sSelPath) + 1
    : > :       '.lParam = lpSelPath
    : > :       sBrowseDlgInitialPath = sSelPath
    : > :
    : > :    End With
    : > :
    : > :    pidl = SHBrowseForFolder(BI)
    : > :
    : > :    If pidl Then
    : > :
    : > :       If SHGetPathFromIDList(pidl, spath) Then
    : > :          BrowseForFolderByPath = Left$(spath, InStr(spath, 
    vbNullChar) -
    : > 1)
    : > :       Else
    : > :          BrowseForFolderByPath = ""
    : > :       End If
    : > :
    : > :       Call CoTaskMemFree(pidl)
    : > :
    : > :    Else
    : > :       BrowseForFolderByPath = ""
    : > :    End If
    : > :
    : > :   Call LocalFree(lpSelPath)
    : > :
    : > : End Function
    : > :
    : > :
    : > : ''in the module
    : > : Public Function BrowseCallbackProcStr(ByVal hWnd As Long, _
    : > :                                       ByVal uMsg As Long, _
    : > :                                       ByVal lParam As Long, _
    : > :                                       ByVal lpData As Long) As Long
    : > :
    : > :   'Callback for the Browse STRING method.
    : > :
    : > :   'On initialization, set the dialog's
    : > :   'pre-selected folder from the pointer
    : > :   'to the path allocated as bi.lParam,
    : > :   'passed back to the callback as lpData param.
    : > :
    : > :    Select Case uMsg
    : > :       Case BFFM_INITIALIZED
    : > :
    : > :          'Call SendMessage(hWnd, BFFM_SETSELECTIONA, _
    : > :                           True, ByVal lpData)
    : > :
    : > :           If (hWnd <> 0) And Len(sBrowseDlgInitialPath) > 0 Then
    : > :             DoEvents  '<this may not be required
    : > :             Call SendMessage(hWnd, BFFM_SETSELECTIONA, 1, ByVal
    : > sBrowseDlgInitialPath)
    : > :          End If
    : > :
    : > :          Case Else:
    : > :
    : > :    End Select
    : > :
    : > : End Function
    : > :
    : > : "Randy Birch" wrote:
    : > :
    : > : > My mistake ... because the demo calls SHBrowseForFolder in the form, 
    but
    : > : > BrowseCallbackProcStr is in a BAS module, the variable
    : > : > 'sBrowseDlgInitialPath' should be declared Public in the general
    : > : > declarations section of the BAS module where BrowseCallbackProcStr
    : > lives.  I
    : > : > just re-tried the browse code with these changes and C:\ (and all 
    other
    : > : > folders and shares I fired at it) were all properly selected.
    : > : >
    : > : > 'BAS module
    : > : > Option Explicit
    : > : > Public sBrowseDlgInitialPath As String
    : > : >
    : > : > -- 
    : > : >
    : > : > Randy Birch
    : > : > MVP Visual Basic
    : > : > http://vbnet.mvps.org/
    : > : > Please respond only to the newsgroups so all can benefit.
    : > : >
    : > : >
    : > : > "Arbormead" <Arbormead@discussions.microsoft.com> wrote in message
    : > : > news:70C30773-60E8-4106-A7C5-9DF9CFD9A656@microsoft.com...
    : > : > : Randy
    : > : > :
    : > : > : You are right I am using the string method.  However, I have made 
    the
    : > : > adjustments you recommend but I am unsure where to declare the 
    public
    : > : > bas-level string variable : Private sBrowseDlgInitialPath As String.
    : > : > Declaring this at the start of the module and making the changes 
    below
    : > : > starts the browse at My Computer each time it runs, even though 
    fixpath
    : > is
    : > : > set to c:\
    : > : > :
    : > : > : Could you help me out a little further with the location of the
    : > : > declaration and where I may be going wrong? The only changes I have 
    made
    : > is
    : > : > to set the spath value as follows where IOPath is the contents of a
    : > textbox
    : > : > populated from an ini file on form load.  I did change the fixpath
    : > default
    : > : > value in the fixpath function to a server location 
    [\\server\folder\"
    : > but
    : > : > for ease I have changed tback to c:\ in case this was where I was 
    going
    : > : > wrong
    : > : > :
    : > : > : spath = FixPath(IO1Path.Text)
    : > : > : getdir = BrowseForFolderByPath(spath)
    : > : > :
    : > : > : I look farward to your comments
    : > : > :
    : > : > : "Randy Birch" wrote:
    : > : > :
    : > : > : > You don't mention specifically if you're using the PIDL or 
    string
    : > : > method,
    : > : > : > but I suspect the string version of the code. Try this 
    modification
    : > to
    : > : > the
    : > : > : > way the callback is set ... the routine/code quoted here is the 
    same
    : > as
    : > : > from
    : > : > : > my page, so make any appropriate translation if you renamed
    : > variables or
    : > : > : > procedures:
    : > : > : >
    : > : > : > 1) Define a new public bas-level string variable called
    : > : > : > sBrowseDlgInitialPath ...
    : > : > : >
    : > : > : >     Private sBrowseDlgInitialPath As String
    : > : > : >
    : > : > : >
    : > : > : > 2) comment out the following lines in the BrowseForFolderByPath
    : > : > function:
    : > : > : >
    : > : > : >       lpSelPath = LocalAlloc(LPTR, Len(sSelPath) + 1)
    : > : > : >       CopyMemory ByVal lpSelPath, ByVal sSelPath, Len(sSelPath) 
    + 1
    : > : > : >       .lParam = lpSelPath
    : > : > : >
    : > : > : >
    : > : > : > 3) add this line in place of the lines above (sSelPath was 
    passed to
    : > : > : > BrowseForFolderByPath as the initial path):
    : > : > : >
    : > : > : >     sBrowseDlgInitialPath = sSelPath
    : > : > : >
    : > : > : >
    : > : > : > 4) in the BrowseCallbackProcStr function, comment out the line:
    : > : > : >
    : > : > : >          Call SendMessage(hWnd, BFFM_SETSELECTIONA, True, ByVal
    : > lpData)
    : > : > : >
    : > : > : >
    : > : > : > 5) and add this block in its place:
    : > : > : >
    : > : > : >          If (hwnd <> 0) And Len(sBrowseDlgInitialPath) > 0 Then
    : > : > : >             DoEvents  '<this may not be required
    : > : > : >             Call SendMessage(hwnd, BFFM_SETSELECTIONA, 1, ByVal
    : > : > : > sBrowseDlgInitialPath)
    : > : > : >          End If
    : > : > : >
    : > : > : > Here we've removed the passing of the initial folder from the
    : > callback's
    : > : > : > lpData member (and removed the need to allocate the memory for 
    that
    : > : > string
    : > : > : > in the call), and simply used the public string variable to set 
    the
    : > : > initial
    : > : > : > path. The lParam member of the BrowseInfo UDT is not used, nor 
    is
    : > the
    : > : > lpData
    : > : > : > member of BrowseCallbackProc. I find this always works, whereas 
    I
    : > did
    : > : > : > experience a problem with the lpData method on Windows 2000 
    which
    : > : > prompted
    : > : > : > me to devise this workaround.
    : > : > : >
    : > : > : > -- 
    : > : > : >
    : > : > : > Randy Birch
    : > : > : > MVP Visual Basic
    : > : > : > http://vbnet.mvps.org/
    : > : > : > Please respond only to the newsgroups so all can benefit.
    : > : > : >
    : > : > : >
    : > : > : > "Arbormead" <Arbormead@discussions.microsoft.com> wrote in 
    message
    : > : > : > news:501D74F8-70C2-4CD5-8E3C-DE916322F5F9@microsoft.com...
    : > : > : > : I have used the shBrowseForFolder procedure as supplied by 
    Randy
    : > Birch
    : > : > at
    : > : > : > VBNet and have come across a small problem when packaging up the
    : > : > project.
    : > : > : > :
    : > : > : > : Basically the procedure starts at a predefined path as laid 
    out in
    : > a
    : > : > text
    : > : > : > box, the contents of which are loaded at the start.  This works 
    fine
    : > : > with
    : > : > : > VB6 but when I package up the project and then install it, the 
    same
    : > : > : > procedure starts at My Computer.  After selecting a path the 
    second
    : > time
    : > : > I
    : > : > : > run it it works fine.  Obviously I would like to run it fine the
    : > first
    : > : > time
    : > : > : > but I'm unsure why this is happening.
    : > : > : > :
    : > : > : > : I have used the VB6 Package and deployment Wizard and also the
    : > Visual
    : > : > : > Studio Installer, both do the same thing.  Is there anywhere 
    else I
    : > : > should
    : > : > : > be looking to resolve this issue?  I can post the code if 
    required
    : > but
    : > : > : > basically it is a very minor modification od the one I found at
    : > : > : > http://vbnet.mvps.org/code/callback/browsecallback.htm
    : > : > : > :
    : > : > : > : Let me know if I can provide more information
    : > : > : > :
    : > : > : > : many thanks
    : > : > : >
    : > : > : >
    : > : >
    : > : >
    : >
    : > 
    

  • Next message: iela: "How to send IP address automatically to the server in every 5 minutes?"

    Relevant Pages

    • Re: Recycle Bin Help
      ... > As far as I know, the actual folder is always in the drive's root. ... > Dim bFound As Boolean ... > Dim sDrive As String ... > and then add another loop to go through all the drives. ...
      (microsoft.public.vb.winapi)
    • Re: Mounting a "virtual drive"
      ... MapFolderToDrive() method, which you pass a drive letter and a folder name ... It can also be run at startup to re-map drives on reboot. ... internal static extern bool DefineDosDevice(uint dwFlags, string ... mappedVolumeName = volumeMap.ToString.Substring; ...
      (microsoft.public.dotnet.languages.csharp)
    • Re: Transfer Files Using VBA
      ... holding down the Shift key and selecting the last file. ... You can then drag all of the files to the new folder. ... look at the Name statement in Vba help to get started. ... I'd like to transfer files from several drives on my pc to one cetnral ...
      (microsoft.public.excel)
    • Re: How to use OpenFileDialog control to select directory path.
      ... you can use the BrowseForFolder dialog to do that. ... Sub New(ByVal Text As String) ... > selecting file using OpenFileDialog control. ... > It should return path of the selected folder, but seems to be not working. ...
      (microsoft.public.dotnet.languages.vb)
    • Re: Mapping of network drives
      ... include mapped drives, even if the interactive login account has the drive mapped. ... function but this works only for local folder creation... ... BOOL MapNetworkDrive(CString sDriveLetter, CString sUserName, CString ... There is no need to declare this as a fixed-length initialized string. ...
      (microsoft.public.vc.mfc)