Forum > General

[Solved] ShellTreeView, manual NodeAdd, basically rubbish idea?

(1/2) > >>

d7_2_laz:
Win x64; laz-main (2.3.0) . Not 2.2.4 due to changes

No, i don't want to open the 'box of Pandora' (a term from a similar topic). But maybe a simple piece of information s missing for to make this happen. If not possible by principle, i'll forget it. - It's Not an issue! Simply an idea.
I post it in General, not LCL, because i'd think it's rather a basic question rather than specific for ShellCtrls stuff.

Imagine for a moment xou have a file change monitor around a shelltreeview who detects that an external usb drive had been attached. I asked my self if it isn't possible to show it up, and indeed that was easily. Because not really an provided "FileInfo" searchrec would be needed. For added folders a correct FileInfo structure  would be needed, but here i failed with a SIGSEV.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---=== This procedure placed simply for test within ShellCtrls would work: // Soemhow similar as parts of TCustomShellTreeView.PopulateWithBaseFiles;procedure TCustomShellTreeView.test_ShAddTreeNode(parNode: TTreeNode; fullpath: String);var NewNode: TTreeNode; capt: String;    FI: TFileItem; SR: TSearchRec; FindResult: Integer;begin  if parNode = Nil then       capt := ExcludeTrailingBackslash(fullpath)  else capt := ExcludeTrailingBackslash(ExtractFileName(fullpath));  SR.Name := fullpath;   // Really fille SearchRec would be next  FI := TFileItem.Create(SR, '');  // This one here is only for test with add a drive  NewNode := TShellTreeNode(Items.AddChildObject(nil, capt, PChar(capt)));  TShellTreeNode(NewNode).FFileInfo := TFileItem(FI).FileInfo;    //  Not really needed here, but would work  NewNode.HasChildren:= True;end;
I'm aware: TCustomShellTreeView.PopulateTreeNodeWithFiles does not really create a SerachRec record.  But to apply and assign one as mentioned above is possible. Simply as a pre-exercise for folders, where FileInfo surely is needed-

=== When trying to access the FFileInfo structure within an unit using a helper type, it compiles, but at runtime it throws a SIGSEV.
The debug call stack does show an error at funciton "fpc_ansistr_decr_ref".


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Type  TShellTreeNodeEx = class(TShellTreeNode)  private    FFileInfo: TSearchRec;    FBasePath: String;  protected  public    //function ShortFilename: String;    //function FullFilename: String;    property FileInfo: TSearchRec read FFileInfo write FFileInfo;   // Make the property public accessible    //function IsDirectory: Boolean;    property BasePath: String read FBasePath;  end; procedure TExtShellTreeView.yShAddTreeNode(parNode: TTreeNode; fullpath: String);var NewNode: TShellTreeNode;  // or NewNode: TShellTreeNodeEx    capt: String; FI: TFileItem; SR: TSearchRec; FindResult: Integer;begin  if parNode = Nil then       capt := ExcludeTrailingBackslash(fullpath)  else capt := ExcludeTrailingBackslash(ExtractFileName(fullpath));  SR.Name := fullpath;   // Really fille SearchRec would be next  FI := TFileItem.Create(SR, '');  // This one here is only for test via add a drive    //NewNode := TShellTreeNode(Items.AddChildObject(nil, capt, PChar(capt)));  //TShellTreeNode(NewNode).FFileInfo := TFileItem(FI).FileInfo;    //  Not really needed here, but would work    // This one woould be sufficient to work (the node appear and is expandable):  NewNode := TShellTreeNodeEx(Items.AddChildObject(nil, capt, PChar(capt)));    // THIS COMPILES, BUT SIGSEV'S:  TShellTreeNodeEx(NewNode).FileInfo := TFileItem(FI).FileInfo;    /// This line is the problematic one    NewNode.HasChildren:= True;end;
Is there possibly an easy explanation that this basically wont't work?
If not, i'll forget it...

Attached a simplified test project that triggers the NodeAdd manually (without FileWatcher).

wp:
I have the feeling that the declaration of TShellTreeNodeEx is wrong: it duplicates the FFileInfo field. It exists on the ancestor TShellTreeNode, and you reclare it again in the TShellTreeNodeEx. Since the node is created as TShellTreeNode the FFileInfo of that class is used by the entire ShellTreeView. But you assign the FileItem's FileInfo to the new class's FileInfo leaving the inherited one alone.

You could move the FFileInfo declaration in the original TShellTreeNode to the protected section; this way the field is accessible from descendant classes.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---// in shellctrls:type  TShellTreeNode = class(TTreeNode)  private//    FFileInfo: TSearchRec;    FBasePath: String;  protected    FFileInfo: TSearchRec;    ...  end; // in your main unit:  TShellTreeNodeEx = class(TShellTreeNode);Doing this I can run your failing step 2 without crashing.


d7_2_laz:
Oh, yes. The first topic (leaving the inherited one alone) was just because the inherited FFileInfo was not seen from within the unit at all and, so, it should be made accessible.

The second topic (move the FFileInfo declaration in the original TShellTreeNode to the protected section): that does work fine. For this use case. But it was just so that i really didn't intend to aski for changes of ShellCrls.pas.

With this change it appears to me that the ShellTreeView (something similar might happen for the ShellTreeView) would work smoothly together with an app-level placed folder change monitor (whatever this is coded).
May there be reasons against moving the FFileInfo declaration from private to protected,  regarding  that does allow such a use case?

wp:
Committed a new version of ShellCtrls to main in which TShellTreeNode.FFileInfo is protected rather than private. Can't imagine that this change should be harmful in any way, however, extends the usability of the class.

d7_2_laz:
Hello wp, this is really great, it makes it possible to work on it !
I will be very happy to report back if the proof of concept succeeds and if i detect any side-effects.

Many thanks for having given this opportunity!

Navigation

[0] Message Index

[#] Next page

Go to full version