При работе с компонентом TVirtualStringTree в Delphi может возникнуть ошибка доступа при попытке модифицировать текст узлов. Одна из таких ошибок связана с функцией GetNodeCode, созданной для генерации кода узла в формате "Код + Текст". Давайте рассмотрим, как устранить эту ошибку.
Описание проблемы
Автор вопроса создал функцию GetNodeCode, цель которой - генерировать код узла в формате "Код + Текст". Однако при выполнении кода происходит ошибка доступа (access violation) на линии if RootNod.Index = 0 then. Несмотря на то, что RootNod присвоено значение, данные этого объекта недоступны.
Код функции GetNodeCode
function GetNodeCode(Tree: TVirtualStringTree; SelectedNode: PVirtualNode): String;
var
RootNod, TestNode: PVirtualNode;
Code: String;
i, count: integer;
begin
RootNod := SelectedNode;
Result := '';
Count := 0;
if Assigned(RootNod) then
begin
TestNode := Tree.AddChild(RootNod);
RootNod := TestNode;
while Assigned(RootNod) do
begin
if RootNod.Index = 0 then
Result := '1' + Result
else
Result := IntToStr(RootNod.Index + 1) + Result;
RootNod := RootNod.Parent;
end;
Tree.DeleteNode(TestNode);
end
else
begin
RootNod := Tree.GetFirst;
while Assigned(RootNod) do
begin
if not Assigned(RootNod.Parent) then
Count := Count + 1;
Result := IntToStr(Count + 1);
RootNod := Tree.GetNext(RootNod);
end;
end;
end;
Причина ошибки
Ошибка возникает из-за того, что автор функции присваивает новое значение RootNod на линии RootNod := RootNod.Parent;. Для корневого узла дерева его родительский узел равен самому дереву, а не PVirtualNode, что и вызывает ошибку доступа.
Альтернативный ответ
Автор вопроса пытался решить проблему, добавив условие if not Assigned(RootNod.Parent) then Exit;, но ошибка все равно возникала. Также было предложено попробовать отключить оптимизацию и проверить другой ответ на StackOverflow.
Подтвержденный ответ
Чтобы исправить ошибку, вместо RootNod.Parent следует использовать Tree.NodeParent[RootNod]. Для корневого узла дерева его родительский узел равен самому дереву, а не PVirtualNode, поэтому использование Tree.NodeParent[RootNod] гарантирует доступ к правильному родительскому узлу.
Пример исправленной функции GetNodeCode
function GetNodeCode(Tree: TVirtualStringTree; SelectedNode: PVirtualNode): String;
var
RootNod, TestNode: PVirtualNode;
Code: String;
i, count: integer;
begin
RootNod := SelectedNode;
Result := '';
Count := 0;
if Assigned(RootNod) then
begin
TestNode := Tree.AddChild(RootNod);
RootNod := TestNode;
while Assigned(RootNod) do
begin
if RootNod.Index = 0 then
Result := '1' + Result
else
Result := IntToStr(RootNod.Index + 1) + Result;
RootNod := Tree.NodeParent[RootNod];
end;
Tree.DeleteNode(TestNode);
end
else
begin
RootNod := Tree.GetFirst;
while Assigned(RootNod) do
begin
if not Assigned(RootNod.Parent) then
Count := Count + 1;
Result := IntToStr(Count + 1);
RootNod := Tree.GetNext(RootNod);
end;
end;
end;
Теперь функция GetNodeCode должна работать правильно, без ошибок доступа.
Вопрос и ответ о решении ошибки доступа при модификации текста в узлах TVirtualStringTree в Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.