 |
для установки окна и запуска программы.
Примечание: MainWindow, используемое для задания преры-
вания по сообщению окна, которое описывается в данной главе
ниже, является элементом MyApp.
Теперь вы знаете как работает программа и можете начать ее
отлаживать.
Отладка программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Если вы еще этого не сделали, запустите отладчик TWD под
Windows, загрузите программу TDODEMOB.CPP затем нажмите клавишу
F9 для запуска демонстрационной программы. Вы можете перемещать
"мышь" и даже выбирать команды меню, но когда вы нажимаете кнопку
"мыши" и начинаете перемещать "мышь", вы увидите, что происходит
сбой программы и она возвращает управление в TDW с сообщением об
ошибке "Exception 13" ("Исключительная ситуация 13").
Примечание: TDW выводит сообщение "Exception 13", когда
ваша программа приводит к невосстановимой ошибке.
Выявление первой ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда вы нажимаете клавишу Esc и очищаете окно сообщений,
TDW оставляет вас с окне CPU (ЦП). Данное окно выводится, так как
во время сбоя ваша программа выполняет код Windows. Так как вы не
вернулись в окно Module (Модуль), то отсутствует удобный маркер,
который отмечал бы место, в котором обращение вашей программы к
Windows вызвало невосстановимую ошибку.
Перед тем как продолжить, нажмите клавиши Alt-F3, чтобы зак-
рыть окно CPU (в основном вы будете работать в окно Module).
Поиск функции, которая вызывает Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Так как сбой в программе происходит при нажатии левой кнопки
TDeb 3.0 #3-3 = 69 =
"мыши", вероятно проблема заключается в функции WMLButtonUp. Од-
нако существует другой метод, который можно использовать для
определения того, где находилась ваша программа - трассировка
стека.
Для выполнения трассировки стека выберите с помощью команды
ViewіStack (ОбзоріСтек) окно Stack (Стек) и прокрутите вниз спи-
сок шестнадцатиричных инструкций, пока вы не дойдете до строки,
указывающей подпрограмму вашей программы (имя подпрограммы вы
увидите в коде ASCII). Эта строка находится в так называемом яд-
ре Windows.
Как можно видеть в окне Stack, подпрограммой, которую нужно
рассмотреть, в самом деле является подпрограмма WMLButtonDown.
Чтобы перейти к данной подпрограмме в окне Module, сначала щелк-
ните в этом окне кнопкой "мыши". Затем нажмите клавиши Ctrl-S,
наберите WMLButtonDowm и нажмите для поиска этой подпрограммы
клавишу Enter. Если вы увидите сообщение "Search expression not
found" ("Искомое выражение не найдено"), перейдите к началу файла
и клавиши Ctrl-N, чтобы снова выполнить поиск (в TDW вы можете
выполнять поиск только от текущей позиции курсора до конца фай-
ла). Возможно, перед тем как вы найдете функцию, вам потребуется
несколько раз нажать Ctrl-N.
TDeb 3.0 #3-3 = 70 =
Отладка функции WMLButtonDown
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Функция WMLButtonDown воспринимает в качестве параметра пе-
ременную типа RTMessage и выделяет из этого сообщения позицию
"мыши". Затем она вызывает функции Windows MoveTo и SelectObject
для позиционирования пера в окне и выбора текущего инструмента
рисования.
Так как вы видите имя этой подпрограммы в окне Stack, то
приводящим к сбою обращением в Windows должен быть вызов одной из
этих подпрограмм Windows. Чтобы увидеть, какой это вызов, вы мо-
жете выполнить программу до начала этой функции и выполнить ее по
шагам, чтобы увидеть, какой вызов вызывает невосстановимую ошиб-
ку.
При расположении курсора на строке WMLButtonDown перезагру-
зите программу TDODEMOB, нажав клавиши Ctrl-F2, затем нажмите
клавишу F4, чтобы выполнить программу до этой точки. Команда вы
увидите окно ColorScribble, нажмите левую кнопку "мыши", чтобы
программа вернулась в TDW. (Чтобы получить от Windows сообщения
по событию от "мыши", возможно придется нажать клавишу несколько
раз.) На этот раз невосстановимой ошибки не возникает (по крайней
мере пока), поскольку поскольку все, что пока выполнялось, это
вызов Windows функции WMLButtonUp программы TDODEMOB. Отладчик
TDW возвращает вас к первой строке этой функции.
Начните нажимать клавишу F7 для пошагового выполнения прог-
раммы. Когда вы нажмете F7 на вызове MoveTo, то увидите окно со-
общений, в котором выводится "Exeption 13". Вероятно, проблема в
вызове MoveTo.
Отладка MoveTo
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Функция MoveTo работает с пером и текущими координатами кур-
сора x и y. Координаты извлекаются из сообщения Msg, которое при-
ходит от Windows. Если программа не извлекает неверную часть это-
го сообщения (а это не так), то с этими параметрами должно быть
все в порядке.
Местом ошибки должен быть HandleDC - контекст описателя уст-
ройства пера.
В этой точке, поскольку вы имеете две невосстановимых ошиб-
ки, наиболее надежным способом будет выход в TDW и закрытие перед
дальнейшей работой Windows.
Исправление ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Если причиной невосстановимой ошибки является HandleDC, то
либо описатель (контекста устройства) установлен неверно, либо не
TDeb 3.0 #3-3 = 71 =
устанавливался вовсе. На самом деле он не устанавливался. Прог-
рамма должна инициализировать контекст дисплея с помощью следую-
щего вызова Windows:
HandleDC = GetDC(HWindow);
В приведенном ниже исходном коде показан метод
WMLButtonDown с добавленным оператором инициализации контекста.
void ScribbleWindow::WMLButtonDown(RTMessage Msg)
{
if ( !ButtonDown )
{
ButtonDown = True; // отметить кнопку "мыши",
// так что при перемещении "мыши"
// с нажатой кнопкой будет
// рисоваться линия
HandleDC = GetDC(HWindow); // создать контекст вывода
для рисования при нажатой
кнопке "мыши" }
MoveTo(HandleDC, Msg.LP.Lo, Msg.LP.Hi);
// переместить точку рисования
// в точку нажатия кнопки "мыши"
SelectObject(HandleDC, ThePen);
// выбрать перо для контекста
// устройства
}
}
TDeb 3.0 #3-3 = 72 =
Проверка исправлений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В Borland C++ добавьте в ScribbleWindow::WMLButtonUp опера-
тор инициализации контекста. Далее скомпилируйте проект с включе-
нием отладочной информации (выбрав команду (CompileіBuild All)
(КомпиляторіПолное построение)).
Поскольку в нашем случае имеются другие ошибки, снова загру-
зите в TDW программу, затем при выводе окна Module нажмите клави-
шу F9.
Теперь, если вы рисуете с помощью пера, то линия рисуется
назначенным по умолчанию цветом - черным.Попробуйте рисовать раз-
личными цветами, выбирая из меню цвет пера. Красный, зеленый и
голубой будут работать прекрасно, но когда вы попытаетесь изме-
нить цвет обратно на черный, то цвет пера не изменится. Похоже,
вы нашли другую ошибку.
Поиск ошибки назначения цвета пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Наиболее вероятным местом этой ошибки является функция
SCribbleWindow, который создает цвет пера SelectBlackPen. Выйдите
из ColorScribble, затем для сброса программы нажмите клавиши
CtrlF2. Установите точку останова на открывающей фигурной скобке
функции CScribbleWindow::SelecrBlackPen. Затем запустите програм-
му и выберите команду PenіBlack. (Чтобы получить сообщение от
Windows, возможно придется нажать клавишу.) Отладчик TDW должен
остановить выполнение на точке останова. Поскольку этого не про-
исходит, здесь что-то неверно.
Вероятно, функция SelectBlackPen никогда не вызывается. Пос-
кольку данная подпрограмма работает на основе динамически диспет-
черизуемой виртуальной таблице, возможно что-то не так с ее иден-
тификатором.
Установка точки останова по сообщению окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
|