Очередная "Загадочная ошибка" ...

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Очередная "Загадочная ошибка" ...

Сообщение sign » 14.07.2017 08:11:44

Alex2013 писал(а):В общем это "неправильные пчелы и они делают неправильный мед" .... :roll: :wink:
2 Ошибка вылезает ВНУТРИ кода VT (и не спрашивайте меня как она вылезла в inputStr )....
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
Node: PVirtualNode;
Data: PLCLTextData;
begin
  With VST3 do
begin
  NodeDataSize := SizeOf(TLCLTextData);
  Node :=  AddChild(nil  );
  Data := GetNodeData(Node);
Data^.T1:=NewStr('Вес в МТ');  Data^.T2:=NewStr('00000');
//ValidateNode(Node, False); // понятия не имею нужна ли это строка но что с ней что без нее.. результат тот-же . :idea:
end;
end;


NodeDataSize := SizeOf(TLCLTextData); - вот так низзя!
Размер устанавливается обязательно в OnGetNodeDataSize.

Код: Выделить всё
OnGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
  NodeDataSize := SizeOf(TLCLTextData);
end;


Суть в том, что VT сам обращается к OnGetNodeDataSize для понимания, каков размер для выделения памяти и оперированием данными.
А у вас там пусто!

Если структура данных чуть более чем немного сложная, то проще использовать классы.
Код: Выделить всё
procedure TDM.LoadPrice(Sender: TBaseVirtualTree);
var D, P: PVirtualNode;
    Data: PPrice;
begin
  if not Assigned(Sender) then Exit;
  Sender.Clear;
  LoadTitle(Sender);
  if Param.Date = 0 then Param.Date := Now;
  InitParam(DM.q_Price, VarArrayOf(['pVisible', Ord(Param.Price_Is_Show), 'pDeleted', Ord(Param.Price_Is_Deleted), 'pDate', Param.Date]), tsOpen);
  while not DM.q_Price.Eof do begin
    D := FindTitleProduct(Sender, DM.q_PriceGroup.AsInteger);
    P := Sender.AddChild(D);
    Data := Sender.GetNodeData(P);
    Data^ := TPrice.Create;
    Data^.Load;
    q_Price.Next;
  end;
  q_Price.Close;
  FocusVirtualST(Sender, FindRecProduct(Sender, Param.RecPrice));
end;

А в описании одной строки прайса куча всякой всячины, в том числе и String. И не нужно мудрить с PString, с выделением памяти и прочим и прочим.
Несомненно, освобождать память нужно самому через OnFreeNode, но это очень просто:

Код: Выделить всё
procedure TfFirms.vsPriceFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var Data: PPrice;
begin
  Data := Sender.GetNodeData(Node);
  if Assigned(Data^) then FreeAndNil(Data^);
end;


Соответственно, OnGetNodeDataSize:
Код: Выделить всё
procedure TfFirms.vsPriceGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
  NodeDataSize := SizeOf(PPrice);
end;

Всё очень просто и легко, если сперва читать документацию, а не наоборот.
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Очередная "Загадочная ошибка" ...

Сообщение olegy123 » 14.07.2017 09:03:51

sign писал(а):NodeDataSize := SizeOf(TLCLTextData); - вот так низзя!
Размер устанавливается обязательно в OnGetNodeDataSize.

Почему нельзя, если он в официальных демках есть?
Можно вообще обойтись без NodeDataSize:
.AddChild(PParentNode,PDataNode);

Добавлено спустя 23 минуты 8 секунд:
Alex2013 писал(а):VT там совсем не причем ... оказалось иначе .

VT - это давно работающий велосипед, а как он едет зависит только от тебя.

Код: Выделить всё
Var S:String; -- [b]уже тут компилятор заложил NewStr/DisposeStr[/b];
    pS:PString; -- это просто указатель, что с ним будешь делать компилятор предугадать не может..
begin
   pS:=NewStr('Строка'); - правильно
   S:=pS^; - правильно..
   DisposeStr(pS); - правильно..
   S:=pS^; - уже не правильно, но результат неопределенный.. но может вернуть 'Строка'.
   DisposeStr(S); - неправильно
