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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.04.2013, 22:08   #1
noname_06
Пользователь
 
Регистрация: 18.01.2009
Сообщений: 49
По умолчанию Ошибки access violation c TreeView

Изучаю компонент TreeView.

Требования к программе:
В TreeView из файла загружается список категорий и сайтов, по клику в memo выводится индекс выбранного элемента + имя сайта + ссылка. Для категории ссылка = '*'. Может создавать/удалять категории и пункты. Сохраняет обратно в файл.
Ссылки хранятся в динамическом массиве, из которого выбираются по индексу выделенного узла TreeView.

Проблемы:
1) Периодически access violation при добавлении группы или пункта.
2) То же самое (всегда) при выходе из программы, хотя настройки сохраняет.
3) Правильно ли описана процедура удаления записей из TreeView+массива и расстановка ссылок с новыми индексами?
4) Периодически в файл сохраняет "лишние" записи

Чую снова с pointer'ами где-то не угадал, но пока не пойму где и что.

Добавляю группу:
Код:
procedure TForm1.btn1Click(Sender: TObject);  //add group
var
  node: TTreeNode;
  i: Integer;
begin
  node:=TreeView1.Items.Add(nil, InputBox('Новая группа','Введите имя','Group'));                      //создал раздел
  SetLength(da_links, Length(da_links)+1);                        //удлинил массив на 1
  if counter>1 then                                               //если длинне 1 элемента, то сместить к концу
  for i:=TreeView1.Items.Count downto node.AbsoluteIndex do       //от конца до нового элемента                 {было -1}
    da_links[i]:=da_links[i-1];                                   //сместить вперед на 1
  da_links[node.AbsoluteIndex]:='*';                              //в массив записать *
  node.data:=PChar(da_links[node.AbsoluteIndex]);                 //связать data с элементом массива
  lbl1.caption:=node.text;                                        //проверка-перестраховка
  lbl2.caption:=string(node.data);                                //проверка-перестраховка
end;
Добавляю пункт:
Код:
procedure TForm1.btn5Click(Sender: TObject);  //Добавить подчиненный пункт
var
  node: TTreeNode;
  i: Integer;
begin
  if TreeView1.Selected.Parent<>nil then ShowMessage('Не выбрана группа') else
  begin
    node:=TreeView1.Items.AddChild(TreeView1.Selected, edt1.Text);
    SetLength(da_links, Length(da_links)+1);                        //удлинил массив на 1
    for i:=TreeView1.Items.Count-1 downto node.AbsoluteIndex do     //от конца до нового элемента
      da_links[i]:=da_links[i-1];                                   //сместить вперед на 1
    da_links[node.AbsoluteIndex]:=edt2.Text;                        //в массив записать *
    node.data:=PChar(da_links[node.AbsoluteIndex]);
    lbl1.caption:=node.text;                                        //проверка-перестраховка
    lbl2.caption:=string(node.data);                                //проверка-перестраховка
  end;
end;
end;
Сохраняю настройки:
Код:
procedure TForm1.FormDestroy(Sender: TObject);
var F:TIniFile;
    i, counter:Integer;
    node: TTreeNode;
begin
  if FileExists('links.ldb') then                                                         //удалить файл настроек
  if not (DeleteFile('links.ldb')) then                                                   //а стоит ли?
  ShowMessage('Не могу перезаписать настройки');
  F:= TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'links.ldb');                        //создать файл с новыми настройками
  counter:=TreeView1.Items.Count;
  if counter>0 then                                                                       //если TreeView1 не пустой
  begin
    try
      F.WriteString('config', 'count', IntToStr(counter));                                //сохраняем кол-во элементов
      for i:=0 to counter-1 do
      begin
        node:=TreeView1.Items.Item[i];
        F.WriteString('names', 'name_'+IntToStr(i), node.text);                           //сохраняем имя узла
        F.WriteString('links', 'link_'+IntToStr(i), da_links[i]);                         //сохраняем ссылку или '*' для корневых ухлов
      end;
      F.Free;
    except
      ShowMessage('Не могу заполнить links.ldb');
    end;
  end
  else
  F.WriteString('config', 'count', '0');                                                  //если в списке пусто - пишем 0
  F.Free;
end;
Вложения
Тип файла: rar test.rar (14.1 Кб, 11 просмотров)
noname_06 вне форума Ответить с цитированием
Старый 02.04.2013, 22:29   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

Да будет вам известно о TList, TObjectList и TVirtualStringTree =)


Далее, на сколько помню, при добавлении нити, 2м параметром идет указатель, а вы туда строку пихаете. А если юзер ещё и и ничего не введет, то ваще караул
Наверняка в этом ваша проблема.
И да, вроде бы в TreeView тоже надо указывать сколько NodeData занимает, чтобы правильно дерево в памяти строить, потому 2м параметром 500% должен быть или record или Object, но не динамический массив знаков.
Человек_Борща вне форума Ответить с цитированием
Старый 02.04.2013, 22:44   #3
noname_06
Пользователь
 
Регистрация: 18.01.2009
Сообщений: 49
По умолчанию

Досадно. Про "надо указывать сколько NodeData занимает" - буду знать, спасибо. Посоветуйте, пожалуйста, компонент для визуального представления катерогий и ссылок (ака "закладки" в браузере) что бы можно было быстро производить навигацию по ним.
*До этого с TreeView не сталкивался, про pointer - читал. Так что теперь имею массу полезного опыта

**Если заменить динамический массив на stringgrid, то получим желаемый Object?

Последний раз редактировалось noname_06; 02.04.2013 в 23:27.
noname_06 вне форума Ответить с цитированием
Старый 03.04.2013, 08:10   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

Цитата:
Код:
  SetLength(da_links, Length(da_links)+1);                        //удлинил массив на 1
  if counter>1 then                                               //если длинне 1 элемента, то сместить к концу
  for i:=TreeView1.Items.Count downto node.AbsoluteIndex do       //от конца до нового элемента                 {было -1}
    da_links[i]:=da_links[i-1];                                   //сместить вперед на 1
и воспользуйтесь этим
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 06.04.2013, 03:15   #5
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

Цитата:
Посоветуйте, пожалуйста, компонент для визуального представления катерогий и ссылок (ака "закладки" в браузере) что бы можно было быстро производить навигацию по ним.
так ведь написал жеж
Да будет вам известно о TList, TObjectList и TVirtualStringTree =)
Человек_Борща вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Access violation dimavit Общие вопросы Delphi 3 29.07.2012 19:16
access violation ho_N Компьютерное железо 2 30.11.2011 08:36
Access Violation SunKnight Общие вопросы Delphi 2 05.06.2008 16:46
Access Violation Carbon Общие вопросы Delphi 12 18.09.2007 19:55