Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:
В ПОИСКАХ ИСТИНЫ 

Q. Есть приложение на базе диалога. По некоторым причинам необходимо уже внутрь этого диалога вставить закладки (страницы свойств, как хотите). Все это нормально делается и проблем тут не возникает. Но вот при использовании клавиши Tab для прогулки по диалогу фокус с последнего контрола, не принадлежащего Property Page, перемещается не на закладку страницы, а на ее первый определенный в Tab Layout контрол, и только после пробегания по всем элементам Property Page попадает на закладку. Как это вылечить?

George Orlov 

Это

все на сегодня. Счастливо! 

Алекс Jenter [email protected] Красноярск, 2001.

Программирование на Visual C++

Выпуск №39 от 1 апреля 2001 г.

Добрый день, уважаемые подписчики! С праздником вас!

СТАТЬЯ

Диагностические средства MFC

Автор: Олег Быков 

Библиотека MFC предоставляет программисту мощный набор средств для отладки приложений любой сложности. Данная статья ставит своей целью последовательное рассмотрение диагностических средств для помощи начинающим MFC-программистам в выборе и более полном их использовании.

Разработка коммерческих приложений всегда подразумевает написание стабильно работающих систем, и, как следствие, наличие в коде тотальной проверки всего на свете – входных параметров функций, возвращенных значений, полученных указателей и т.д. Но за стабильность приходится платить замедлением работы программы. MFC предлагает следующий подход к проблеме: разработчик вставляет в код набор диагностических макроопределений, которые при невыполнении заданных условий сообщают имя исходного файла с ошибкой, номер строки, и останавливают работу программы. При этом данные макроопределения выполняются только при отладочной сборке проекта (Debug build).

Иными словами, в код помещаются проверки, которые выполняются только в отладочной версии программы, и не включаются в код при окончательной сборке (Release build). За время работы с отладочной версией программы (в идеале) выясняются и устраняются все возможные ошибочные ситуации и надобность в замедляющих работу проверках отпадает (здесь не имеются в виду ошибки, на которые программа должна реагировать определенными действиями. В частности, не стоит проверять таким образом результаты работы API-функций, так как нельзя гарантировать корректность возвращаемых ими значений и в отладочной сборке, и в окончательной). Чтобы стало понятней, рассмотрим несколько диагностических макроопределений.

ASSERT и VERIFY

ASSERT – пожалуй, один из самых часто употребляемых макросов. Принимая в качестве аргумента булево значение, ASSERT продолжает работу программы, если это значение равно TRUE, и прерывает работу программы в ином случае. При этом ASSERT выводит информационное окно с именем исходного файла и номером строки, содержащей сработавший макрос, и предоставляет разработчику выбор – окончательно прервать работу программы (Abort), переключиться в окно отладчика (Retry) или продолжить работу (Ignore).

В качестве примера использования ASSERT можно привести проверку входного значения функции:

void CPerson::SetPersonAge(int nAge) {

 ASSERT((nAge>=0) && (nAge<200)); //
сработает при любых x, меньших 0

 m_nAge = x; // или больших 199

}

При срабатывании макроса (то есть, при передаче неверного nAge) у разработчика есть возможность переключиться в окно отладчика и через список вызовов (Call Stack) определить, откуда был передан ошибочный параметр.

ПРИМЕЧАНИЕ

ASSERT развернется в код только при Debug-сборке. Чтобы обеспечить вычисление параметра и в окончательной версии проекта (в случае, когда в ASSERT вызывается нужная функция), используйте макроопределение VERIFY. При Debug-сборке этот макрос полностью идентичен ASSERT, но, в отличие от него, при Release-сборке VERIFY разворачивается в код и вычисляет значение своего аргумента, хотя при этом никак не влияет на ход выполнения программы.

В MFC определен вспомогательный макрос DEBUG_ONLY, который служит для обеспечения выполнения своего параметра только при Debug-сборке. В Release-версии приложения выражение внутри DEBUG_ONLY будет проигнорировано.

ASSERT_KINDOF и ASSERT_VALID

Эти макросы предназначены для диагностики состояния объектов. ASSERT_KINDOF принимает два параметра — имя класса и указатель на объект - и срабатывает (прерывая выполнение программы подобно ASSERT) в случае, когда объект, переданный по указателю, не является объектом данного класса или одного из потомков данного класса. Пример использования макроса:

CPerson::CPerson(CPerson &newPerson) {

 ASSERT_KINDOF(CPerson, &newPerson); // сработает, если в конструктор

// был передан объект не того класса

}

ASSERT_KINDOF полностью идентичен следующей конструкции (для нашего примера):

ASSERT(newPerson.IsKindOf(RUNTIME_CLASS(CPerson)));

Для того, чтобы получить информацию о классе в процессе исполнения, этот класс должен быть унаследован от CObject (или одного из его потомков), и для него должны быть использованы макросы DECLARE_DYNAMIC(classname) и IMPLEMENT_DYNAMIC(classname, baseclass) (иначе обращение к ASSERT_KINDOF приведет к ошибке нарушения защиты). Это относится и к проверяемому объекту, и к классу.

ASSERT_VALID служит для проверки внутреннего состояния объектов. Этот макрос принимает один параметр – указатель на проверяемый объект – и проделывает с ним следующее: проверяет валидность указателя, проверяет его на равенство NULL, и вызывает функцию объекта AssertValid.

AssertValid реализована почти во всех классах MFC (унаследованных от CObject), но разработчик может реализовать ее и в своем классе, соблюдая определенные правила. Во-первых, AssertValid должна быть переопределенной виртуальной функцией класса CObject. Эта функция описана как const, поэтому внутри нее нельзя изменять данные класса. Во-вторых, для индикации факта невалидности объекта функция должна использовать макрос ASSERT. И в-третьих, в AssertValid желательно вызвать эту же функцию класса-родителя.

Поделиться:
Популярные книги

Часовая башня

Щерба Наталья Васильевна
3. Часодеи
Фантастика:
фэнтези
9.43
рейтинг книги
Часовая башня

Попаданка в Измену или замуж за дракона

Жарова Анита
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Попаданка в Измену или замуж за дракона

На границе империй. Том 9. Часть 3

INDIGO
16. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 3

Жена на пробу, или Хозяйка проклятого замка

Васина Илана
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Жена на пробу, или Хозяйка проклятого замка

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство

Восход. Солнцев. Книга I

Скабер Артемий
1. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга I

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Надуй щеки!

Вишневский Сергей Викторович
1. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки!

Случайная свадьба (+ Бонус)

Тоцка Тала
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Случайная свадьба (+ Бонус)

Газлайтер. Том 5

Володин Григорий
5. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 5

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Наследник 2

Шимохин Дмитрий
2. Старицкий
Фантастика:
попаданцы
альтернативная история
фэнтези
5.75
рейтинг книги
Наследник 2

Неучтенный. Дилогия

Муравьёв Константин Николаевич
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Неучтенный. Дилогия

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник