Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.02.2013, 14:31   #1
vinc2000
Пользователь
 
Аватар для vinc2000
 
Регистрация: 31.01.2012
Сообщений: 47
По умолчанию Работа с Virtualstringtree

Прива всем! Пишу модульный медиа-центр в оболочке explorer'a на основе VT 5.1, на днях столкнулся с проблемой правильной очистки дерева.
Код:
type
  PMyNode = ^TMyNode;
  TMyNode = record
  FullPath:UnicodeString;//путь до файла 
  Display: UnicodeString;//название файла без расш.
  FileName:String;//название файла с расш.
end;
Код:
var
Data: PMyNode;
SR: TSearchRec;
Стандартное получение файлов:
Код:
function ScanFolder(Folder:String):String;
begin
if Folder[Length(Folder)] <> '\' then Folder := Folder + '\'; //при access violation ссылается на эту строчку
  if FindFirst(Folder + '*.*', faAnyFile, SR) = 0 then
  VT1.NodeDataSize := Sizeof(TMyNode);
  begin
    try
      repeat
        if (sr.Name='.') or (sr.Name='..') then continue;
         if (SR.Attr=faDirectory)  then continue;

            Node := VT1.AddChild(nil);
            Data := VT1.GetNodeData(node);

            if Assigned(Data) then
              with Data^ do
                begin
                    Data^.FileName:=SR.Name;
                end;
            until
          FindNext(SR) <> 0;
      finally
        end;
    FindClose(SR);
 end;
end;
И вызов:
Код:
VT1.Clear;//очищать то надо как-то
ScanFolder(Data^.FullPath);
Перекроил весь код проекта, но ошибка либо в функции либо в компоненте VT. Кто-то говорил что надо в цикле освобождать память (Finalize) и clear делать нельзя - как тогда очищать дерево? Код прекрасно работает с Treeview, в VT же ошибки: acces violation. Если не очищать дерево - out of system resources. Немного запутался
Изображения
Тип файла: jpg 2013-02-02_121914.jpg (36.0 Кб, 146 просмотров)
Мне осталась одна забава - пальцы в рот, да веселый свист - прокатилась дурная слава, что похабник я, и скандалист.
vinc2000 вне форума Ответить с цитированием
Старый 02.02.2013, 15:42   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Ну у вас несколько ошибок здесь.
1. NodeDataSize надо определять в событии OnGetNodeDataSize или при создании формы.
2. Вы создаете ветви но не присваиваете им данные.
3. Вместо Record'ов я бы использовал обьекты.
Было бы нечто такое:
Код:
            myObject:=TMyObject.Create(Data1,Data2,...);
            Node := VT1.AddChild(nil,myObject);
            Data := VT1.GetNodeData(node);
в OnNodeFree можно освобождать Node.Data от содержимого.

P.S. Может у вас получиться что-то новое узнать из моего опыта Ссылка 1 и ссылка 2
В особенности обращайте внимание на сообщения Spamer'а.
Человек_Борща вне форума Ответить с цитированием
Старый 02.02.2013, 16:49   #3
vinc2000
Пользователь
 
Аватар для vinc2000
 
Регистрация: 31.01.2012
Сообщений: 47
По умолчанию Работа с Virtualstringtree

Спасибо за ссылки! Буду разбираться!

На самом деле:
1. В онкрейте и определяется, вынес чтобы не решили что я забыл.
2. Про данные - далее...
3. Объекты не пробовал - потестим.

Мое освобождение (думаю верно):
Код:
  Data := VT1.GetNodeData(Node);
  Data.Image.Free;
  Finalize(Data^);
Присвоение у меня вроде как в целтексте VT1 (или я что-то путаю?):
Код:
procedure TForm1.VT1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
begin
  Data := VT1.GetNodeData(Node);
    case Column of
    0: CellText := ExtractFileName(GetFileNameWOExt(Data^.FileName));
  end;
