We help IT Professionals succeed at work.

How to get dynamically the Pidl of the current item of a SHBROWSEFORFOLDER list

655 Views
Last Modified: 2008-08-06
Hello,
Still working with SHBrowseForFolder with the NEW STYLE flag, it's possible to rename a folder.
Nevertheless, in that case, the BFFM_SELCHANGED message is not sent to the BrowseCallbackProc callback function and, consequently, it's impossible to get the new folder name to display it in a status static control for example.
Therefore, I have subclassed the "SHBROWSEFORFOLDER SHELLNAMESPACE CONTROL" so that I can intercept the WM_NOTIFY messages sent to it by its "SYSTREEVIEW32" child, one of these messages being the name change.

'MODULE
Public NormalProcSHBROWSER&, hWndSHBROWSER&, hWndLIST&

Public Type NMHDR
    hwndFrom As Long
    idFrom As Long
    Code As Long
End Type

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length&)

Function BrowseCallbackProc&(ByVal hwnd&, ByVal Msg&, ByVal lParam&, ByVal lpData&)
   Dim Child&, TXT$
   On Error Resume Next
   Select Case Msg
     Case BFFM_INITIALIZED
          .....
          'Get the hWnd of the SHBROWSEFORFOLDER and SYSTREEVIEW32 windows
          Child = GetWindow(hwnd, 5)
          Do While Child <> 0
              TXT = Space(255): x = GetClassName(Child, TXT, 255): TXT = UCase$(Left$(TXT, x))
              if TXT = "SHBROWSEFORFOLDER SHELLNAMESPACE CONTROL" Then
                 hWndSHBROWSER = Child
                 Child = GetWindow(hWndSHBROWSER, 5)
                 Do While Child <> 0
                    TXT = Space(255): x = GetClassName(Child, TXT, 255): TXT = UCase$(Left$(TXT, x))
                     If TXT = "SYSTREEVIEW32" Then hWndLIST = Child: Exit Do
                     Child = GetWindow(Child, 2)
                     Loop
                 Exit Do
              End if
              Child = GetWindow(Child, 2)
              Loop
          'Subclass SHBROWSEFORFOLDER
          NormalProcSHBROWSER = SetWindowLong(hWndSHBROWSER, -4, AddressOf WinProcSHBROWSER)

     Case BFFM_SELCHANGED
          GetPathNameText lParam

    End Select
End Function

Function GetPathNameText$(pidl&)
    Dim x&, TXT$
    TXT = Space(260)
    x = SHGetPathFromIDListA(pidl, TXT)
    If x = 1 Then TXT = Left$(TXT, InStr(TXT, Chr$(0)) - 1)
    GetPathNameText = TXT
End Function

Function WinProcSHBROWSER&(ByVal hwnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
    Dim NM As NMHDR, x&
    If Msg = WM_NOTIFY Then
        CopyMemory NM, ByVal lParam, Len(NM)
        If NM.Code = -460 Then
            If NM.hwndFrom = hWndLIST Then

'HERE I KNOW THAT THE NAME OF THE FOLDER displayed in the current item HAS CHANGED.
'I should want to now retrieve the Pidl of the current item of  the
' SYSTREEVIEW32 to Call GetPathNameText
'or use it to send a forced BFFM_SELCHANGED notification to the to the BrowseCallbackProc
' function even if the selection has not really changed.
'HOW TO KNOW THE CURRENT Pidl ????????????????????

            End If
        End If
    End If
   
    WinProcSHBROWSER = CallWindowProc(NormalProcSHBROWSER, hwnd, Msg, wParam, lParam)
   
End Function

Or maybe another solution exist ???
Thank you for your help,
Philippe
Comment
Watch Question

Author

Commented:
I have rewritten the WinProcSHBROWSER function ... not to get the PiDl but directly the new edited text
...but it doesn't work perfectly :

Public Type TVITEM
    mask As Long
    hItem As Long
    state As Long
    statemask As Long
    Text As String          'other solution is "Text as Long" to be used as pointer
    Textmax As Long
    iImage As Long
    iSelectedimage As Long
    cChildren As Long
    lParam As Long
End Type

Public Type NMTVDISPINFO
    hdr As NMHDR
    item As TVITEM
End Type

Const TVN_FIRST = -400
Const TVN_ENDLABELEDIT = TVN_FIRST - 60

Function WinProcSHBROWSER&(ByVal hwnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
    Dim NM As NMHDR, Buffer as String, DI As NMTVDISPINFO, TV As NMTREEVIEW

    If Msg = WM_NOTIFY Then
        CopyMemory NM, ByVal lParam, Len(NM)
        If NM.Code = TVN_ENDLABELEDIT Then
            If NM.hwndFrom = hWndLIST Then
                WinProcSHBROWSER = CallWindowProc(NormalProcSHBROWSER, hwnd, Msg, wParam, lParam)
                CopyMemory DI, ByVal lParam, Len(DI)
                Buffer = DI.item.Text
                Exit Function
            End If
        End If
    End If
    WinProcSHBROWSER = CallWindowProc(NormalProcSHBROWSER, hwnd, Msg, wParam, lParam)
End Function

Unfortunately, THE STRING GOT IN THE Buffer VARIABLE IS ONLY 1-character long, i.e. "M" instead of "MyFolder" or "S" instead of "Second folder" ...
Same result if  TVITEM.Text is declared as Long and then
 Buffer = Space(260)
 and then call lstrcpy Buffer, DI.item.Text

What's wrong ????

Thank you for your possible help ... though my problem seems to be not really interesting for anybody else :-)
Philippe
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
A small comment : the title of the question should be :
How to get and display dynamically the name of the selected folder in a SystreeView32 control

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.