Recent

Author Topic: Problem with TShellTreeView  (Read 11846 times)

pusuni

  • Jr. Member
  • **
  • Posts: 72
Problem with TShellTreeView
« on: August 16, 2015, 02:01:28 pm »
Hi !

I'm trying to do a directory explorer with custom icons using TShellTreeViev , but I have a problem. The process:

First, I created a TImagelist with four icons:
Icon number 0: closed folder
icon numbre 1: opened folder
icon number 2: hidden  - closed folder and
icon number 3: hiddden - opened folder

After that, I added the following code to the  AdvancedCustomDrawItem  of the TshellTreeView:
Code: [Select]
procedure TForm1.ShellTreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
  var PaintImages, DefaultDraw: Boolean);
begin
  begin
     case Node.Expanded of
        TRUE:
           if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then Node.ImageIndex :=3
           else Node.ImageIndex :=1;
        FALSE:
           if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then Node.ImageIndex :=2
           else Node.ImageIndex :=0;
     end;
  end;
end;

and the directory explorer seems to work correctly. I took two captures:

http://fotos.subefotos.com/17a90577e858d72ea721c8bef2fd4f05o.jpg
http://fotos.subefotos.com/1318c99fb027476c90f53bcee1e061aao.jpg

but when I selected a directory ,  and the text is marked, the icon disappears. I took  another capture:
http://fotos.subefotos.com/bff8a31adf99afe36487e97e86bde157o.jpg

Anyone know what the problem is? Why doesn't it work properly?
What's wrong with my code?


Thanks in advanced

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Problem with TShellTreeView
« Reply #1 on: August 16, 2015, 03:06:46 pm »
Perhaps the var parameter DefaultDraw needs to be set False?

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with TShellTreeView
« Reply #2 on: August 16, 2015, 04:51:25 pm »
Hi! I've tried and it haven't  fixed the issue. It worse.

Code: [Select]
procedure TForm1.ShellTreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
  var PaintImages, DefaultDraw: Boolean);
begin
  begin
    DefaultDraw := FALSE;
     case Node.Expanded of
        TRUE:
           if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then Node.ImageIndex :=3
           else Node.ImageIndex :=1;
        FALSE:
           if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then Node.ImageIndex :=2
           else Node.ImageIndex :=0;
     end;
  end;
end;




Result: http://subefotos.com/ver/?3f23e9327b2c147296d931d7277ed8a5o.jpg#codigos


Code: [Select]
procedure TForm1.ShellTreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
  var PaintImages, DefaultDraw: Boolean);
begin
  begin
     case Node.Expanded of
        TRUE:
           if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then Node.ImageIndex :=3
           else begin Node.ImageIndex :=1;     DefaultDraw := FALSE; end;
         FALSE:
           if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then Node.ImageIndex :=2
           else Node.ImageIndex :=0;
     end;
  end;
end;




Result:
http://subefotos.com/ver/?fe29025c4ebe452fd019ccec4060291co.jpg#codigos


Regards

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Problem with TShellTreeView
« Reply #3 on: August 16, 2015, 06:36:17 pm »
It seems you have to do something rather hackish, such as the following (you will need to adapt this to your specific case):

Code: [Select]
implementation

type
  TCustomTreeViewAccess = class(TCustomTreeView);

procedure TForm1.ShellTreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage;
  var PaintImages, DefaultDraw: Boolean);

var
  idx, indent: integer;
  r: TRect;

  function GetIconIndex: integer;
  begin
    case Node.Expanded of
      True: if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then
              Result:=3
            else Result:=1;
      False: if (FileGetAttr( ShellTreeView1.GetPathFromNode (node)) and faHidden) <> 0 then
               Result:=2
             else Result:=0;
    end;
  end;

begin
  idx:=GetIconIndex;
  Node.ImageIndex:=idx;
  PaintImages:=True;
  DefaultDraw:=True;
  if (cdsSelected in State) then
    begin
      DefaultDraw:=False;
      r:=Node.DisplayRect(False);
      indent:=TCustomTreeViewAccess(Sender).Indent;
      imgList.Draw(Sender.Canvas, indent*Node.Level+indent, r.Top, idx, True);
    end;
end;     

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with TShellTreeView
« Reply #4 on: August 18, 2015, 01:45:04 pm »
Hi howardpc!

I don't know how I should use your PASCAL code.

I've uploaded a test project with only two controls Could you modify this project with your code?

Thanks in advanced

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Problem with TShellTreeView
« Reply #5 on: August 18, 2015, 04:36:47 pm »
The altered project is attached with two components side-by-side so you can compare the two handlers written by you and me.
The code I showed is not complete. It has various flaws, and does not paint some things correctly or completely.

A correct solution would require a deeper understanding than I have of the the various painting stages (cdPrePaint, cdPostPaint, cdPreErase, cdPostErase) and drawing states (cdsSelected, cdsGrayed, cdsDisabled, dsChecked, cdsFocused, cdsDefault, cdsHot, cdsMarked, cdsIndeterminate) that the advanced handler uses.

This would require you or me digging into the sources (which I do not have the time or motivation to do), or the skills of one of the developers who wrote the code. He could explain how to exploit it to do what you are after perfectly. Perhaps such a person will read this and be more help to you.

wp

  • Hero Member
  • *****
  • Posts: 13625
Re: Problem with TShellTreeView
« Reply #6 on: August 18, 2015, 05:21:54 pm »
TShellTreeView is just a plain old TreeView which has a OnGetImageIndex and OnGetSelectedIndex event where an image index can be assigned to each node. I wonder why these events are not published. Forgotten?

Anyway, here are instructions to get icons to each node without digging into the inner details of the treeview, and without a need for custom-drawing of the nodes:

Load the ShellCtrls.pas (from lazarus\lcl)
At the end of the declaration of TShellTreeview add:
Code: [Select]
  TShellTreeView = class(TCustomShellTreeView)
  published
    { TCustomTreeView properties }
    property Align;
    ....
    property StateImages;   // <--- add
    property OnGetImageIndex;   // <-- add
    property OnGetSelectedIndex;  // <-- add
  end;
Save and recompile the ide (menu "Tools" / "Build Lazarus with..."
After a while Lazarus will restart, and the TShellTreeView will have the new properties "StateImages" (not needed here), "OnGetImageIndex" and "OnGetselectedIndex".

Add this event handler for "OnGetImageIndex" of the ShellTreeView:
Code: [Select]
procedure TForm1.ShellTreeView1GetImageIndex(Sender: TObject; Node: TTreeNode);
var
  path: String;
  attr: LongInt;
begin
  path := ShellTreeView1.GetPathFromNode(node);
  attr := FileGetAttr(path);
  case Node.Expanded of
    True : if (attr and (faHidden + faVolumeID + faSysFile)) = faHidden then  // extended to the the drive icons correct
             Node.ImageIndex:=3 else
             Node.ImageIndex:=1;
    False: if (attr and (faHidden + faVolumeID + faSysFile)) = faHidden then
             Node.ImageIndex:=2 else
             Node.ImageIndex:=0;
  end;
end; 

and add this event handler to "OnGetSelectedIndex":
Code: [Select]
procedure TForm1.ShellTreeView1GetSelectedIndex(Sender: TObject; Node: TTreeNode);
begin
  Node.SelectedIndex := Node.ImageIndex;
end;

And finally, if not already done, link the "Images" property of the Shelltreeview with the imagelist on the form.

This is working here at Windows 7.

If nobody disagrees here then I'll post a patch to add them to the official version.

Bart

  • Hero Member
  • *****
  • Posts: 5743
    • Bart en Mariska's Webstek
Re: Problem with TShellTreeView
« Reply #7 on: August 18, 2015, 07:01:43 pm »
If nobody disagrees here then I'll post a patch to add them to the official version.

Don't you have commit rights?
Feel free to commit IMO, otherwise upload patch and assign to me.

Bart

wp

  • Hero Member
  • *****
  • Posts: 13625
Re: Problem with TShellTreeView
« Reply #8 on: August 18, 2015, 07:24:05 pm »
Don't you have commit rights?
Only for "components". Uploaded a patch as issue #28539.

wp

  • Hero Member
  • *****
  • Posts: 13625
Re: Problem with TShellTreeView
« Reply #9 on: August 18, 2015, 07:29:50 pm »
but when I selected a directory ,  and the text is marked, the icon disappears.

This is because every node uses the "SelectedIndex" for selection of the image in the selected case. Your code only assigns the "node.ImageIndex" - just add "node.SelectedIndex := node.ImageIndex" and it should work.

Bart

  • Hero Member
  • *****
  • Posts: 5743
    • Bart en Mariska's Webstek
Re: Problem with TShellTreeView
« Reply #10 on: August 18, 2015, 08:45:46 pm »
Don't you have commit rights?
Only for "components". Uploaded a patch as issue #28539.

Thanks.

Bart

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with TShellTreeView
« Reply #11 on: August 19, 2015, 08:24:31 am »
Thanks very much at all. I fixed the issue with all this information.


Best regards,
pusuni

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with TShellTreeView
« Reply #12 on: August 19, 2015, 10:00:44 am »
but when I selected a directory ,  and the text is marked, the icon disappears.

This is because every node uses the "SelectedIndex" for selection of the image in the selected case. Your code only assigns the "node.ImageIndex" - just add "node.SelectedIndex := node.ImageIndex" and it should work.


Guau!! I've Added your code to mine: this is the most easy way to fix the problem!!


Thank you very much

Bart

  • Hero Member
  • *****
  • Posts: 5743
    • Bart en Mariska's Webstek
Re: Problem with TShellTreeView
« Reply #13 on: August 19, 2015, 11:13:26 am »
Uploaded a patch as issue #28539.

Committed in r49686.

Thanks.

Bart

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with TShellTreeView
« Reply #14 on: August 28, 2015, 12:48:34 pm »
Hi again!

I've found a new problem with the control: if I change the "FileSortType" property from the fstNone (it's the default value) to another value (fstAlphabet, for example) in Windows,  I get all the carpets duplicate.

If I don't change the default value, all work properly. In Linux  there is not problem.

I took two captures:
http://fotos.subefotos.com/79168f486dc15c52d64a4fc6a2600fe7o.jpg

http://fotos.subefotos.com/26f4e421d2ee1521c34390b4c5dafd06o.jpg

Is it a bug?

Thanks in advanced

 

TinyPortal © 2005-2018