procedure TStCustomShellTreeView.ShellEvent(Sender : TObject;
SI1, SI2 : TStShellItem; Events : TStNotifyEventsSet);
const
LastPidl : PItemIDList =
nil;
var
I : Integer;
Node : TTreeNode;
NewNode : TTreeNode;
SF : TStShellFolder;
Pidl : PItemIDList;
begin
DoShellChangeNotify(SI1, SI2, Events);
if InternalEvent
then begin
InternalEvent := False;
Exit;
end;
if SI1 =
nil then
Exit;
{ Something happened in the shell. See if it's something we }
{ need to handle. We could get this event twice. If we do, we }
{ don't add to the tree view twice. }
if ((neFolderCreate
in Events)
or (neDriveAdd
in Events))
or ((neFileCreate
in Events)
and (toShowFiles
in Options))
and (SI1.Pidl <> LastPidl)
then begin
{ A folder was created. See if its parent is one we have in the list. }
Node := FindParentNode(SI1);
if Node <>
nil then
{ If the node doesn't have any subnodes then we don't }
{ need to do anything. }
if Node.Count <> 0
then begin
SF := TStShellFolder.Create(Controller);
SF.Assign(TStShellFolder(SI1));
if SF.FParentFolder =
nil then
SF.FParentFolder := Controller.DesktopFolder;
SF.ParentList := Folders.FList;
{ It could be that a network drive is in the list but was }
{ not connected and has been reconnected. If that is the }
{ case then we don't want to add the folder again. }
NewNode := FindNodeByPath(SF.Path);
if NewNode =
nil then
NewNode := Items.AddChild(Node, SF.DisplayName);
NewNode.Data := Pointer(Folders.FList.Add(SF));
LastPidl := SF.Pidl;
NewNode.ImageIndex := SF.IconIndex;
NewNode.SelectedIndex := SF.OpenIconIndex;
NewNode.OverlayIndex := SF.OverlayIconIndex;
if (neDriveAdd
in Events)
then
NewNode.HasChildren := True;
CustomSort(TreeCompareFunc, Integer(Self));
Exit;
end;
end;
if ((neFolderDelete
in Events)
or (neDriveRemove
in Events)
or ((neFileDelete
in Events)
and (toShowFiles
in Options)))
then begin
{ A folder was deleted. See if it is one we have in the list. }
Node := FindNodeByPidl(SI1.Pidl);
if Node =
nil then
Node := FindNodeByPath(SI1.Path);
if (Node <>
nil)
and (Selected = Node)
then
Selected := Node.GetNext;
if Node <>
nil then begin
{ Remove it from the underlying list and from the tree view. }
Folders[Integer(Node.Data)].Free;
Folders.FList[Integer(Node.Data)] :=
nil;
Node.Delete;
Exit;
end;
end;
if (neFolderRename
in Events)
or
((neFileRename
in Events)
and (toShowFiles
in Options))
then begin
{ A folder was renamed. This could be an item deleted to the }
{ recycle bin. See if the destination is the recycle bin. }
SHGetSpecialFolderLocation(
Application.Handle, CSIDL_DESKTOP, Pidl);
if SI2 <>
nil then begin
if ILIsEqual(Pidl, SI2.Pidl)
then begin
{ It's the recycle bin so delete from the tree view. }
Node := FindNodeByPidl(SI1.Pidl);
if Node <>
nil then begin
Folders[Integer(Node.Data)].Free;
Folders.FList[Integer(Node.Data)] :=
nil;
Node.Delete;
Exit;
end;
end else
{ See if it's one we have in the list. }
for I := 0
to Pred(Folders.Count)
do begin
if UpperCase(Folders[I].Path) = UpperCase(SI1.Path)
then begin
Folders[I].Assign(TStShellFolder(SI2));
if Folders[I].FParentFolder =
nil then
Folders[I].FParentFolder := Controller.DesktopFolder;
Node := FindNodeByPidl(SI2.FPidl);
if Node <>
nil then begin
Node.Text := SI2.DisplayName;
CustomSort(TreeCompareFunc, Integer(Self));
end;
Break;
end;
end;
end;
end;
if (neNetShare
in Events)
or (neNetUnShare
in Events)
then begin
Node := FindNodeByPidl(SI1.Pidl);
if Node <>
nil then
Node.OverlayIndex := SI1.OverlayIconIndex;
end;
if (neMediaInsert
in Events)
or (neMediaRemove
in Events)
then begin
{ Media was added or removed. We need to flush the shell }
{ cache and update the display or we'll just get a cached }
{ icon and display name. }
Node := FindNodeByPath(SI1.Path);
if Node <>
nil then begin
Node.ImageIndex := SI1.IconIndex;
Node.Text := SI1.DisplayName;
end;
end;
end;