Программирование на Visual C++. Архив рассылки
Шрифт:
В процессе пошаговой отладки программист может использовать целый ряд специальных окон отладчика для наблюдения за состоянием программы. Они описаны в последующих разделах.
Окно Variables
В этом окне автоматически отображаются значения локальных переменных (вкладка Locals), переменных-членов класса, адресуемого указателем this (вкладка This), а также всех переменных, которые используются в предыдущей и текущей строках программы (вкладка Auto). На вкладке Auto также показываются возвращаемые значения функций.
Чтобы изменить значение переменной в окне Variables, достаточно просто два раза кликнуть
Выпадающий список Context позволяет просматривать локальные переменные любой из вызванных в данный момент функций. Кроме того, код выбранной в нём функции отображается в окне редактора.
Вы, вероятно, заметили, что отладчик "умеет" распознавать стандартные структуры данных (CString, RECT и т. п.) и показывать их содержимое в удобном виде. Оказывается, можно не только изменить представление этих структур в окне Variables, но и определить представление для собственных структур. Для этого нужно отредактировать файл autoexp.dat, расположенный в каталоге :\Common\MSDev98\Bin. Описание формата приводится в самом файле.
Окно Watch
Окно Watch позволяет просматривать значения переменных и выражений. Переменные и выражения можно размещать на любой из четырёх вкладок. Добавить переменную или выражение в окно Watch можно одним из следующих способов:
– Ввести с клавиатуры
– Перетащить из окна редактора или из окна Variables
– Добавить из окна Quick watch
Чтобы изменить значение переменной, достаточно два раза кликнуть на старом значении и ввести новое. Значение выражений изменять нельзя.
Чтобы узнать тип переменной или выражения, нужно щёлкнуть по ним правой кнопкой и выбрать Properties из всплывающего меню.
В окне Watch можно наблюдать любые регистры процессора и изменять их значения, хотя это удобнее делать в окне Registers. Можно также использовать регистры в выражениях.
Можно указать отладчику, в каком формате выводить значение переменной/выражения, используя флаги форматирования. Эти флаги добавляются к имени переменной или выражению через запятую. Большинство из них совпадает с символами форматирования функции printf: d – целое число со знаком, u – беззнаковое целое, f – число с плавающей точкой, c – символ, s – строка и т. д. Однако есть четыре флага, на которых я хочу остановиться подробнее.
Флаг wm превращает код сообщения в его название, например:
Флаг wc позволяет стиль окна, например:
Флаг hr переводит коды ошибок Win32 и значения HRESULT, возвращаемые функциями COM, в удобочитаемый вид, например:
Наконец, в Visual C++ есть числовой флаг, который позволяет просмотреть заданное количество элементов массива, адресуемого указателем (по умолчанию показывается всего один элемент). Допустим, мы выделили динамический массив из 10 целых чисел:
Чтобы просмотреть его содержимое в окне Watch, нужно ввести:
Псевдорегистр ERR
Как известно, получить расширенный код ошибки после вызова функций Win32 API можно с помощью GetLastError. Однако расставлять по всей программе вызовы GetLastError
Другие окна отладчика
Окно Registers. Позволяет просматривать и изменять значения регистров процессора.
Окно Memory. Позволяет просматривать и изменять содержимое ячеек памяти.
Окно Call Stack. Показывает последовательность вызванных функций. Используя контекстное меню, можно отобразить также типы и значения параметров этих функций. К тексту любой функции можно переместиться, сделав двойной щелчок на её имени. Обратите внимание, что точки останова можно ставить прямо в этом окне.
Окно Disassembly. Показывает текст отлаживаемой программы на языке ассемблера. Иногда без помощи этого окна ошибку в программе найти не удаётся.
Диалоги
Диалоги отладчика предоставляют вам ряд дополнительных возможностей. Они вызываются из меню Debug.
Quick Watch. Имеет возможности, аналогичные возможностям окна Watch, с той разницей, что в нём можно просматривать только одну переменную за раз. Используется, когда вам не хочется добавлять переменную в окно Watch.
Exceptions. Позволяет настроить реакцию отладчика на возникновение системных и пользовательских исключений.
Threads. Показывает список активных потоков. Позволяет приостановить (suspend) или продолжить (resume) поток, а также установить на него фокус.
Modules. Показывает список загруженных модулей. Для каждого модуля выводится диапазон адресов и имя файла.
Edit and Continue
В заключение хотелось бы упомянуть о новой мощной возможности, которая появилась в Visual C++ 6.0 – Edit and Continue. С её помощью вы можете вносить изменения в код программы и перестраивать её, не прерывая сеанса отладки.
Для этого достаточно вызвать команду Apply code changes из меню Debug (или нажать Alt+F10), после того как вы подправили исходные тексты. Более того, Visual C++ может вызывать для вас эту команду автоматически. Это будет происходить, если в окне Tools->Options на вкладке Debug установить флаг Debug commands invoke Edit and Continue.
Q. У меня dialog-base приложение, живет в systray. Необходимо, чтобы приложение при повторном запуске находило уже запущеный экземпляр программы и активизировало его. Я пытался сделать это через FindWindow, в которую передается имя зарегистрированного класса окна, и заголовок окна, которое разыскивается. По заголовку я искать не могу, так как он все время у меня меняется. Следовательно, нужно искать по зарегистрированному имени класса окна. Вот тут то и начинается проблема. Я его не знаю. MFC сама их раздает dialog-based приложениям. А переопределить это имя можно было бы в PreCreateWindow, но этот метод CDialog не наследует из CWnd. Во всех остальных методах, имя класса уже зарегистрированно, т.е. менять его поздно. Как быть?