end;
Мне осталась одна забава - пальцы в рот, да веселый свист - прокатилась дурная слава, что похабник я, и скандалист.
vinc2000 вне форума Ответить с цитированием
Старый 02.02.2013, 17:42   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Присвоение у меня вроде как в целтексте VT1 (или я что-то путаю?):
VT должен ещё до этого знать размер данных. Где присваивать его я написал.

Цитата:
Мое освобождение (думаю верно):
Думаю да. Но я с записями никогда не работал.
Человек_Борща вне форума Ответить с цитированием
Старый 03.02.2013, 13:55   #5
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Вообще говоря против использования записей здесь вообще ничего не имею, ибо так сам Создатель повелел. Далее
Код:
var
Data: PMyNode;
......................
   Data.Image.Free;
При том, что
Код:
 TMyNode = record
  FullPath:UnicodeString;//путь до файла 
  Display: UnicodeString;//название файла без расш.
  FileName:String;//название файла с расш.
end;
Я что-то проглядел? Честно говоря даже теряюсь, что тут можно посоветовать. Видимо только Человек_Борща с его нечеловеческими способностями может

Последний раз редактировалось Баламут; 03.02.2013 в 13:59.
Баламут вне форума Ответить с цитированием
Старый 03.02.2013, 14:21   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Хахахах... это где вы у меня не человеческие способности высмотрели?
Я не люблю записи т.к. у меня с ними вечно проблемы. Потому пользуюсь объектами.
Человек_Борща вне форума Ответить с цитированием
Старый 03.02.2013, 18:03   #7
vinc2000
Пользователь
 
Аватар для vinc2000
 
Регистрация: 31.01.2012
Сообщений: 47
По умолчанию Работа с Virtualstringtree

Начал крейтить объекты и перекраивать весь код проекта...оказалось что это пока сверх моего понимания

Еще обнаружилось нечто: при поиске находит не только файлы, но и каталоги, добавляя их в VT, с TreeView / Memo все в порядке. Никто случайно не в теме отчего это? Функция же не вызывает подозрений? Может дело в неверном присваивании все тех же данных?

Код:
function ScanFolder(Folder:String):String;
begin
  if FindFirst(Folder + '*.*', faAnyFile, SR) = 0 then // Если вместо *.* поставить *.mp3 (к примеру)
  begin              //-добавляет в VT правильно, иначе показывает каталоги даже с ExtractFileExt
    try
      repeat
        if (sr.Name='.') or (sr.Name='..') then continue;
         if (SR.Attr=faDirectory)  then continue;
            Data^.FCaption := SlashSep(Folder, SR.Name);
            s := ExtractFileExt(Data^.FCaption);
            if (s='.mp3') or ..... then
               begin
               Node := VT1.AddChild(nil);
               Data := VT1.GetNodeData(node);
               end;
            .....
Мне осталась одна забава - пальцы в рот, да веселый свист - прокатилась дурная слава, что похабник я, и скандалист.

Последний раз редактировалось vinc2000; 04.02.2013 в 11:24. Причина: Доб. код
vinc2000 вне форума Ответить с цитированием
Старый 14.10.2013, 19:18   #8
sorockinalex
Пользователь
 
Регистрация: 10.10.2009
Сообщений: 22
Злость Никак не разберусь с VirtualStringTree

Здравствуйте, никак не могу разобраться с этим компонентом, весь день мучился...
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, VirtualTrees, StdCtrls;

type
  TAttrValue = packed record
          id,
          parentid:Integer;
          param,
          value:string
  end;

  PAttrValue = ^TAttrValue;


type
  TForm1 = class(TForm)
    VST: TVirtualStringTree;
    Button1: TButton;
    Button2: TButton;
    procedure VSTGetNodeDataSize(Sender: TBaseVirtualTree;
      var NodeDataSize: Integer);
    function GetNodeData(const ANode: PVirtualNode): PAttrValue;
    procedure Button1Click(Sender: TObject);
    procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType;
      var CellText: WideString);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;



