Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как поймать "Access violation"

9.5K
20 января 2007 года
Borgir
97 / / 20.12.2006
День добрый, мастера!

Есть у меня на форме компонент TreeView.
Я в нем на событии OnMouseDown делаю такую вещь:
 
Код:
if(Button==mbRight)
{
    TPoint pp;
    pp.x=X;
    pp.y=Y;
    ::ClientToScreen(Objects->Handle,&pp);
    Objects->Selected=Objects->GetNodeAt(X,Y);
    PopupMenu1->Popup(pp.x,pp.y);
}

Это для того чтоб при щелчке на ноде правой кнопкой сначала выделялась эта нода, а затем показывалось PopUp-меню. (кстати Objects - это просто название TreeView).
Все работает нормально до тех пор пока я не ткну правой кнопкой по пустому месту компонента (мимо ноды то есть). При этом вылетает ошибка "Access violation". и вылетает она на предпоследней строчке, видимо на функции GetNodeAt(X,Y). Подскажите как бы мне избежать этой ошибки или просто перехватить ее (как обычно поступают с исключениями)?
Заранее спасибо.
11K
20 января 2007 года
.nornad
125 / / 04.01.2007
Поставь точку прерывания на начало обработчика и при проходе по шагам смотри, что у тебя в NULL.

Добавлено: извини, сразу не всё внимательно прочёл. Посмотри, что возвращает GetNodeAt и какие ей даются X/Y.
1
20 января 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Borgir
День добрый, мастера!

Есть у меня на форме компонент TreeView.
Я в нем на событии OnMouseDown делаю такую вещь:
 
Код:
if(Button==mbRight)
{
    TPoint pp;
    pp.x=X;
    pp.y=Y;
    ::ClientToScreen(Objects->Handle,&pp);
    Objects->Selected=Objects->GetNodeAt(X,Y);
    PopupMenu1->Popup(pp.x,pp.y);
}

Это для того чтоб при щелчке на ноде правой кнопкой сначала выделялась эта нода, а затем показывалось PopUp-меню. (кстати Objects - это просто название TreeView).
Все работает нормально до тех пор пока я не ткну правой кнопкой по пустому месту компонента (мимо ноды то есть). При этом вылетает ошибка "Access violation". и вылетает она на предпоследней строчке, видимо на функции GetNodeAt(X,Y). Подскажите как бы мне избежать этой ошибки или просто перехватить ее (как обычно поступают с исключениями)?
Заранее спасибо.


Добавь вначале своего кода:

 
Код:
if(!Objects->ItemIndex) return;


.nornad
Достойный ответ. Если нод не выбран - функция генерирует исключение.
9.5K
20 января 2007 года
Borgir
97 / / 20.12.2006
Дело в том, что исключение не генерируется (иначе вообще этого вопроса не было бы), а генерируется ошибка. Поэтому я никак не могу посмотреть, что возвращает GetNodeAt.
А по поводу
 
Код:
if(!Objects->ItemIndex)return;

То дело в том что ItemIndex в начале кода наверняка какой-то определенный. Он должен поменяться как раз за счет вызова функции GetNodeAt.
Надо каким-то образом до вызова этой функции проверять эти координаты.
1
20 января 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Borgir
Дело в том, что исключение не генерируется (иначе вообще этого вопроса не было бы), а генерируется ошибка. Поэтому я никак не могу посмотреть, что возвращает GetNodeAt.
А по поводу
 
Код:
if(!Objects->ItemIndex)return;

То дело в том что ItemIndex в начале кода наверняка какой-то определенный. Он должен поменяться как раз за счет вызова функции GetNodeAt.
Надо каким-то образом до вызова этой функции проверять эти координаты.


А самому проверить - не никак?
Вопервых я ошибся - свойство ItemIndex у компонента отсутствует.
Что бы проверить что не один узел не выбран необходимо проверять Selected на равенство NULL. Во вторых функция возвращает опять же нулл если не один узел не выбран - но при этом никакой ошибки не возникает. Т.е. ошибка у тебя гдето дальше скорее всего ты пытаешься обрабатывать полученный узел - например так:

 
Код:
TMenuItem *NewItem = new TMenuItem(PopupMenu1);
        PopupMenu1->Items->Add(NewItem);
        NewItem->Caption = "Menu Item " + Objects->Selected->Text;

