| |
BIGLIB |
| большущая библиотека (9812 книг), можно не только прочитать но и скачать бесплатно |
|
| |
ФАНТАСТИКА |
| фентези,
фантастика, фантастические повести |
|
| |
ФИЛОСОФИЯ |
книги, которые заставляют
задуматься над окружающим тебя миром.
|
|
| |
МЕДИЦИНА |
медицинские книги,
методички,
народные лечебники |
|
| |
КУЛИНАРИЯ |
рецепты
тортов, консервирование,
все о спиртных
напитках. |
|
| |
СТИХИ |
| стихи популярных
и не очень авторов |
|
| |
ТВОРЧЕСТВО |
| народное творчество,
стихи, песни и т.д. |
|
| |
ЮМОР |
| анекдоты, приколы,
смешные истории |
|
| |
ЭРОТИКА |
| эротические рассказы,
книги о технике секса,
кама-сутра и др. |
|
|
| |
 |
7. Когда отладчик TDW закончит листинг глобальной памяти,
снова вызовите список объектов глобальной памяти и выбе-
рите команду Close Log File (Закрытие файла регистрации),
чтобы закрыть файл.
TDeb 3.0 #3-3 = 59 =
8. Выберите из локального меню команду Erase Log (Стереть
протокол), чтобы очистить протокол.
9. Нажмите F9, чтобы снова запустить программу, и при помощи
"мыши" проконтролируйте информацию в блоке About Program
Manager. Запомните проценты, приведенные там для систем-
ных ресурсов.
10. Нарисуйте в Simple Paint достаточно, чтобы уменьшить сис-
темные ресурсы на 20-30 процентов.
11. Нажмите клавишу для возврате в TDW и повторите шаги 4-8,
на этот раз с другим именем файла протокола (регистра-
ции).
12. Выйдите из TDW, распечатайте файлы протоколов и сравните
их.
Проделав это, вы отметите следующее:
- Объекты памяти, принадлежащие BCWDEMOB, не увеличились в
размерах.
- Объекты памяти GDI увеличились в размерах.
Первое из этих примечаний подтверждает то, что вы уже знаете
о программе: отлаживаемый код программы BCWDEMOB выделяет гло-
бальную память, а не локальную.
Второе говорит вам нечто новое: BCWDEMOB выделяет объекты
Интерфейса графических устройств (GDI) и не освобождает их.
Нахождение ошибки: функциональный подход
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Теперь, зная характер ошибки, вы можете начать искать место
в программе, где выделяются объекты памяти, не освобождаемые
впоследствии. Для этого полезно сделать функциональный обзор
программы и исследовать каждую подпрограмму в последовательности
их вызова.
Выбор элементов меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Выбор элементов меню выполняется посредством помещения кур-
сора в меню, нажатия левой кнопки "мыши" и перемещения по меню к
желаемому элементу, выбор которого изменяет цвет, толщину пера
или форму изображения. Изменение любого из этих значений вызывает
посылку сообщения WM_COMMAND в подпрограмму WndProc, которая об-
рабатывает сообщение, вызывая для этого DoWMCommand.
DoWMCommand содержит оператор switch, который сохраняет сде-
TDeb 3.0 #3-3 = 60 =
ланный вами выбор в переменной программы. Эти переменные хранятся
в сегменте данных BCWDEMO и не влияют на глобальную память.
Рисование фигуры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Для того, чтобы нарисовать фигуру, вы устанавливаете курсор
в предназначенную для графического ввода пользователя область ок-
на, удерживая нажатой левую кнопку "мыши" перемещаете курсор в
другую точку и там отпускаете кнопку "мыши". Если вы перемещаете
"мышь" при ненажатой левой кнопке, вы можете заметить, что фигура
по мере перемещения рисуется, стирается и снова рисуется. Остает-
ся она на экране только при отпускании левой кнопки.
Нажатие левой кнопки "мыши"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При нажатии левой кнопки в области пользовательского графи-
ческого ввода Windows посылает сообщение WM_LBUTTONDOWN в
WndProc, что приводит к вызову DoButtonDown. Эта подпрограмма
сохраняет текущую позицию "мыши" (которая далее именуется
меткой) и выполняет установки характеристик пера в структуре
thisShape. Эта структура представляет собой переменную программы
и влияет только на сегмент данных программы BCWDEMO.
Перемещение "мыши"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда вы перемещаете "мышь" при нажатой левой кнопке в поль-
зовательской области ввода, Windows посылает WM_MOUSEMOVE (или WM
_MOUSEFIRST, что то же самое) в WndProc, которая вызывает
DoMouseMove. Эта подпрограмма вызывает DrawShape для стирания фи-
гуры от предыдущей позиции "мыши" до исходной, а затем снова -
для рисования фигуры от текущей позиции до метки. Единственное
использование глобальной памяти в DoMouseMove состоит в получении
контекста устройства для текущего окна, который освобождается в
конце подпрограммы вызовом ReleaseDC.
Рисование фигуры (и нахождение позиции ошибки)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Теперь рассмотрим подпрограмму DrawShape, которая дважды вы-
зывается из DoMouseMove. DrawShape запоминает перо, которым рисо-
валась предыдущая фигура, создает новое перо и рисует линию, эл-
липс или прямоугольник. В конце своей работы она восстанавливает
сохраненное на входе перо.
Поскольку перо - это объект интерфейса графических устройств
(GDI), выделяемый в глобальной памяти, подпрограмма DrawShape мо-
жет содержать код, вызывающий проблемы с памятью. Эта подпрограм-
ма вызывает особенное подозрение, так как она вызывается дважды
при каждом перемещении мыши. Если она создает перья и не удаляет
их, то она "съест" память очень скоро.
TDeb 3.0 #3-3 = 61 =
Действительно, недалеко от начала DrawShape выделяет перо
вызовом SelectObject, но не освобождает выделенную ему память вы-
зовом DeleteObject в конце. Чтобы исправить эту ошибку, вы должны
заменить последнюю строку DrawShape следующим кодом:
DeleteObject(SelectObject(hdc,saveObject));
Возможно, найденная ошибка является единственной причиной
проблем с памятью, однако желательно проверить и все остальные
места программы, связанные с рисованием объектов.
Отпускание левой кнопки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
При отпускании левой кнопки "мыши" BCWDEMOB рисует фигуру в
последний раз и оставляет ее на экране. Отпускание кнопки застав-
ляет Windows послать сообщение WM_LBUTTONUP в WndProc, которая
вызывает DoLButtonUp. Эта подпрограмма сохраняет текущий прямоу-
гольник из пользовательской области в массив текущей фигуры
thisShape, вызывает InvalidateRect для добавления области в об-
ласть обновления окна, а затем вызывает UpdateWindow, которая по-
сылает сообщение WM_PAINT прямо в главное окно. Эта подпрограмма
не использует глобальную память.
При выходе из DoLButtonUp сообщение WM_PAINT находится в
очереди и готово к обработке в WndProc.
TDeb 3.0 #3-3 = 62 =
Перерисовка экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Когда WndProc получает сообщение WM_PAINT, она вызывает
DoPaint для перерисовки соответствующей области экрана (описана
выше в этом разделе). При перерисовке обновляемого прямоугольника
DoPaint вызывает две подпрограммы Windows, влияющие на глобальную
память: CreateCompatibleDC и SelectObject. В конце DoPaint вызы-
ваются DeleteDC и DeleteObject, которые освобождают выделенную в
начале подпрограммы память.
Заключение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Так как вы рассмотрели все подпрограммы, вы можете быть уве-
рены, что ошибка, связанная с памятью, найдена. Этот метод был
выбран потому, что вы недостаточно детально знаете отлаживаемую
программу. Разумеется, в программе, написанной лично вами, вы
нашли бы такую ошибку гораздо быстрее.
Не мешает также и более подробное тестирование программы.
Хорошо зная программу, вы могли бы не искать ошибку в части прог-
раммы, связанной с меню, так как обнаружили бы, что сбой програм-
мы наступает и при одном только перемещении курсора по экрану с
помощью "мыши". Кроме того, обнаружив, что проблема возникает
только при перемещении "мыши" в области пользовательского графи-
ческого ввода при нажатой левой кнопке (это вы могли бы обнару-
жить, нажав кнопку и перемещая курсор до тех пор, пока не прои-
зойдет сбой программы), вы могли бы сразу предположить, что
проблема связана с подпрограммой DoMouseMove и на ней сосредото-
чить свои усилия.
TDeb 3.0 #3-3 = 63 =
Глава 19. Отладка программы, использующей ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Пример объектно-ориентированной программы данной главы был
написан с помощью класса ObjectWindows, который существенно об-
легчает программирование в Windows.
Примерами программ служат программа TDODEMO и TDODEMOB (B
обозначает версию программы с ошибками). Программа TDODEMOB со-
держит несколько ошибок, которые вы выявите при работе с данной
главой.
Перед тем, как продолжить изучение, полезно запустить из
Windows программу TDODEMO и немного поэкспериментировать с ней,
|
adfun.ru
|
|
|
|