var
  Form1: TForm1;
  params:array of TAttrValue;

implementation

{$R *.dfm}

procedure TForm1.VSTGetNodeDataSize(
  Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
  NodeDataSize := SizeOf(TAttrValue)
end;

function TForm1.GetNodeData(const ANode: PVirtualNode): PAttrValue;
begin
  result := VST.GetNodeData(Anode);
end;

procedure TForm1.Button1Click(Sender: TObject);
  function FindNode(i:integer):PVirtualNode;
  begin
    Result:=VST.GetFirst;
    while (Result <> nil) do
    begin
      with GetNodeData(Result)^ do
        if id = i then exit;
      Result := VST.GetNext(Result);
    end;
  end;

var
  pNode: PVirtualNode;
  i:Integer;
begin

  //сначала создаём всё в корне, так как параметры при создании могут идти вперемежку
  i:=0;
  while i<Length(params) do
  begin
    pNode:=VST.AddChild(nil, Pointer(params[i].id));
    with GetNodeData(pNode)^ do
    begin
      param := params[i].param;
      value := params[i].value;
    end;
    Inc(i);
  end;
ShowMessage('!');
  //теперь перемещаем подчинённые
  i:=0;
  while i<Length(params) do
  begin
    if params[i].parentid<>0 then FindNode(params[i].id).Parent:=FindNode(params[i].parentid);
    Inc(i);
  end;

end;

procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
begin
  if Column = 0 then
    CellText := GetNodeData(Node).param
  else if Column = 1 then
    CellText := GetNodeData(Node).value
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//записываем данные в массив
SetLength(params,5);
params[0].id:=1;
params[0].parentid:=0;
params[0].param:='Пра-Прадедушка';
params[0].value:='Алексей';

params[1].id:=2;
params[1].parentid:=1;
params[1].param:='Прадедушка';
params[1].value:='Николай';

params[2].id:=3;
params[2].parentid:=2;
params[2].param:='Дедушка';
params[2].value:='Виктор';

params[3].id:=4;
params[3].parentid:=3;
params[3].param:='Папа';
params[3].value:='Владислав';

params[4].id:=5;
params[4].parentid:=4;
params[4].param:='Я';
params[4].value:='Алексей';

end;

end.
Перемещение веток не работает как задумано, почему-то образуется куча дубликатов!

Не сворачивается после разворачивания дерево!

Как добавить иконки + в дерево?


И ещё, как копировать из делфи, чтобы кодировка на русском была при вставке в форум??
sorockinalex вне форума Ответить с цитированием
Старый 14.10.2013, 19:22   #9
sorockinalex
Пользователь
 
Регистрация: 10.10.2009
Сообщений: 22
По умолчанию

Вот как загружается

http://pixs.ru/showimage/1png_9767740_9376163.png
При клике на дерево:

http://pixs.ru/showimage/2png_1687435_9376170.png

Последний раз редактировалось sorockinalex; 14.10.2013 в 19:23. Причина: Не работают теги IMG
sorockinalex вне форума Ответить с цитированием
Старый 14.10.2013, 19:48   #10
sorockinalex
Пользователь
 
Регистрация: 10.10.2009
Сообщений: 22
По умолчанию

ха-ха, ну с перемещением частично разобрался:
Код:
    if params[i].parentid<>0 then VST.MoveTo(FindNode(params[i].id), FindNode(params[i].parentid),amInsertAfter, False );
sorockinalex вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
virtualstringtree shturman1387 Компоненты Delphi 2 20.12.2012 20:34
Передача данных в VirtualStringTree в цикле The SCS Компоненты Delphi 0 16.04.2012 15:50
VirtualStringTree - добавление данных The SCS Компоненты Delphi 1 14.04.2012 07:53
Обновление VirtualStringTree по таймеру woofer Помощь студентам 1 22.05.2010 02:55
VirtualStringTree чужого окна akaTemporary Общие вопросы Delphi 0 29.01.2010 14:32