Форум: "Основная";
Текущий архив: 2002.03.28;
Скачать: [xml.tar.bz2];
ВнизКак однозначно проверить, существует ли объект (создан ли, не испорчен ли)? Найти похожие ветки
← →
lipskiy (2002-03-16 20:38) [13]2 bad-md
> А где у вас "AV"-то выскакивает?
К сожалению, очень сложно объяснить. Но попробую привести свой код без лишнего. Если кому не в лом будет разобраться и указать на явную глупость - буду благодарен.
Я создаю TreeView динамически, и на каждую ноду вешаю рекорд со списком разных параметров, в т.ч. и событий.
Вот описание:
type
PntRec = ^TRec;
TRec = record
FName: String; // обрабатываемый нодой файл
EOnSelect: TTVChangedEvent; // событие по выбору ноды
EOnDeSelect: TTVChangedEvent; // событие по снятию выбора ноды
// и еще список параметров разных типов
end;
var
RecPtr: PntRec;
type
TSTreeView = class (TTreeView)
private
SelNode,PrevNode:TTreeNode; // текущая и предыдущая выделенная нода
.......
procedure Change(Node: TTreeNode); override;
procedure FOnChange(Sender:TObject; Node:TTreeNode);
.......
public
function sAddItem(... см. ниже)
end;
Теперь создаю ветки, примерно так:
function TSTreeView.sAddItem(
Caption: String;
Tree: TTreeNode;
FName: String;
OnSelect: TTVChangedEvent;
OnDeSelect: TTVChangedEvent):TTreeNode;
var
Node:TTreeNode;
begin
New(RecPtr);
RecPtr^.FName:= FName;
RecPtr^.EOnSelect:= OnSelect;
RecPtr^.EOnDeSelect:= OnDeSelect;
Node:= Items.AddObject(Tree, Caption, RecPtr);
Result:= Node;
end;
Дальше вешаю обработчик на открытие ноды.
Для некоторых целей прищлось перекрыть метод Change, внутри него пишу примерно следующее:
procedure TSTreeView.Change(Node: TTreeNode);
begin
//... некоторые проверки
if Node = nil then exit;
if Node.Data = nil then exit;
FOnChange(Self,Node); // вызываю основной обработчик
//... некоторые проверки
inherited Change(Node);
end;
И, наконец, основной обработчик, в котором и происходит AV:
procedure TSTreeView.FOnChange(Sender:TObject; Node:TTreeNode);
// вложенная процедурка обработки ноды
procedure ServiceNode(Node:TTreeNode);
begin
PrevNode:= SelNode; // запоминаем в буфер предыдущей ноды
SelNode:= Node; // запоминаем в буфер текущей ноды
// далее производятся некотрые неопасные действия с Node:
// (меняю цвет шрифта, выделения, обновляю историю переходов)
end;
begin
// если на ноду не назначено обработчика - ничего с ней не делаем
if not Assigned(PntRec(Node.Data)^.EOnSelect) then exit;
// если повторно кликнули по той же ноде - тоже не обрабатываем
if Node = SelNode then exit;
ServiceNode(Node); // сменились SelNode и PrevNode
if PrevNode <> nil then
if PrevNode.Data <> nil then
if Assigned(PntRec(PrevNode.Data)^.EOnDeSelect) then // << ЗДЕСЬ AV !!!
PntRec(PrevNode.Data)^.EOnDeSelect(Sender,PrevNode);
PntRec(SelNode.Data)^.EOnSelect(Sender,SelNode);
end;
Важное замечание: Ошибка нестабильная, чаще всего не происходит. И останов происходит не всегда на указанной строчке, иногда немного дальше - после выхода из FOnChange, но еще до выхода из Change.
Заметил еще, что ошибка происходит, когда бегаю по нескольким нодам мышкой подряд. Причем ошибка вылетает через интервал времени задержки выбора ноды (свойство ChangeDelay). Если я ChangeDelay устанавливаю в ноль, то ошибка не возникает или возникает значительно реже.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.03.28;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.009 c