TreeView странность.
Модератор: Модераторы
>>Вот это неправильно:
Слышал звон и не знал где он. Что тут неправильно?
На этом форуме всё топится во флейме, а непонимающие люди с умным видом порют чушь((
Слышал звон и не знал где он. Что тут неправильно?
На этом форуме всё топится во флейме, а непонимающие люди с умным видом порют чушь((
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
zub писал(а):Цените время форумчан
Убрал, в сообщении выше и в первом сообщении, в самом низу.
Добавлено спустя 5 минут 40 секунд:
vitaly_l писал(а):И покажите, в своём примере, как вы чистите pointer,
А как мне их почистить? Посмотрите, пожалуйста, примеры в сообщении выше.
wofs писал(а):А как мне их почистить? Посмотрите, пожалуйста, примеры в сообщении выше.
Посмотрел, но Вы вернулись к изначальному варианту и опять ничего не создаёте - значит и чистить Вам ничего не надо!
zub писал(а):На этом форуме всё топится во флейме, а непонимающие люди с умным видом порют чушь((
Слышал звон и не знал где он. Что тут неправильно?
Когда он подключал схему с использованием new(), то старая схема - переставала работать, т.к. адрес был уже правильный и не совпадал с адресом из ответа SQL. И поэтому он не мог заполнить дерево, т.к. сравнение всегда возвращало false.
Я так понимаю сейчас всё работает и делает правильно? И автор при этом, ничего не чистит? Верно?
Золотое правило: Если работает - не трогай!
PS: Я в примерах не нашёл использования функции new(), соответственно: постольку, поскольку - Вы ничего не создавали, то и удалять ничего ненужно. Соответственно "самодельная" функция Clear(); лишняя и более того неправильная, т.к. ничего не чистит, разве что data присваивается nil.
.
Последний раз редактировалось vitaly_l 03.09.2017 07:35:38, всего редактировалось 1 раз.
zub писал(а):olegy123 писал(а):wofs писал(а):Просто в коде процедурубуду вызывать через QueueAsyncCallКод: Выделить всё
FillTree();
WTF?
Зачем?
Мултипоточность нужно применять там где это необходимо - иначе решения задачи усложняется в разы.
Вместо правильности кода будете ловить эксепшены в неожиданных местах.
У вас было проблема в утечке памяти. Продолжали работать с зомби классом.
Какая тут мультипоточность? это отложенное выполнение процедуры
Приношу свои извинения. Спутал с операторами в VC++ с многопоточными асинхронными запросами.
Добавлено спустя 10 минут 15 секунд:
zub писал(а):>>Вот это неправильно:
Слышал звон и не знал где он. Что тут неправильно?
На этом форуме всё топится во флейме, а непонимающие люди с умным видом порют чушь((
Нужен модератор, с академическим знанием, с огромным просветительским опытом и званием не ниже действующего члена академии наук СССР. С купленными местами в РФ категорически не брать.
Обязательно, чтобы был фанат одной школы - других люто ненавидел. Только его флейм был "истиной в последней инстанции".
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
vitaly_l писал(а):Я в примерах не нашёл использования функции new(), соответственно: постольку, поскольку - Вы ничего не создавали, то и удалять ничего ненужно.
Изначально так и было.
vitaly_l писал(а):Соответственно "самодельная" функция Clear(); лишняя и более того неправильная, т.к. ничего не чистит, разве что data присваивается nil.
А ее и нет ныне...
vitaly_l писал(а):Я так понимаю сейчас всё работает и делает правильно? И автор при этом, ничего не чистит? Верно?
Золотое правило: Если работает - не трогай!
Правильно, через QueueAsyncCall.
Спасибо всем.
p.s. разве, что в примерах память, выделенную под массив забыл освободить при закрытии приложения.
wofs писал(а):Правильно, через QueueAsyncCall.
Clear(); А ее и нет ныне...
В этом-то весь и секрет. Постольку поскольку, вы уже не используете "самописную" Clear(), значит вы уже не используете и Items[i].Free;, соответственно как выразился Zub - вы уже "не рубите всё дерево на корню", т.к. отсутствует запрос Items[i].Free;.
Тогда зачем Вы запускаете QueueAsyncCall? А?
Функцию, QueueAsyncCall - вам предложили использовать именно из-за Clear() и Items[i].Free; которая в ней.
Но теперь когда их нет, зачем QueueAsyncCall ?
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
vitaly_l писал(а):Но теперь когда их нет, зачем QueueAsyncCall ?
Потому, что я использую
Код: Выделить всё
Items.Clear; //очищаем дерево в процедуре FillTree();
И без QueueAsyncCall я получаю ту же проблему (не ошибку!), из-за которой сюда пришел.
Скажите, какая у вас Ос, я скопмилирую оба проекта под нее и вы посмотрите, наконец, что за проблема.
wofs писал(а):пытаетесь тыкнуть меня носом в мои ошибки
Так вы убрали свою самодельную Clear();? Значит оно всё таки, действительно было лишним?
Значит я, уже - не зря потратил своё время, т.к. кроме Вас это читают и другие. Надеюсь они смогут понять разницу между адресом на глобальную переменную(как в новом примере) и адресом на локальную переменную(как в старом примере). И надеюсь они смогут понять почему адрес данный на локальную переменную - становится зомби адресом, после окончания работы функции, в следствии чего и появляются Ваши "странные" глюки. И такое решение (с помощью костыля в виде QueueAsyncCall, но без понимания сути проблемы ) уже - не приведёт к сбою АЭС или падению самолёта, если они подсмотрят это решение в этом топике.
.
Последний раз редактировалось vitaly_l 03.09.2017 12:53:48, всего редактировалось 1 раз.
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
vitaly_l писал(а):в следствии чего и появляются Ваши "странные" глюки.
Глюки есть и без моих самописных функций очистки.
Добавлено спустя 39 секунд:
Зесь красным "Узел 11" читать как "Узел 7":
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось wofs 03.09.2017 12:55:38, всего редактировалось 2 раза.
wofs писал(а):Глюки есть и без моих самописных функций очистки.
И надеюсь они смогут понять почему адрес данный на локальную переменную - становится зомби адресом. И такое решение (с помощью костыля в виде QueueAsyncCall, но без понимания сути проблемы ) уже - не приведёт к сбою АЭС или падению самолёта, если они подсмотрят это решение в этом топике.
Последний раз редактировалось vitaly_l 03.09.2017 12:58:19, всего редактировалось 1 раз.
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
vitaly_l писал(а):И такое решение (с помощью костыля в виде QueueAsyncCall, но без понимания сути проблемы ) уже - не приведёт к сбою АЭС или падению самолёта, если они подсмотрят это решение в этом топике.
Однако, предложенное вами решение в виде создания своих указателей не заработало и дерево не заполнилось.
wofs писал(а):Однако, предложенное вами решение в виде создания своих указателей не заработало и дерево не заполнилось.
Потому что, помимо исправленного, нужно было ещё и вот это исправить:
Код: Выделить всё
if Tree1.Items.Item[i].Data = Pointer(FieldByName(idParent).asInteger)
и прочитайте уже про pointеr и узнайте: что это такое и чем оно отличается от переменной?
И попробуйте, понять в каких случаях зомби адрес может совпадать с новым адресом и выдаваться такой глюк как у Вас, именно при вышеприведённом запросе: if Tree1.Items.Item[i].Data = Pointer(FieldByName(idParent).asInteger) then...
На этом ликбезу конец.
vangamode := off;
.
Последний раз редактировалось vitaly_l 03.09.2017 13:13:01, всего редактировалось 1 раз.
wofs писал(а):хранит адрес на ячейку памяти
Когда вы сравниваете номер ячейки if Tree1.Items.Item[i].Data = Pointer(FieldByName(idParent).asInteger) then... то сравниваете его с зомби ячейкой, и поэтому при СЛУЧАЙНОМ совпадении номера ячейки - появляется Ваш якобы глюк. Независимо от того что в ячейке лежит. И поэтому выскакивает запись из ячейки, которая была при предыдущих запросах. Постольку поскольку совпадают номера ячеек.
После этого вы создаёте ещё один Pointer(FieldByName(idNode).asInteger)... Который не всегда может равняться тому что при запросе if then, т.к. функция asInteger локальная и может каждый раз - возвращать разное значение номера ячеек, даже если запросы идут подряд.
.
- wofs
- постоялец
- Сообщения: 379
- Зарегистрирован: 05.10.2009 10:16:55
- Откуда: Астрахань
- Контактная информация:
vitaly_l писал(а):Я пробовал переписатьКод: Выделить всё
if Items.Item[iTree].Data = Pointer(integer(dbArr[i + 1, 1])) then
наКод: Выделить всё
PtrToInt2^ := integer(dbArr[i + 1, 1]);
if Items.Item[iTree].Data = PtrToInt2 then
Но получил указатель, который указывает черте куда.
Нашел ошибку!
Добавлено спустя 9 минут 16 секунд:
Функция заполнения теперь выглядит так:
Код: Выделить всё
procedure TForm1.FillTree(); // заполнение дерева
var
i, iTree: integer;
ptrToInt2 : ^Integer;
begin
New(ptrToInt2);
with Tree1 do
begin
BeginUpdate;
Items.Clear; //очищаем дерево
ptrToInt2^ := integer(dbArr[0, 0]);
// node.data := ptrToInt2; // или так @ptrToInt2; - зависит от директивы Zub - писал выше
Items.AddObject(nil, dbArr[0, 2], ptrToInt2);
// добавляем корневой объект
for i := 0 to Length(dbArr) - 2 do // перебираем в цикле
begin
if i = 0 then
Log('iTree= ' + IntToStr(0) + ' Node= ' + string(dbArr[i, 0]) + ' Parent= ' +
string(dbArr[i, 1]) + ' Name= ' + string(dbArr[i, 2]));
iTree := 0;
while iTree < Items.Count do
begin
PtrToInt2^ := integer(dbArr[i + 1, 1]);
if Items.Item[iTree].Data = PtrToInt2 then
begin
Log('iTree= ' + IntToStr(iTree) + ' Node= ' + string(dbArr[i + 1, 0]) +
' Parent= ' + string(dbArr[i + 1, 1]) + ' Name= ' + string(dbArr[i + 1, 2]));
ptrToInt2^ := integer(dbArr[i+1, 0]);
Items.AddChildObject(Items.Item[iTree],
string(dbArr[i + 1, 2]), ptrToInt2); // добавляем дочерние объекты
break;
end;
Inc(iTree);
end;
end;
Items[0].Expand(True);
EndUpdate;
Dispose(ptrToInt2);
end;
end;
Дерево заполняется, но неверно:
Проблема все-таки опять в сравнении:
Код: Выделить всё
PtrToInt2^ := integer(dbArr[i + 1, 1]);
if Items.Item[iTree].Data = PtrToInt2 then
У вас нет необходимых прав для просмотра вложений в этом сообщении.
