Search code examples
delphidelphi-2007windows-shelltlistview

Get/Set TShellListView Path/Folder as String (Not Using .Root)


I want to set the path for a TShellListView to display a directory of files using Delphi 2007. I can initially use TShellListView.Root to set the root path like this and it shows the directory I want:

View := TShellListView.Create(Self);
// ...
View.Root := 'C:\Windows';

But if the user navigates away from that directory using backspace and I try to set the .Root back to the original directory, the directory displayed does not change. It looks like .Root is meant to define the root of the shell namespace, not the current directory.

Also, if the user navigates around (using backspace, etc.) the .Root property does not update to reflect the currently displayed path. There is no .Path property like there is for TShellTreeView.

What I want is a way to get and set the current path as a string without being required to link the TShellListView to a TShellTreeView and set TShellTreeView.Path or hack ShellCtrls.pas since the relevant methods of TShellListView all look private. I find it hard to believe there isn't a straightforward way to get/set the path, so I assume I'm missing something simple here, but this component is not documented at all.


Solution

  • You can get the currently loaded path using

    ShellListView1.RootFolder.PathName
    

    Setting the Root property works, but it isn't updated when you change folders interactively. So you need to force it to think there's a change. This works if you're always resetting it to the same original path:

    ShellListView1.Root := View.RootFolder.PathName; // Updates to current location
    ShellListView1.Root := 'C:\Windows';
    

    Alternatively, for arbitrary paths you could just add/remove the trailing \ in order to fool the SameText check in SetRoot:

    if ShellListView1.Root[Length(ShellListView1.Root)] = '\' then
      ShellListView1.Root := ExcludeTrailingPathDelimiter(ANewPath)
    else
      ShellListView1.Root := IncludeTrailingPathDelimiter(ANewPath);