end;


NewStr/DisposeStr - это аналог сишного malloc+strcpy/free,
Вообще я не понимаю, почему нужно использовать NewStr/DisposeStr? когда спокойно можно работать с обычным String значением.

TDataNode = record
S1:String;
S2:String;
end;
PDataNode=^TDataNode;

NodeDataSize:=sizeof(TDataNode);
Код: Выделить всё
var
Node: PVirtualNode;
Data: PDataNode;
begin
  Node :=  AddChild(...);
  Data := GetNodeData(Node);
 
  Data^.S1:='.........'
  Data^.S2:='.........'

Компилятор все поймет правильно..
NewStr/DisposeStr - не нужен тут.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Очередная "Загадочная ошибка" ...

Сообщение Alex2013 » 14.07.2017 14:33:27

2sign : Спасибо за "рецепт", попробую ...
olegy123 писал(а):Вообще я не понимаю, почему нужно использовать NewStr/DisposeStr? когда спокойно можно работать с обычным String значением.

"Я вообще ничего не понимаю! "(с)Кеп Смолет :D Уфф.... писал уже... возникает проблема при расширении записи ... т. е. если было "0000" а стало "1001" все Ок а если было "0000" а стало "0000_1111_1111" возникает исключение... с .NewStr/DisposeStr с записи-расширением все Ок

Возможно дело в пока криво подключенном редакторе полей ... Но вроде глючит (при расширении записи ) и с "левой табличкой" .

olegy123 писал(а):VT - это давно работающий велосипед, а как он едет зависит только от тебя.

На любом что велосипеде что мотоцикле нужно научится ездить ... а если простых описаний не обнаружил ( хорошо хоть в вике нашел ... не прошло и года,ага :wink: ) а примеры сделаны в основном чтобы похвастаться "неодолимой мощью" пакета . То процесс может изрядно затянутся .. :idea:
Зы
Новых исследований пока не делал ... обнаружил белую полосу на втором мониторе (по чему-то видимую только под линукс ) :shock: думал сбой системы ... в процессе "разбора полетов" реально его и устроил ... :wink: поднял бекап ... а полоса просто глюком стареющего перегретого LCD-монитора оказалось. ( В лнуксе 75 гц стояло и было видней...) Короче "облом нечаянно нагрянет "... Умфф...
Последний раз редактировалось Alex2013 31.08.2017 17:19:53, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Очередная "Загадочная ошибка" ...

Сообщение olegy123 » 14.07.2017 15:44:10

Alex2013 писал(а):"Я вообще ничего не понимаю! "(с)Кеп Смолет :D Уфф.... писал уже... возникает проблема при расширении записи ... т. е. если было "0000" а стало "1001" все Ок а если было "0000" а стало "0000_1111_1111" возникает исключение... с .NewStr/DisposeStr с записи-расширением все Ок
Тогда я не понимаю.. или лыжи не едут..

.AddChild..; - это добавление нода в таблицу..
Код: Выделить всё
    function AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode; overload; virtual;
    function AddChild(Parent: PVirtualNode; const UserData: IInterface): PVirtualNode; overload;
    function AddChild(Parent: PVirtualNode; const UserData: TObject): PVirtualNode; overload;


если данные где то уже есть, то проще их нпрямую связать без кэшиования.. можно указать [TObject].
Разумеется [TObject] должен жить больше чем сам VST.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Очередная "Загадочная ошибка" ...

Сообщение sign » 15.07.2017 07:27:29

olegy123 писал(а):
sign писал(а):NodeDataSize := SizeOf(TLCLTextData); - вот так низзя!
Размер устанавливается обязательно в OnGetNodeDataSize.

Почему нельзя, если он в официальных демках есть?
Можно вообще обойтись без NodeDataSize:
.AddChild(PParentNode,PDataNode);

Можно и числовые константы в программе цифирками писать.
Но не нужно.
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Пред.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25

Рейтинг@Mail.ru
cron