Ошибка доступа при этом гарантирована, если валидность указателя не проверяется - или не перехватывается исключение
11K
21 января 2007 года
.nornad
125 / / 04.01.2007
Попробовал воспроизвести указанную проблему. Не вышло. Код работает нормально, а вот проблемы нет. Из этого могу сделать вывод, что либо перед приведённым участком кода стоит что-то, что всё портит, либо Objects вообще другой компонент, который предполагалось создавать динамически, но никто его не создал.
Есть ещё третий вариант. Иногда билдер мажет мимо строки, на которой падает. Редко, но бывает. В данном случае могло бы падать на пусто PopupMenu1, например...
1
21 января 2007 года
kot_
7.3K / / 20.01.2000
Цитата: .nornad
Попробовал воспроизвести указанную проблему. Не вышло. Код работает нормально, а вот проблемы нет. Из этого могу сделать вывод, что либо перед приведённым участком кода стоит что-то, что всё портит, либо Objects вообще другой компонент, который предполагалось создавать динамически, но никто его не создал.
Есть ещё третий вариант. Иногда билдер мажет мимо строки, на которой падает. Редко, но бывает. В данном случае могло бы падать на пусто PopupMenu1, например...


На пустом меню тоже не падает - как уже сказал выше - скорей всего в последствии пытается обратиться к полученному узлу. В этом случае ошибка возникает.

9.5K
21 января 2007 года
Borgir
97 / / 20.12.2006
Спасибо за советы, буду смотреть. Хотя при пошаговом выполнении ошибка выскакивала именно на этой строке.

------
Вобщем проблема решена, и все намного проще чем мы думали. Я добавил в код проверку
 
Код:
if(Objects->GetNodeAt(X,Y)!=NULL)

и все заработало. Насколько я понял проблема все таки была в этой строчке:
 
Код:
Objects->Selected=Objects->GetNodeAt(X,Y);

Ведь если тыкаешь мышкой на пустом месте, то GetNodeAt возвращает NULL, и мы при этом пытаемся присвоить свойству Selected значение NULL. Видимо это и вызывает ошибку.

P.S. kot_ что-то тебе плюсик не ставится. Говорит что надо поставить плюсик кому-нибудь еще сначала, хотя я поставил перед этим плюсик .nornad
11K
21 января 2007 года
.nornad
125 / / 04.01.2007
Цитата: kot_
На пустом меню тоже не падает - как уже сказал выше - скорей всего в последствии пытается обратиться к полученному узлу. В этом случае ошибка возникает.


Если PopupMenu1 будет NULL, то упадёт. ;)
Я именно это имел в виду, когда предположил, что PopupMenu1 пустой.

1
21 января 2007 года
kot_
7.3K / / 20.01.2000
Цитата: Borgir
Насколько я понял проблема все таки была в этой строчке:
 
Код:
Objects->Selected=Objects->GetNodeAt(X,Y);

Ведь если тыкаешь мышкой на пустом месте, то GetNodeAt возвращает NULL, и мы при этом пытаемся присвоить свойству Selected значение NULL. Видимо это и вызывает ошибку.


Нет никакой ошибки это не вызовет - просто снимется выделение и все. Судя по всему - ты гдето пытаешься обработать выбранный узел, не проверяя его на нулл

Цитата: Borgir

P.S. kot_ что-то тебе плюсик не ставится. Говорит что надо поставить плюсик кому-нибудь еще сначала, хотя я поставил перед этим плюсик .nornad



На форуме установлено ограничение - нельзя добавить репутацию, не добавив предварительно 10 после последнего. Так что не мучайся.

9.5K
21 января 2007 года
Borgir
97 / / 20.12.2006
Нет. Нигде дальше я не обрабатываю узел. После приведенного текста у меня сразу показывается PopupMenu и все. Ошибку вызывает именно эта строка. Да и не суть важно. Главное разобрались как обойти эту проблему.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог