Delphi Pages Forums

Delphi Pages Forums (http://www.delphipages.com/forum/index.php)
-   General (http://www.delphipages.com/forum/forumdisplay.php?f=2)
-   -   problems porting an app from Delphi 7 to 10 (http://www.delphipages.com/forum/showthread.php?t=217319)

kolbasz 12-03-2015 09:18 PM

1 Attachment(s)
Ok, I did it anyway! Just for the fun. :)

1. Download VST from here(first link): http://www.soft-gems.net/index.php/all-downloads After install don't forget to add the source folder both for win32/win64.
2. Download TestVST.zip
3. Enjoy!

http://i1270.photobucket.com/albums/...olbasz/vst.png


PS: If you have trouble installing VST under Delphi Seattle(but only then) try this link: http://blog.kassebaum.eu/

kolbasz 12-03-2015 09:34 PM

Oh hell! I forgot to add the gray stripes. You need to create a BeforeCellPaint event, like this:
Code:

procedure TForm1.VSTBeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
var
  c1, c2: TColor;
begin
  if (Node <> Sender.FocusedNode) then
  begin
    GetColors((Sender as TVirtualStringTree).Canvas.Brush.Color, 8, c1, c2);
    if Node.Index mod 2 = 0 then
      TargetCanvas.Brush.Color := c1
    else
      TargetCanvas.Brush.Color := c2;
    TargetCanvas.FillRect(CellRect);
  end;
end;

Here you go:
http://i1270.photobucket.com/albums/...olbasz/VST.png

DavidB3 12-04-2015 05:28 AM

1 Attachment(s)
The problem is that I keep getting this message after I enabled show images in header.
If I click on yes, it doesn't ask anymore but it doesn't show images in list (only in header).
So I have to click on No every time I save the project.


Yes, the idea of using png instead of icons is good. Unfortunately, I tried with TListView and had problems (images too faded, grayed, lost transparency and/or lost color bit depth).
I will try with this component too, maybe it will work...

kolbasz 12-04-2015 05:42 AM

Don't worry! That's not a problem at all, you have slightly different version of VST, so an extra parameter(procedure GetImageIndex) was added, removed or renamed. The solution is to delete the procedure's body and declaration and recreate it again with your version, then paste only the content from my example:

Code:

procedure TForm1.VSTGetImageIndex(new params....)
var
  Data: PData;
begin
  Data := VST.GetNodeData(Node);
  case Column of
    0: ImageIndex := Data.FImageIndex1;
    4: IMageIndex := Data.FImageIndex2;
  end;
end;


DavidB3 12-04-2015 07:04 AM

Yes, that solved the problem, thanks.
Thought it was in the component code but it was way simpler xD

But now comes the hard part :D
I see that TVirtualStringTree's functions are different from TListView's functions.
For example, don't laugh :), I search now the equivalent of ListView.ItemIndex. I read several Google finds without luck...
The idea is to know you have a selected row and later access the data to read/write/delete.

LE: found how to get the selected row but not how to find its index in 0 .. rowcount - 1

kolbasz 12-04-2015 07:23 AM

Quote:

For example, don't laugh :), I search now the equivalent of ListView.ItemIndex. I read several Google finds without luck...
It take some time to get use to it, but after that you don't want to touch TListView again :)

Code:

var
  Node: PVirtualNode;
  Data: PData;
begin
  Node := VST.GetFirstSelected;
  if Node <> nil then
  begin
    //since MultiSelect is not enabled, there is only one Node
    Data := VST.GetNodeData(Node);
    //Do something with Data   
  end;
end;

One more thing, I forget to free the nodes...To prevent memory leaks you should add the following to your code(OnFreeNode):
Code:

procedure TForm1.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  Data: PData;
begin
  Data := Sender.GetNodeData(Node);
  Finalize(Data^);
end;

PS: There is a Node.Index property:
Code:

Node := VST.GetFirstSelected;
 if Node <> nil then
  ShowMessage(IntToStr(Node.Index));


DavidB3 12-04-2015 08:54 AM

Ok, thanks.

Another thing:

I see that you used this to add a row:

Code:

type
  PData = ^TData;

  TData = record
      FId: Integer;
      FName, FVName, FFirstDrive, FSecondDrive: String;
      FImageIndex1, FImageIndex2: Integer;
  end;

But most of the times a column or more are deleted. So when you assign a variable of this type to the node data, I don't think it will be too "happy" about the extra data.
I can declare types for all combinations of deleted columns and use the appropriate one but it's not so professional.
Is there a "dynamic" approach?

kolbasz 12-04-2015 09:12 AM

Quote:

But most of the times a column or more are deleted. So when you assign a variable of this type to the node data, I don't think it will be too "happy" about the extra data.
I can declare types for all combinations of deleted columns and use the appropriate one but it's not so professional.
Are you planning to delete columns? I wasn't aware of that! Strongly suggest to hide it, instead of delete it, so the data structure can be preserved.
If you are referring to delete a row, that's not a problem at all...After VST.DeleteNode, OnFreeNode procedure is automatically triggered, and the node(s) are freed. You can check this by putting a break point to OnFreeNode.
Generally speaking the node's data is a pointer, so it can point to anything(TOjbect, TClass). It's perfectly safe with one condition, to free the data it points to on FreeNode event. In this particular case I have chosen a record because it's more easier to work with.

DavidB3 12-04-2015 09:33 AM

In the app if you right click on header a popup menu will show and you can choose which column you want to show or hide.
I wasn't implemented this in the test app because it was suppose to be very simple...
Btw, there are many other things I haven't implemented :D

In ListView I chose to delete the column(s). That's because the current hiding method is not very good (setting Width to 0). Is there a better one in TVirtualStringTree?
Beside the data structure is not stored in ListView/VirtualStringTree but in an array of record (VMEntries).
This data is used internally, the other is just for "show" :D
I sync them by using values for the columns tags. So, if I delete a column, I still know what kind are the next ones from their tag values.

kolbasz 12-04-2015 09:44 AM

Quote:

That's because the current hiding method is not very good (setting Width to 0)
This is funny way to hide a column :), but I guess there is no other solution(TListView).
To truly hide the column(VST):
Code:

VST.Header.Columns[3].Options := VST.Header.Columns[3].Options - [coVisible];
To add a column:
Code:

var
  VirtualTreeColumn: TVirtualTreeColumn;
begin
  VirtualTreeColumn := VST.Header.Columns.Add;
end;

Quote:

This data is used internally, the other is just for "show" :D
I sync them by using values for the columns tags. So, if I delete a column, I still know what kind are the next ones from their tag values.
No need to sync under VST, all the data is available in the internal structure, you can get rid of VMEntries.


All times are GMT. The time now is 08:37 AM.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.