ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 21


         Глава 17. Турбо отладчик для Windows (TDW)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Турбо отладчик для Windows (TDW) позволяет отлаживать  прик-
ладные  программы,  написанные для Microsoft Windows версии 3.0 и
старше. Он работает под управлением Windows на той же машине, что
и  отлаживаемая  программа,  и выполняет переключения между собс-
твенными экранами и экранами отлаживаемой  прикладной  программы,
как это делает Турбо отладчик.

     Отладка происходит  во  многом  аналогично отладке с помощью
Турбо отладчика, за исключением того, что здесь вы получаете дос-
туп к информации, являющейся специфичной для Windows, например:

     - Сообщения,  принимаемые  и  посылаемые  окнами  прикладной
       программы;

     - Глобальная динамически распределяемая область памяти;

     - Локальная динамически распределяемая область памяти;

     - Полный список  модулей  (включая  динамически  компонуемые
       библиотеки DLL), загружаемых Windows;

     - Отладка динамически компонуемых библиотек (DLL).

                 Требования для запуска TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Отладчик TDW работает в стандартном  или  улучшенном  режиме
386, что означает необходимость иметь компьютер с процессором как
минимум 80286 или выше, и как минимум один мегабайт памяти.

     TDW поддерживает только стандартные графические режимы дисп-
лея:  CGA,  EGA,  VGA,  SVGA  и  монохромную  графическую   плату
Hercules. Если  вы  используете необычный драйвер,  то прежде чем
запускать Windows и TDW,  перейдите на стандартный драйвер.  Если
вы  попытаетесь использовать при работе с TDW нестандартный драй-
вер,  то не сможете переключаться между экранами TDW и прикладной
программы.

     Используя DLL с именем TDVIDEO.DLL  TDW  поддерживает  Super
VGA. С  TDW распространяется множество DLL,  которые поддерживают
различные платы Super VGA (описанные в файле README на  дистрибу-
тивной дискете).  Чтобы использовать c TDW эти DLL, скопируйте их
в каталог, где находится TDW.EXE, и назовите TDVIDEO.DLL.

     Если  вы  не найдете DLL, поддерживающую  плату  Super  VGA,
свяжитесь с фирмой Borland.

     Как и Турбо отладчик, TDW может использовать второй монитор,
подключенный  к компьютеру,  что дает возможность на одном экране
просматривать вывод TDW,  а на другом - прикладной программы. Для
этого  нужно  запустить TDW с параметром командной строки -do или
выполнить утилиту TDINST, установив User Screen Updating в значе-
ние Other display.

                        Установка TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При установке в системе Турбо отладчика программа  установки
помещает файлы, относящиеся к работе в Windows, в тот же каталог,
что и файлы Турбо отладчика. Это файлы:

     - TDW.EXE, собственно отладчик TDW;

     - TDWHELP.TDH, файлы системы подсказки TDW;

     - WRSETUP.EXE,  утилита настройки конфигурации для программы
       удаленной отладки в Windows WREMOTE;

     - WREMOTE.EXE,  программа удаленной отладки прикладных прог-
       рамм для Windows.  (Удаленная отладка в Windows описана  в
       Приложении E);

     - WINDEBUG.DLL,  динамически компонуемая библиотека, необхо-
       димая для выполнения TDW и WREMOTE;

     - TDDEBUG.386,  программа, которую загружает Window для под-
       держки прерывания программы по Ctrl-Alt-SysRq и аппаратной
       отладки.

     Процесс установки создает пиктограммы  для  TDW,  WRSETUP  и
WREMOTE  и помещает их под группой Windows Applications (приклад-
ные программы для Windows) менеджера программ Windows.  Вы можете
запустить  одну из этих программ,  выбрав соответствующую пиктог-
рамму, как и для любых других прикладных программ Windows.

                 Настройка конфигурации TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и в случае работы с Турбо отладчиком,  вы можете настро-
ить  конфигурацию TDW двумя способами - при помощи параметров ко-
мандной строки или при помощи утилиты TDINST  (с  параметром  ко-
мандной строки -w).

       Использование параметров командной строки TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Как и для Турбо отладчика, вы можете установить конфигурацию
TDW, используя различные параметры командной строки,  за которыми
может следовать необязательное имя программы со своими  собствен-
ными параметрами.  Имени программы может предшествовать имя марш-
рута.

     Поскольку TDW является программой для Windows,  вы  вероятно
будете вводить параметры командной строки либо при помощи команды
FileіRun (ФайліВыполнение) менеджера программ,  либо  при  помощи
команды FileіProperties (ФайліСвойства) менеджера программ, чтобы
изменить свойства командной строки пиктограммы TDW.  Вы также мо-
жете запустить Windows из командной строки DOS и использовать ко-
манду TDW,  за которой могут в произвольном порядке следовать па-
раметры  командной  строки,  либо имя программы с параметрами или
без,  либо и то,  и другое - и  все  это  как  аргументы  команды
Windows.

     Синтаксис командной строки для TDW имеет следующий вид:

     TDW [параметры] [имя_программы [аргументы_программы]]

     Отладчик TDW имеет меньше параметров командной  строки,  чем
Турбо отладчик TD.  За исключением параметра -t,  используемые им
параметры совпадают с параметрами Турбо отладчика,  которые расс-
матривались выше.

     Ниже приводятся параметры командной строки TDW:

 ЪДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і-?, -р    і  Обращение  за  подсказкой  о параметрах команднойі
 і          і  строки TDW.                                      і
 і          і                                                   і
 і-c<файл>  і  Использование файла конфигурации <файл>.         і
 і          і                                                   і
 і-do       і  Запуск TDW на вторичном дисплее.                 і
 і          і                                                   і
 і-ds       і  Обновление   экранов  путем  свопинга  (подкачки)і
 і          і  страниц.                                         і
 і          і                                                   і
 і-l        і  Запуск в режиме Ассемблера. Отладка  кода началь-і
 і          і  ной загрузки библиотеки DLL.                     і
 і          і                                                   і
 і-p        і  Использование "мыши".                            і
 і          і                                                   і
 і-sc       і  Игнорировать регистр в именах идентификаторов.   і
 і          і                                                   і
 і-sdкаталогі  Установить в качестве каталога с исходными файла-і
 і          і  ми указанный каталог.                            і
 і          і                                                   і
 і-tкаталог і  Установить в качестве начального каталога  запус-і
 і          і  ка указанный каталог.                            і
 АДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Один из этих параметров командной строки, параметр t, досту-
пен только в TDW. Этот параметр изменяет начальный каталог запус-
ка TDW, т.е. каталог, в котором TDW ищет файл конфигурации и фай-
лы .EXE,  не заданные с полным маршрутом. Синтаксис этой парамет-
ра:

     -tимя_каталога

     Этот параметр позволяет установить только один начальный ка-
талог запуска.  Если  ввести с помощью одного параметра несколько
таких каталогов, то TDW все их игнорирует. Если указать несколько
параметров -t  с разными каталогами,  то TDW использует последний
из них.

                Использование TDINST для TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы воспользоваться  программой TDINST для TDW,  запустите
TDINST с параметром командной строки -w.  TDINST для TDW работает
аналогично TDINST для Турбо отладчика,  за исключением того,  что
файл конфигурации по умолчанию будет называться  TDCONFIG.TDW,  и
доступно меньше  параметров.  (См.  список  параметров  командной
строки TDW в предыдущем разделе).

     Описание использования TDINST см. в Приложении D.

                      Использование TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При запуске TDW он появляется в полноэкранном символьном ре-
жиме DOS, а не в окне. Несмотря на такой внешний вид,  TDW -  это
прикладная программа Windows и работать может только в Windows.

     В отличие от других работающих в Windows программ, вы не мо-
жете использовать оперативные клавиши Windows (типа  Alt-Esc  или
Ctrl-Esc)  для  выхода из экрана TDW.  Однако,  если отлаживаемая
прикладная программа является активной (курсор активен в одном из
ее окон),  вы  можете использовать эти клавиши или "мышь" для пе-
реключения на другие программы.

     Отладка в TDW во многом похожа на отладку в Турбо отладчике,
за исключением нескольких свойств Турбо отладчика,  которые рабо-
тают иначе,  и нескольких дополнительных свойств, помогающих при-
отладке программ для Windows.

            Различия между TDW и Турбо отладчиком
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Различными являются следующие свойства:

     - Переключение из вашей прикладной программы в TDW  выполня-
       ется при помощи комбинации клавиш Ctrl-Alt-SysRq. Эта опе-
       рация аналогична использованию Ctrl-Break для переключения
       из прикладной программы для DOS в Турбо отладчик,  за иск-
       лючением того,  что при этом прикладная программа для  DOS
       завершается, а для Windows - только приостанавливается.

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

     - Если это возможно, выполните вашу программу до ее нормаль-
       ного  конца  или  используйте команду System для выхода из
       нее до выхода из TDW или загрузки другой программы для от-
       ладки. Нештатный выход из прикладной программы для Windows
       может привести к тому,  что не будут освобождены ее ресур-
       сы,  что  в  свою очередь может вызвать проблемы у TDW или
       другой прикладной программы.

     - Запись нажатий клавиш не выполняется.

     - Нельзя отлаживать драйверы устройств или резидентные прог-
       раммы.

     - Не поддерживается аппаратная отладка. (Если хотите, вы мо-
       жете оставить устройство TDH386.SYS в CONFIG.SYS.  Это  не
       помешает работе Windows или TDW).

     - Следующие команды меню File недоступны,  поскольку TDW ра-
       ботает под управлением Windows:

          * DOS Shell, т.к. оболочка отсутствует;

          * Resident,  т.к.  TDW  не может по завершении остаться
            резидентным;

          * Table Relocate, поскольку вы не можете установить ба-
            зовый сегмент таблицы символических имен.

                     Новые средства TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Новые свойства,   поддерживаемые   отладчиком  программ  для
Windows:

     - Окно просмотра Windows Messages (Сообщения Windows), пока-
       зывающее сообщения,  передаваемые окнам в вашей программе.

     - В окне регистрации Log вы имеете возможность выводить сле-
       дующие три типа данных:

          * Сегменты данных, расположенные в локальной динамичес-
            ки распределяемой области вашей прикладной программы;

          * Сегменты  данных,  расположенные в глобальной динами-
            чески распределяемой области;

          * Полный список модулей,  составляющих программу, вклю-
            чая динамически компонуемые библиотеки (DLL);

          * Приведение типа выражений от логических номеров памя-
            ти к дальним указателям.

     - Отладка динамически компонуемых библиотек (DLL).

     - Параметр  командной  строки -t,  позволяющий устанавливать
       начальный каталог запуска TDW,  чтобы можно было использо-
       вать файл конфигурации или файлы .EXE из этого каталога.

                Регистрация сообщений Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для трассирования передаваемых в окна вашей прикладной прог-
раммы сообщений   выберите    команду    ViewіWindows    Messages
(ОбзоріСообщения Windows),  чтобы  открыть окно Windows Messages.
Это окно показывает сообщения,  которые Windows посылает  в  одно
или более окон вашей программы.

     Окно Windows  Messages  (Сообщения  Windows) состоит из трех
областей: области выбора окна Window Selection (верхняя левая об-
ласть), области  класса  сообщений  Message Class (верхняя правая
область) и области сообщений Messages (нижняя область). Сообщения
показывает область Messages.

    ЙН[*]НННWindows messagesННННННННННННННННННН3НННННН[ ][ ]»
    єWindowproc wndproc±±±±±±±іLog±message±WM±PAINT±±±±±±±±±є
    є                         і                             є
    є                         і                             є
    є                         і                             є
    єДДДДДДДДДДДДДДДДДДДДДДДДДД<І°°°°°°°°°°°°°°°°°°°°°°°°°°>є
    єHwnd:2214 wParam:0000 lParam:000000000 (000f) WM PAINT є
    ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННЅ

      Рис. 17.1 Окно Windows Messages

                         Выбор окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ЪДДДДДДДДДДДДДДї
     і Add...       і         Добавить
     і Remove       і         Удалить
     і Delete All   і         Удалить все
     АДДДДДДДДДДДДДДЩ

     Прежде чем вы сможете регистрировать  сообщения,  вы  должны
сначала указать, для которого окна будут регистрироваться сообще-
ния. Это выполняется в верхней левой области, области выбора окна
Window Selection. Локальное меню этой области (активируемое нажа-
тием клавиш  Alt-F10) позволяет добавить выбранное окно,  удалить
выбранное окно или удалить все выбранные окна.

                 Добавление выбранного окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для того, чтобы добавить выбранное окно, вы можете либо выб-
рать  команду  Add (Добавление) из локального меню области Window
Selection (Выбор окна),  либо просто начать ввод в области. В том
и другом случае вы получите окно диалога:

     Вы можете  в этом окне ввести либо имя подпрограммы, которая
обрабатывает сообщения для окна (выбрав  "кнопку"  Window  Proc),
либо значение логического номера (выбрав "кнопку" Handle). Введи-
те столько имен подпрограмм или логических номеров, сколько нужно
для трассировки сообщений для ваших окон.

           Й[*]ННAdd window or handle to watchНННННН»
           є                                        є
           є Window identifier                      є
           є ±±±±±±±±±±±±±±±±±              OK      є
           є                                ±±±±±±  є
           є                                Cancel  є
           є Identify by                    ±±±±±±  є
           є   (*) Window proc              Help    є
           є   ( ) Handle                   ±±±±±±  є
           є                                        є
           ИННННННННННННННННННННННННННННННННННННННННј

     Рис. 17.2 Диалоговое окно Add Window

     Add window or handle to watch - добавить окно  или описатель
для просмотра;  Window identifier - идентификатор окна;  Identify
by - идентификация по...;  Window proc - процедура окна; Handle -
описатель; OK - нормально; Cancel - отмена; Help - справка.

          Примечание: Ввод в этом окне первого значения также ус-
     танавливает класс сообщений в "Log all messages" ("Регистра-
     ция всех сообщений").

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

     Если вы предпочитаете использовать имя переменной с логичес-
ким номером, вы должны сначала перейти по программе к строке, где
этой переменной присваивается логический номер.  (Для  пошагового
перемещения по программе служат клавиши F7 или F8). Если вы пыта-
етесь ввести  имя переменной до этого оператора присваивания, TDW
не сможет принимать сообщения для этого логического номера.

ыбор окна для прикладной программы, использующей ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы   отлаживаете   прикладную  программу,  использующую
ObjectWindows, и выбираете  команду  ViewіWindows  Messages  (Об-
зоріСообщения Windows), то по умолчанию выводится диалоговое окно
Windows Messages (Сообщения Windows),  показанное на  Рис.  17.1.
Для стандартных   программ   Windows   и  программ,  использующих
ObjectWindows, это окно работает одинаково,  только имя процедуры
Windows вы  использовать не сможете.  Вместо этого для того окна,
сообщения которого вы хотите  регистрировать  или  по  сообщениям
которого хотите установить прерывания,  нужно использовать описа-
тели окна.

                  Получение описателя окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Перед тем, как вы сможете использовать описатель объекта ок-
на, нужно выполнить программу и пройти то место, где он инициали-
зируется. Для этого можно использовать несколько методов.

     - Простейший  способ  состоит  в  запуске  вашей программы и
       возврате в TDW по Ctrl-Alt-SysRq.

     - Другая  возможность заключается в задании точки останова в
       подпрограмме обработки сообщений (примером  которой  может
       быть подпрограмма, обрабатывающая сообщения WM_MOUSEMOVE),
       и последующем выполнении в окне действия, которое приведет
       к срабатыванию точки останова (например,  перемещения "мы-
       ши").

     - Если основные проблемы у вам заключаются в самом окне (та-
       кие, как невосстановимая ошибка прикладной программы, воз-
       никающая при первоначальном выводе окна),  получать указа-
       тель окна придется более длинным путем.

       Так как описатель инициализируется  функцией ObjectWindows
       CreateWindow, и данная функция выполняется после того, как
       вы инициализируете окно,  то  нужно переопределить в клас-
       се  окна  эту функцию и для получения описателя установить
       на ней точку прерывания.

       Например, в следующем исходном коде данная функция переоп-
       ределяется для  класса   окна   ScribbleWindow   программы
       TDODEMO:

         void ScribbleWindow()
         {
                  TWindow::SetupWindow();
         }

       Далее позиционируйте курсор на строке после оператора ини-
       циализации и нажмите F4 для выполнения  программы  до  той
       точки,  где  инициализируется описатель окна,  диалогового
       окна или управляющего элемента. В данном примере нужно по-
       зиционировать  курсор  на  закрывающей  квадратной  скобке
       функции SetupWindow.

     После того,  как  описатель инициализирован и вы вернулись в
TDW, выбрав команду DataіInspect (ДанныеіПроверка)  и  введя  имя
соответствующего объекта          окна         (в         TDODEMO
WinMain#MyApp.MainWindow), можно получить описатель окна. Найдите
элемент данных  HWindow  и скопируйте его в окно Clipboard (нажав
клавиши Shift-F3).  После этого вы  можете  вставлять  содержимое
HWindow в  качестве  описателя в диалоговом окне Add (Добавление)
или в верхней левой области окна Window Messages (нажмите клавиши
Shift-F4 в текстовом поле ввода диалогового окна).

    Задание окна с разрешенной поддержкой ObnjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы запускаете программу TDINST с  параметром  командной
строки -w,  то можете включить в TDW поддержку сообщений окна для
ObjectWindows. Когда данный параметр включен, вы можете использо-
вать имена оконных объектов,  как если бы они описывались в вашей
прикладной программе.

     При выборе команды  ViewіWindows  Messages  (ОбзоріСообщения
окна) при  включенном  параметре OWL на экран выводится следующий
экран:

    ЙН[*]НННOWL Windows MessagesННННННННННННННН3НННННН[ ][ ]»
    єWindow±object±11c5:006e±±іLog±all±messages±±±±±±±±±±±±±є
    є                         і                             є
    є                         і                             є
    є                         і                             є
    єДДДДДДДДДДДДДДДДДДДДДДДДДБ<І°°°°°°°°°°°°°°°°°°°°°°°°°°>є
    єHwnd:2214 wParam:0000 lParam:000000000 (000f) WM PAINT є
    є                                                       є
    є                                                       є
    є                                                       є
    ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННЅ

     Рис. 11.1 Окно Windows  Messages  с  разрешенной  поддержкой
ObjectWindows

            ЪДДДДДДДДДДДДДї
            і Add...      і      Добавить
            і Remove      і      Отменить
            і Delete All  і      Удалить все
            АДДДДДДДДДДДДДЩ

     Перед тем,  как  вы сможете регистрировать сообщения,  нужно
сначала указать,  для какого окна регистрируются  сообщения.  Это
можно сделать в левой верхней области - области выбора окна.  Ло-
кальное меню области (которое активизируются с помощью клавиш Alt
-F10) позволяет вам добавить окно, удалить окно, или отменить все
выбранные окна.

Добавление выбора окна с разрешенной поддержкой ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Перед тем,  как  вы сможете использовать объект окна,  нужно
выполнить программу и пройти то место,  где он  инициализируется.
Обычно объект инициализируется в операторе, аналогичном следующе-
му оператору в определении функции в TDODEMO:

     void CScribbleAllocation::InitMainWindow()
     {
         MainWindow = new ScribbleWindow(NULL, Name);
     }

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

     После инициализации  оконного объекта вы можете добавить его
в область выбора окна.  Для добавления выбранного окна вы  можете
либо выбрать команду Add (Добавление) локального меню области вы-
бора окна,  либо начать ввод в этом окне имени объекта.  Любой из
методов выводит диалоговое окно Add Window (Добавление окна).

     Если вы  не  находитесь в той подпрограмме,  где описывается
объект, для доступа  к  нему  требуется  переопределение  области
действия. Например, в TDODEMO MainWindow является элементом MyApp
(так как MyApp представляет собой тип CScribbleApplication, кото-
рый является производным от TApplication, а TApplication содержит
элемент данных с именем MainWindow). Однако, поскольку MyApp опи-
сывается в  функции WinMain,  то если вы не находитесь в этой фу-
нкции, доступа к MyApp у вас нет. Таким образом, переопределением
области действия,  которое  обеспечивает  работу в данном модуле,
является  WinMain#MyApp.MainWindow.

           Й[*]НAdd window or handle to watchНННННННН»
           є                                         є
           є Window identifiers                      є
           є ±±±±±±±±±±±±±±±±±±±±±±±±±±±             є
           є                                   OK    є
           є                                 ±±±±±±± є
           є                                         є
           є                                  Cancel є
           є Identified by                   ±±±±±±± є
           є  (.) Window object                      є
           є  ( ) Handle                      Help   є
           є                                 ±±±±±±± є
           є                                         є
           ИНННННННННННННННННННННННННННННННННННННННННЅ

     Рис. 17.4  Диалоговое окно Add Window с разрешенной поддерж-
кой ObjectWindows

          Примечание: Ввод в данном окне первого  значения  уста-
     навливает   также   класс  сообщений  в  значение  "Log  all
     messages" ("Регистрация всех сообщений").

     Вы можете ввести либо имя подпрограммы, которая обрабатывает
сообщения для  окна  (выберите  переключатель  Window Object) или
значение-описатель  (выберите  переключатель   Handle).   Введите
столько  имен подпрограмм или значений описателей,  сколько нужно
для отслеживания сообщений ваших окон.

                     Отмена выбора окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для отмены  выбора окна переместите курсор на элемент, затем
либо выберите локальное меню и используйте команду  Remove  (Уда-
лить), либо нажмите клавиши Del, Ctrl-Y или Ctrl-R.

     Чтобы отменить  все окна,  выберите в локальном меню команду
Delete All (Удалить все).

             Задание класса сообщений и действия
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Верхняя правая  область  - это область класса сообщений.  Ее
локальное меню идентично локальному меню области  выбора  окна  и
позволяет  вам добавить класс сообщения,  удалить класс сообщения
или удалить все классы, которые вы добавили.

           ЪДДДДДДДДДДДДДї
           і Add...      і           Добавить
           і Remove      і           Отменить
           і Delete All  і           Удалить все
           АДДДДДДДДДДДДДЩ

     Перед тем,  как добавить в данной области класс сообщений, в
области выбора окна нужно задать процедуру окна или описатель.

     Если вы  не  задаете  конкретный  класс  сообщений или класс
просматриваемых сообщений, то TDW наблюдает за всеми сообщениями,
передаваемыми процедуре окна или его описателю.

                 Добавление класса сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы добавить класс сообщений,  выберите в  области  класса
сообщений  команду локального меню Add (Добавление).  TDW выводит
следующее диалоговое окно:

            Й[*]НННSet message filterННННННННННННННННН»
            є Message Class                     OK    є
            є  ( ) All messages               ±±±±±±± є
            є  ( ) Mouse                              є
            є  ( ) Window                      Cancel є
            є  ( ) Input                      ±±±±±±± є
            є  ( ) System                             є
            є  ( ) Initialization              Help   є
            є  ( ) Clipboard                  ±±±±±±± є
            є  ( ) DDE                                є
            є  ( ) Non-client                         є
            є  ( ) Other                              є
            є  (.) Single message      ( ) Break      є
            є                          (.) Log        є
            є  Single Message name                    є
            є  ±±±±±±±±±±±±±±±±±±±±±±                 є
            ИНННННННННННННННННННННННННННННННННННННННННЅ

     Рис. 17.5 Диалоговое окно Set Message Filter

     Message Class - класс сообщений;  All messages - все сообще-
ния; Mouse - "мышь"; Window - окно; Input - ввод; System - систе-
ма; Initialization - инициализация; Clipboard - буфер вырезанного
изображения; DDE  - динамический обмен данными ;  Non-client - не
пользовательское;  Other - прочее; Single message - отдельное со-
общение;  Break - прерывание;  Log - регистрация;  Single message
name - имя отдельного сообщения.

     Диалоговое окно  Set Message Filter (Задание фильтра сообще-
ния) выводит вам подсказку как для класса,  так и  для  действия,
выполняемого при приеме сообщения.

     Отладчик TDW по умолчанию регистрирует все сообщения,  начи-
нающиеся с WM_.  Поскольку поступает так много сообщений, вы, ве-
роятно, захотите ограничить их, выбрав в списке классов сообщений
один из классов.  Вы можете добавлять только по одному классу со-
общений. Поэтому, если вы хотите отслеживать сообщения нескольких
классов, для каждого класса сообщений нужно использовать параметр
Add.

     Классы сообщений описываются в следующей таблице:

                    Классы сообщений Windows        Таблица 17.1
 ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і  Класс сообщения     і  Описание                            і
 ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і All messages         і  Все сообщения, начинающиеся с WM_.  і
 і (все сообщения)      і                                      і
 і                      і                                      і
 і Mouse                і  Сообщения, генерируемые событием от і
 і ("мышь")             і  "мыши" (например, WM_LBUTTONWODN и  і
 і                      і  WM_MOUSEMOVE)                       і
 і                      і                                      і
 і Window               і  Сообщения от менеджера Windows      і
 і (окно)               і  (например, WM_PAINT и WM_CREATE)    і
 і                      і                                      і
 і Input                і  Сообщения, генерируемые по событию  і
 і (ввод)               і  от клавиатуры или при доступе       і
 і                      і  пользователя к меню System, полосе  і
 і                      і  прокрутки, или блоку размера        і
 і                      і  (например, WM_KEYDOWN и             і
 і                      і  WM_SYSCOMMAND)                      і
 і                      і                                      і
 і System               і  Сообщения, генерируемые при         і
 і (система)            і  изменениях в системе (например,     і
 і                      і  WM_FONTCHANGE и WM_SPOOLERSTATUS)   і
 і                      і                                      і
 і Initialization       і  Сообщения, генерируемые при         і
 і (инициализация)      і  создании диалогового блока или окна і
 і                      і  (например, WM_INITDIALOG и          і
 і                      і  WM_INITMENU)                        і
 і                      і                                      і
 і Clipboard            і  Сообщения, генерируемые, когда одна і
 і (буфер вырезанного   і  прикладная задача пытается получить і
 і изображения)         і  доступ к буферу вырезанного         і
 і                      і  изображения или окну другой         і
 і                      і  прикладной задачи (например,        і
 і                      і  WM_SIZECLIPBOARD и WM_DRAWCLIPBOARD)і
 і                      і                                      і
 і DDE                  і  Сообщения динамического обмена      і
 і (динамический        і  данными, генерируемые прикладными   і
 і обмен данными)       і  программами при коммуникации с      і
 і                      і  окнами другой прикладной программы  і
 і                      і  (например, WM_DDE_INITIATE и        і
 і                      і  WM_DDE_ACK)                         і
 і                      і                                      і
 і Non_client           і  Сообщения, генерируемые Windows     і
 і (не пользователь)    і  для обслуживания непользовательской і
 і                      і  области окна прикладной задачи      і
 і                      і  (например, WM_NCHITTEST и           і
 і                      і  WM_NCCREATE)                        і
 і                      і                                      і
 і Other                і  Любые сообщения, начинающиеся с     і
 і (прочие)             і  WM_, которые не попадают в другие   і
 і                      і  категории, например, другие         і
 і                      і  сообщения управления отображением   і
 і                      і  и многие интерфейсные               і
 і                      і  документирующие сообщения           і
 і                      і                                      і
 і Single Message       і  Любое отдельное сообщение,          і
 і (отдельное сообщение)і  начинающееся с WM_, которое вы      і
 і                      і  хотите зарегистрировать или         і
 і                      і  прервать программу по сообщению     і
 АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Для отслеживания  отдельного   сообщения   выберите   Single
Message  (Отдельное сообщение) и введите имя или номер сообщения.
Если вы вводите имя сообщения,  учтите, что все буквы должны быть
заглавными.

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

     Например, если вы хотите отслеживать  сообщение  WM_PAINT  и
останавливать программу всякий раз, как в окно посылается это со-
общение, вы выбираете область Window Selection (Выбор окна) и вы-
полняете следующие действия:

     1. Выверите правую верхнюю область, Message Class (Класс со-
        общений).

     2. Вызовите ее локальное меню и выберите команду Add (Добав-
        ление).

     2. В окне диалога выберите при помощи селективных переключа-
        телей Action (Действие) установку  Break  (Прерывание)  и
        при помощи  селективных  переключателей Message Name (Имя
        сообщение) установку Single  Message  (Отдельное  сообще-
        ние).

     4. В  блоке  ввода  Message  Name  (Имя  сообщения)  введите
        WM_PAINT и нажмите клавишу Return.

     На Рис.  17.1  показано,  как выглядит окно Windows Messages
после того, как вы сделали данный выбор, и поступило сообщение.

                  Удаление класса сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для удаления класса сообщений поместите курсор  на удаляемый
элемент и либо вызовите локальное меню и выберите из него команду
Remove, либо нажмите Delete или клавиши Ctrl-Y.

     Для удаления всех классов выберите команду Delete All  (Уда-
лить все) из локального меню.

     После того,  как  вы  удалите все классы,  будет установлено
умолчание "Log all messages" ("Регистрация всех  сообщений").  Вы
не можете удалить этот класс командами Remove или Delete All.

                     Просмотр сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     ЪДДДДДДДДДДДДДДДДДДДДДДДДї
     і Send to log window   Noі       Передача в окно регистрации
     і Erase log              і       Стереть регистрацию
     АДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Оконные сообщения  выводятся  в  нижней области окна Windows
Messages. Эта область может содержать до 200 сообщений.

     Если вы  хотите сохранить сообщения в файле,  вы должны отк-
рыть файл журнала для окна Log (выбрав команду ViewіLog File (Об-
зоріФайл  регистрации),  а  затем команду Open Log File (Открытие
файла регистрации) из локального меню).  Затем вы должны  перейти
обратно в область Messages (Сообщения) и изменить  установку Send
To  Log  Window  (Передача  в окно регистрации) локального меню в
значение Yes (это означает, что запись в протокол разрешена).

     Если вы  хотите очистить область от всех сообщений, выберите
команду Erase Log (Стереть протокол) из локального меню. На сооб-
щения, записываемые в окно Log (Регистрация), эта команда не вли-
яет.

                Замечания по сообщениям окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы выводите сообщения более чем для одного окна,  то не
регистрируйте  все  сообщения.  Регистрируйте  вместо  этого  для
каждого окна конкретные сообщения или конкретный класс сообщений,
поскольку  большое число сообщений,  передаваемых между Windows и
TDW может привести к "зависанию" системы.

     При установки прерывания по классу сообщений от "мыши" нужно
учитывать,  что перед тем,  как снова станет активной клавиатура,
за  сообщением mouse down (перемещение "мыши" вниз) должно следо-
вать сообщение mouse up (перемещение "мыши" вверх). Это ограниче-
ние означает,  что когда вы возвращаетесь в прикладную программу,
вам может потребоваться несколько раз нажать кнопку "мыши", чтобы
получить  сообщение mouse up.  Вы узнаете,  что в Windows принято
сообщение,  когда увидите  его  в  нижней  области  окна  Windows
Messages (Сообщения Windows).

     Если вы вводите имя описателя, но указываете, что это проце-
дура, TDW будет воспринимать ваш ввод. Однако, когда вы запустите
программу,  TDW  не будет регистрировать никаких сообщений.  Если
TDW не регистрирует сообщения после того,  как вы установили опи-
сатель, чтобы увидеть, выбрали ли вы "кнопку" Handle (Описатель),
проверьте диалоговое окно Set Message Filter (Задание фильтра со-
общений).

        Получение содержимого памяти и списка модулей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для получения содержимого глобальной или  локальной  динами-
чески распределяемой  области  или списка модулей вашей программы
для Windows сначала вызовите окно Log командой ViewіLog (Просмотр
іПротокол:), а затем вызовите локальное меню.  Последней командой
локального  меню  окна Log (Регистрация) является команда Display
Windows info (Вывод информации Windows). Выбор этой команды вызо-
вет на экран окно диалога Windows Information, из которого вы мо-
жете выбрать тип списка,  который вы хотите вывести на экран, и с
какого места начать вывод.

              Й[*]НННННWindows informationНННННННН»
              є Display                           є
              є   (*) Global heap         OK±±±±  є
              є   ( ) Local heap                  є
              є   ( ) Module list         Cancel  є
              є                           ±±±±±±  є
              є Started at                        є
              є   (*) Top                 Help    є
              є   ( ) Bottom              ±±±±±±  є
              є   ( ) Handle                      є
              є                                   є
              є Starting handle                   є
              є                    є
              є                                   є
              ИНННННННННННННННННННННННННННННННННННј

     Рис. 17.6 Диалоговое окно Windows information

     Windows information - информация Windows;  Display -  вывод:
Global heap - глобальная динамически распределяемая область памя-
ти; Local heap - локальная динамически распределяемая область па-
мяти;  Module  list - список модулей;  Started at - начало на...;
Top - вершина;  Bottom -  конец;  Handle  -  описатель;  Starting
handle - начальный описатель;  not avaliable - недоступно; Cancel
- отмена; Help - справка.

     Если вы выбрали параметр вывода содержимого глобальной дина-
мически распределяемой области памяти, то вы можете выбрать вывод
с  верхнего адреса динамически распределяемой области до нижнего,
с нижнего до верхнего, либо с позиции, определяемой начальным ло-
гическим номером (описателем).

     Начальный логический номер - это имя логического номера гло-
бальной памяти, устанавливаемого в вашей прикладной программе при
вызове   подпрограммы   выделения   памяти   Windows,    например
GlobalAlloc. Выбор начального логического номера  заставляет  TDW
вывести на экран объект, соответствующий этому логическому номеру
(описателю), а также следующие за ним четыре объекта в динамичес-
ки распределяемой памяти.

                Получение списка содержимого
          глобальной динамически распределяемой памяти
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Глобальная динамически распределяемая память -  это  область
глобальной  памяти,  которую  Windows  делает  доступной для всех
прикладных программ. Если вы выделяете такие ресурсы, как пиктог-
раммы, элементы изображения, диалоговые окна или шрифты, либо ес-
ли вы выделяете память при помощи функции GlobalAllc,  ваша прик-
ладная программа будет использовать глобальную динамически  расп-
ределяемую область памяти.

     Для получения списка объектов данных в глобальной динамичес-
ки распределяемой  области  выберите  селективный   переключатель
Global  Heap (Глобальная динамически распределяемая область памя-
ти) в окне диалога Windows Information,  а затем выберите  "кноп-
ку" OK.  Объекты  данных  будут перечислены в окне Log (Регистра-
ция).  Поскольку этот список скорее всего  превысит  число  строк
окна Log (по умолчанию это число равно 50),  вы должны либо запи-
сать содержимое в файл журнала (при помощи локального  меню  окна
Log)  или увеличить число строк,  которое может использовать окно
Log (для этого служит утилита TDINST).  Можно установить максимум
до 200 строк.

     Следующая таблица  показывает пример с двумя строками вывода
для глобальной  динамически  распределяемой области памяти и дает
объяснения по каждому их полю:

    Формат вывода глобальной динамически распределяемой области
                                                     Таблица 17.2
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і0EC5      00000040b PDB (OF1D)                                 і
і053 (053D)00002DC0b GDI DATA MOVEABLE LOCKED=0001 PGLOCKED=0001і
ГДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іПоле          і Описание                                       і
ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іOEC5          іОписатель или объект памяти, выраженный         і
і              ів виде шестнадцатиричного значения из 4 цифр илиі
і              іслова FREE, что указывает на свободный блок     і
і              іпамяти.                                         і
і              і                                                і
і(053D)        іСелектор памяти, указывающий на запись в таблицеі
і              іглобальных дескрипторов. Если у него то же      і
і              ізначение, что и у описателя памяти, то селектор і
і              іне выводится.                                   і
і              і                                                і
і00000040b     іШестнадцатиричное число, представляющее длину   і
і00002DC0b     ісегмента в байтах.                              і
і              і                                                і
іPDB           іДля кого распределяется сегмент. Обычно это     і
іGDI           іприкладная программа или библиотечный модуль.   і
і              іPDB - это блок описания процесса, который       і
і              іназывают также префиксом программного сегмента  і
і              іPSP.                                            і
і              і                                                і
і(0F1D)        іОписатель, указывающий на владельца PDB.        і
і              і                                                і
іDATA          іТип объекта памяти. Тип может быть следующим:   і
і              і DATA - сегмент данных прикладной программы или і
і              і        DLL                                     і
і              і CODE - сегмент кода прикладной программы или   і
і              і        DLL                                     і
і              і PRIV - системный объект или глобальные данные  і
і              і        для прикладной программы или DLL.       і
і              і                                                і
іMOVEABLE      іАтрибут распределения памяти. Объект может      і
і              іиметь атрибуты FIXED, MOVEABLE или MOVEABLE     і
і              іDISCARDABLE.                                    і
і              і                                                і
іLOCKED=00001  іДля объекта MOVEABLE или MOVEABLE DISCARDABLE   і
і              іэто число блокировок объекта, который           і
і              іиспользуется с помощью функции GlobalLock или   і
і              іLockData.                                       і
і              і                                                і
іFGLOCKED=00001іДля улучшенного режима 386 число блокировок     і
і              істраниц для объекта, который использует         і
і              іфункцию GlobalPageLock. Если страничная         і
і              іблокировка установлена на объект памяти, то     і
і              іWindows не может выгрузить на диск ни одну      і
і              іиз 4-килобайтовых страниц объекта.              і
АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

истинг содержимого локальной динамически распределяемой области
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Локальная динамически  распределяемая  область  памяти - это
частная область памяти для прикладной программы. Для других прик-
ладных  программ  Windows (включая другие экземпляры той же прог-
раммы) она недоступна.

     Программа не обязательно имеет локальную динамически распре-
деляемую  область  памяти.  Windows создает локальную динамически
распределяемую область  памяти  прикладной  программы  с  помощью
функции LocalAlloc.

     Чтобы просмотреть список объектов данных в локальной динами-
чески распределяемой области памяти,  выберите селективный перек-
лючатель Local Heap (Локальная динамически распределяемая область
памяти)  в  диалоговом  окне  Windows   Information   (Информация
Windows), затем выберите "кнопку" OK. В окне Log (Протокол) выве-
дется список объектов данных.

     Поскольку размер списка будет вероятно превышать число строк
в  окне Log (по умолчанию 50),  вам следует записать содержимое в
файл регистрации (с помощью локального меню окна Log) или  увели-
чить  число строк в окне Log (с помощью программы TDWINST). Можно
задать до 200 строк.

     В следующей таблице приведена типичная строка вывода локаль-
ной  динамически  распределяемой области с последующим пояснением
ее формата.

ормат вывода локальной динамически распределяемой области
                                                     Таблица 17.3
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і 05CD:    0024   BUSY   (10AF)                                 і
ГДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Поле        і Описание                                        і
ГДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і OEC5        і Смещение объекта в локальном сегменте данных.   і
і             і                                                 і
і 0024        і Длина объекта в байтах.                         і
і             і                                                 і
і BUSY        і Размещение объекта памяти:                      і
і             і  FREE - нераспределенный блок памяти;           і
і             і  BUSY - распределенный объект.                  і
і             і                                                 і
і (10AF)      і Описатель локальной памяти для объекта.         і
АДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                  Получение списка модулей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы увидеть список модулей задачи или DLL,  которые загру-
жены Windows,  выберите  селективный  переключатель  Module  List
(Список модулей) в диалоговом окне Windows Information  (Информа-
ция Windows), затем выберите "кнопку" OK. Список модулей выведет-
ся в окне Log (Протокол).

     В следующей таблице показан пример - три выводимые строки
списка модулей с последующим пояснением по каждому полю.

    Формат вывода списка модулей Windows (Таблица 17.7)
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іПример вывода списка модулей                                   і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і0985 TASK TDW      C:\TD\TDW.EXE                               і
і0E2D DLL  WINDEBUG C:\WIN3\WINDEBUG.DLL                        і
і0EFD TASK GENERIC  C:\TD\GENERIC.EXE                           і
ГДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іПоле              і               Описание                     і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і0EFD              іЛогический номер сегмента памяти, выраженныйі
і                  і4-значным шестнадцатиричным значением.      і
і                  і                                            і
іTASK              іТип модуля. Модуль может быть либо задачей, і
і                  ілибо DLL.                                   і
і                  і                                            і
іGENERIC           іИмя модуля.                                 і
і                  і                                            і
іC:\TD\GENERIC.EXE іМаршрут к выполняемому файлу модуля.        і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

       Отладка динамически компонуемых библиотек (DLL)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     DLL представляет  собой  библиотеку  подпрограмм  и ресурсов
Windows,  компонуемых с вашей прикладной программой во время  вы-
полнения,  а не компиляции.  Такая компоновка во время выполнения
позволяет нескольким прикладным программам разделять  одну  копию
подпрограмм,  данных  или драйверов устройств,  экономя тем самым
память.  При запуске прикладной программы,  использующей  DLL,  в
случае,  если DLL еще не загружена в память, Windows загружает ее
таким образом, чтобы программе стали доступны ее точки входа.

     При загрузке в TDW прикладной программы,  с которой компону-
ются DLL,  TDW определяет,  какие из этих библиотек DLL (если они
используются) имеют таблицы имен идентификаторов (были  скомпили-
рованы с параметром включения отладочной информации) и трассирует
для вас эти библиотеки. Если во время выполнения прикладной прог-
раммы  TDW встречает вызов точки входа одной из этих DLL,  то TDW
загружает таблицу имен идентификаторов и исходный код этой библи-
отеки  и устанавливает маркер строки модуля в начало подпрограммы
DLL, вызываемой прикладной программой. Затем DLL становится в ок-
не Module, так же как и коды вашей прикладной программы.

          Примечание: Отладчик TDW может загрузить DLL,  не имею-
     щую  таблицы  имен  идентификаторов,  но только в окно CPU и
     только при отладке именно в окне CPU.

     При выходе из подпрограммы  DLL  TDW  перезагружает  таблицу
имен идентификаторов и исходный код вашей программы и  устанавли-
вает маркер строки на следующий оператор после вызова точки входа
DLL.

     Если вы выполняете трассировку программы с помощью клавиш F7
и F8,  для TDW может оказаться невозможным возврат  в  вызывающую
программы из подпрограммы,  поскольку DLL может возвращать управ-
ление через  вызов функции Windows.  В этом случае ваша программа
просто выполняется так,  как если бы вы нажали клавишу F9.  Такое
проведение  является общим для кода начальной загрузки библиотеки
DLL.  Чтобы принудительно вернуться в прикладную программу  перед
началом трассировки прикладной программы до вызова DLL установите
в вашей прикладной программе точку останова на строке после обра-
щения к DLL. При отладке кода начальной загрузки DLL (кода иници-
ализации) установите точку останова на первой  строке  прикладной
программы.

     Поскольку отладка DLL в  TDW  значительно  автоматизирована,
вам не нужно задавать, какую DLL нужно загрузить. Однако, вам мо-
жет понадобиться выполнить и другие задачи, например:

     - Добавить DLL в список DLL;

     - Установить точки останова,  прерывания,  слежения и т.д. в
       DLL;

     - Задать, какие DLL TDW не должен загружать;

     - Отладить начальный код загрузки DLL.

     Для выполнения любой из этих задач вы должны  войти  в  окно
диалога Load Modules or DLLs ("Загрузка модулей или DLL") при по-
мощи команды ViewіModules (ОбзоріМодули).  (Это  диалоговое  окно
также выводится при нажатии клавиши F3).

     Й[*]ННННННННННLoad modules or DDL symbolsНННННННННННННННННН»
     є                                                          є
     є Source modules            DDLs & Programs                є
     є ±demo±±±±±±±±±±±  Load    ±SCRNFUNC.DDL*±±  Symbol load  є
     є ±±±±±±±±±±±±±±±±          ±DEMO.EXE*±±±±±±  °°°°°°°°°°°  є
     є ±±±±±±±±±±±±±±±±  Cancel  ±WINDEBUG.DDL±±±  Load symbols є
     є ±±±±±±±±±±±±±±±±          ±WREMOTE.EXE±±±±   ( )  No     є
     є ±±±±±±±±±±±±±±±±  Help    ±NWPOPUP.EXE±±±±   (*)  Yes    є
     є ±±±±±±±±±±±±±±±±  °°°°°   ±PROGRAM.EXE±±±±               є
     є ±±±±±±±±±±±±±±±±          ±USER.EXE±±±±±±±  Debug startupє
     є ±±±±±±±±±±±±±±±±          ±GDI.EXE±±±±±±±±   ( )  No     є
     є ±±±±±±±±±±±±±±±±          ±KRNL386.EXE±±±±   (*)  Yes    є
     є ±±±±±±±±±±±±±±±±          ±±±±±±±±±±±±±±±±               є
     є ±±±±±±±±±±±±±±±±                                         є
     є ±±±±±±±±±±±±±±±±          DDL name                       є
     є ±±±±±±±±±±±±±±±±          ±±±±±±±±±±±±±±±±  Add DDL      є
     є ±±±±±±±±±±±±±±±±          ±±±±±±±±±±±±±±±±  °°°°°°°°°°°  є
     є                                                          є
     ИННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

     Рис. 17.7 Диалоговое окно Load modules or DDLs

     Load modules or DDL symbols - загрузка модулей или идентифи-
каторов DDL;  Source modules - исходные модули; DDLs & Programs -
библиотеки DDL и программы;  Load - загрузка;  Symbol load - заг-
рузка идентификаторов;  Cancel  - отмена;  Help - справка;  Debug
startup - отладка кода инициализации; Add DDL - добавить DDL; DDL
name - имя библиотеки DDL.

     Использование диалогового окна Load Modules or DLLs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Это диалоговое окно позволяет:

     - Перейти к другому исходному модулю вашей прикладной  прог-
       раммы;

     - Выполнить операции (такие, как загрузка файла имен иденти-
       фикаторов и исходного файла) с DLL и файлами .EXE.

             Переход к другому исходному модулю
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы отлаживаете прикладную программу,  состоящую из нес-
кольких исходных модулей,  скомпонованных в один файл .EXE, и вам
нужен доступ к модулю программы,  отличному от текущего загружен-
ного  в окно Module,  вы можете вызвать окно Load Modules or DLLs
(Загрузка модулей или DDL) и выбрать  один  из  модулей  в  левом
списке,  который  называется Source Modules (Исходные модули).  В
этом списке перечислены все модули,  скомпонованные в вашей прик-
ладной программе.

     Для того, чтобы выбрать модуль, выделите его, нажмите клави-
шу Enter или дважды нажмите кнопку  "мыши",  либо  выберите  окно
Load (Загрузка). Отладчик TDW выведет на дисплей окно Module (Мо-
дуль), и в нем будет находиться новый исходный модуль.

                 Работа с DLL и программами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При отладке прикладной программы, с которой связана одна или
более DLL (это верно для любых прикладных программ  для Windows),
и  вы вызвали окно диалога Load Modules or DLLs (Загрузка модулей
или DDL),  вы увидите там список DLLs & Programs (DLL и  програм-
мы), в котором перечислены DLL и файлы .EXE. Этот список включает
в себя все DLL и файлы .EXE,  загруженные Windows в  текущий  мо-
мент,  а также все библиотеки DLL,  запускаемые при запуске прик-
ладной программы.  Он не включает DLL,  которые  ваша  прикладная
программа  запускает вызовом LOADLIBRARY,  если только они уже не
загружены программой или Windows.

     Элементы в верхней части списка,  помеченные справа многото-
чием, это файлы .EXE вашей прикладной программы и DLL с таблицами
имен идентификаторов, вызываемые вашей прикладной программой. Ес-
ли вы не не делали изменений, отладчик TDW автоматически загружа-
ет таблицу имен идентификаторов и исходный код для  каждой  поме-
ченной  DLL,  всякий  раз при вызове этой DLL из вашей программы.
Кроме того,  TDW автоматически загружает таблицу имен идентифика-
торов и исходный код любой библиотеки DLL, которую ваша программа
запускает вызовом LOADLIBRARY,  даже хотя сначала эта DLL может и
не  присутствовать в списке.  (Она там появится после загрузки ее
TDW).

     "Кнопки" справа от списка позволяют выполнять операции с вы-
деленными вами DLL или прикладными программами.  Окно  текстового
ввода под списком позволяет добавить в список DLL.  Вы можете ис-
пользовать эти средства следующим образом:

  Управляющие "кнопки"окна диалога DLLs & Programs  Таблица 17.5
ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Кнопка            і                 Описание                  і
ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і Symbol load       і Загружает таблицу имен идентификаторов и  і
і                   і исходные файлы для DLL или прикладной     і
і                   і программы. Эта команда изменяет содержимоеі
і                   і окна Module (Модуль), и вы можете         і
і                   і устанавливать точки останова, сообщения   і
і                   і Windows, и т.д. для DLL.                  і
і                   і                                           і
і Load Symbols      і Задает, загружать ли таблицу имен         і
і (No/Yes)          і идентификаторов DLL и ее исходный код,    і
і                   і когда прикладная программа вызывает DLL.  і
і                   і Вы можете использовать этот параметр,     і
і                   і чтобы предотвратить загрузку данной       і
і                   і информации для библиотеки, которая не     і
і                   і требует отладки. По умолчанию будет       і
і                   і установлено значение Yes (Да).            і
і                   і                                           і
і Debug startup     і Задает, нужно ли отлаживать код начальной і
і (No/Yes)          і загрузки DLL. По умолчанию устанавливаетсяі
і                   і No (Нет).                                 і
і                   і                                           і
і DLL Name          і Введите имя DLL, отсутствующей в списке   і
і                   і DLLs & Programs (DDL и программы), чтобы  і
і                   і добавить библиотеку в этот список.        і
і                   і Добавление DLL в список позволит затем    і
і                   і использовать для этой DLL одну из трех    і
і                   і предыдущих команд. При необходимости можноі
і                   і задать полный маршрут.                    і
і                   і                                           і
і Add DLL           і Добавить DLL в текущий блок текстового    і
і                   і ввода в список DLLs & Programs.           і
АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

           Добавление DLL в список DLLs & Programs
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Прежде чем вы сможете установить отладочные параметры, необ-
ходимость отлаживать начальный код  загрузки  DLL  или  загружать
таблицу  имен идентификаторов и исходный код DLL,  эта DLL должна
быть внесена в список DLL & Programs (DLL и программы). Библиоте-
ка  DLL,  к которой обращается ваша программа,  может и не быть в
этом списке,  поскольку сразу после загрузки программы TDW  знает
только  о DLL,  компонуемых с начальным кодом загрузки прикладной
программы.  Программа может также запустить DLL явно,  при помощи
команды LOADLIBRARY.  TDW не знает об этом до вызова LOADLIBRARY.

     Существует два различных типа кода начальной загрузки,  упо-
минаемые в данном разделе:  начальный код загрузки вашей приклад-
ной программы и начальный код загрузки DLL. Некоторые динамически
компонуемые библиотеки  DLL  запускаются начальным кодом загрузки
вашей прикладной программы.  Когда ваша программа запускает  DLL,
выполняется начальный код загрузки DLL.

     Если вы хотите добавить DLL в список DLLs & Programs,  вызо-
вите диалоговое окно Load Modules or DLLs (Загрузка  модулей  или
DDL)  (нажмите  клавишу  F3  или используйте команду ViewіModules
(ОбзоріМодули)), перейдите к блоку текстового ввода DLL Name (имя
DLL),  введите имя DLL (если необходимо, введите полный маршрут),
и активизируйте "кнопку" Add DLL,  чтобы добавить это имя в  спи-
сок.

            Установка параметров отладки для DLL
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы  хотите установить для DLL точки останова или слеже-
ния,  или еще какие-либо параметры отладки, вызовите окно диалога
Load  Modules or DLLs (Загрузка модулей или DDL) (нажмите клавишу
F3 или выберите команду ViewіModules),  найдите DLL в списке DLLs
& Programs,  выделите его и затем используйте команду Symbol Load
(Загрузка идентификатора), чтобы получить окно Module с этой биб-
лиотекой DLL в нем.  В окне Module (Модуль) вы можете выполнить с
DLL интересующие вас операции.

  Управление загрузкой TDW таблиц имен идентификаторов DLL
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     По умолчанию  TDW  загружает  таблицу имен идентификаторов и
исходный код для каждой DLL, к которой обращается ваша прикладная
программа,  но  только  если  DLL  имеет совместимую таблицу имен
идентификаторов.  DLL имеет таблицу имен идентификаторов, совмес-
тимую с TDW. При компиляции с включенной информации для отладки и
с помощью компилятора Турбо Паскаля для Windows DLL содержит таб-
лицу идентификаторов, совместимую с TDW.

     Поскольку загрузка  отладочной  информации  для  DLL и затем
загрузка отладочной информации для прикладной программы после то-
го,  как DLL отработает,  занимает время,  вам может понадобиться
отменить стандартные действия для DLL, которую вы не хотите отла-
живать.  Чтобы  TDW  не загружал таблицу имен идентификаторов для
DLL, вызовите окно диалога Load Modules or DLLs (нажатием клавиши
F3 или командой ViewіModules), найдите имя этой DLL в списке DLLs
& Programs,  выделите  его  и активизируйте "кнопку" Load Symbols
(Загрузка идентификаторов) со значением No (Нет).

            Отладка начального кода загрузки DLL
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     По умолчанию TDW не отлаживает начальный код загрузки DLL, а
только  загружает  таблицу  имен идентификаторов DLL,  когда ваша
прикладная программа вызывает точку входа этой DLL. Затем TDW вы-
зывает окно Module (Модуль) или CPU (ЦП) с маркером текущей стро-
ки на начале подпрограммы DLL, вызванной прикладной программой.

     Отладчик TDW будет отлаживать начальный  код  загрузки  DLL,
если вы явно зададите это. Вы можете использовать TDW для отладки
любого из двух типов начального кода загрузки DLL.

       Какого рода начальный код загрузки вы отлаживаете

     - Код инициализации, непосредственно после LibMain (по умол-
       чанию).

     - Ассемблерный  код,  скомпонованный с DLL,  выполняющий на-
       чальную загрузку и содержит  эмулированные  математические
       пакеты  для используемой DLL модели памяти (выбираемой при
       запуске TDW параметром командной строки -l).

     После того,  как вы задали отладку начального кода  загрузки
одной  или  более  DLL вашей прикладной программы,  TDW загружает
таблицу имен идентификаторов для каждой библиотеки DLL либо когда
начальный  код  загрузки вашей прикладной программы запускает эту
DLL,  либо  когда  прикладная   программа   явно   делает   вызов
LOADLIBRARY.

           Загружена ли уже ваша прикладная программа?

     Если вы пытаетесь загрузить прикладную программу,  а уже за-
тем задать отладку начального кода загрузки,  отладчик TDW  может
повести  себя  иначе,  чем вы ожидали,  так как некоторые или все
библиотеки DLL могут уже оказаться  загруженными.  Следовательно,
задавать отладку начального кода нужно:

     - Установив  отладку  для  DLL  до загрузки вашей прикладной
       программы.

     - Загрузив вашу прикладную программу, указав DLL для отладки
       начального  кода загрузки,  а затем перезапустив программу
       (Ctrl-F2 или RunіProgram Reset).

           Выполнение отладки начального кода загрузки

     Учитывая все эти предварительные замечания,  используйте для
задания  отладки начального кода загрузки для одной или более DLL
и для отладки начального кода загрузки этих  библиотек  следующие
шаги:

     1. Вызовите окно диалога Load Modules or DLL (нажмите F3 или
        воспользуйтесь командой ViewіModules (ОбзоріМодули).

     2. Найдите DLL в списке DLLs & Programs и выделите ее.

     3. Активизируйте "кнопку" Debug Startup (Отладка кода иници-
        алиазции) значением Yes (Да).

     4. Повторите шаги 2 и 3, пока вы не зададите отладку началь-
        ного  кода  загрузки для всех библиотек DLL,  для которых
        это необходимо.

     5. Если нужная вам DLL находится не в списке  или  в  списке
        нет  DLL  (поскольку вы еще не загрузили прикладную прог-
        рамму),  используйте поле текстового ввода DLL  Name  для
        ввода каждого имени DLL и добавления его в список при по-
        мощи "кнопки" Add DLL (Добавление DLL),  а затем выберите
        "кнопку"  Debug Startup Yes (Отладка начального кода раз-
        решена).

     6. После того, как вы установили все DLL, для которых вы хо-
        тите отлаживать начальный код загрузки,  следующим  шагом
        будет   либо   загрузка   при  помощи  команды  FileіLoad
        (ФайліЗагрузка) вашей прикладной программы (если  вы  еще
        ее не загрузили),  либо перезагрузка программы при помощи
        команды RunіProgram  Reset  (ВыполнениеіСброс  программы)
        (если вы загрузили ее до того, как задали отладку началь-
        ного кода загрузки).

     7. Перед выполнением прикладной программы вам следует  уста-
        новить  точки  останова,  чтобы после выполнения кода на-
        чальной загрузки DLL возвращаться в прикладную программу.
        Когда в окне Module  находится  исходный  код  прикладной
        программы, сделайте следующее:

          а) установите на  первой  строке  прикладной  программы
             точку останова;

          б) если вы отлаживаете код начальной загрузки для какой-
             либо из DLL,  загруженной вызовом LoadLibrary, уста-
             новите точку останова на первой  строке  кода  после
             каждого из этих вызовов.

     7. Когда ваша прикладная программа запускает каждую  из DLL,
        отладчик  TDW  выводит либо LibMain DLL в окне Module (по
        умолчанию),  либо начало листинга ассемблерного кода  на-
        чальной загрузки библиотеки в окне CPU (так как TDW запу-
        щен с параметром -l).

     8. Когда вы закончили отлаживать начальный код загрузки DLL,
        нажмите клавишу F9 для того, чтобы выполнить до конца на-
        чальный код загрузки и вернуться к  прикладной программе.
        Если вы задали еще другие библиотеки DLL для отладки  на-
        чального  кода  загрузки,  TDW выводит на экран начальный
        код для этих библиотек DLL, как только программа запуска-
        ет каждую из них.

     Не забудьте выполнить до конца начальный код  загрузки  DLL,
прежде  чем перезагрузить текущую прикладную программу или загру-
зить новую.  Если вы забудете сделать это,  частично  выполненный
начальный код DLL может привести к тому,  что Windows "зависнет",
и вам придется перезагружаться.

          Преобразование описателей памяти в адреса
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Windows использует для объектов не адреса памяти, а логичес-
кие номера (описатели) памяти,  так как выполняет собственную ор-
ганизацию памяти и может изменить физическое расположение объекта
в памяти. Если вам нужен фактический адрес, соответствующий логи-
ческому номеру, вы можете использовать для этого встроенные имена
Турбо  отладчика  -  lh2fp  (для  локальных логических номеров) и
gh2fp (для глобальных логических номеров) для обращения по  логи-
ческому номеру к адресу памяти.

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

     - Вы можете использовать окно DataіInspect (ДанныеіПроверка)
       для вычисления следующего выражения:

         (lh2fp) hLocalMemory

     - Вы можете использовать команду Type Cast (Приведение типа)
       окна Inspector (Проверка) и ввести там  lh2fp  в  качестве
       типа.

     В любом  случае  выражение  вычисляется  для первого символа
блока памяти, на который указывает HLocalMemory.

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

     (Mystruct far *) (lh2fp)hLocalMemory

                   Рекомендации по отладке
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поскольку прикладные программы для Windows являются интерак-
тивными программами,  лучший способ отладки состоит в том,  чтобы
запустить ее и останавливать в точках останова.

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

     При пошаговом режиме в цикле приема сообщения вы можете  на-
жать  комбинацию  клавиш  Alt-F5,  чтобы  видеть экран прикладной
программы, но вы не сможете с ней взаимодействовать. Для этого вы
должны нажать клавишу F9 для запуска программы, чтобы видеть окна
программы,  однако как быть, если вам нужно попасть обратно в TDW
для трассировки ошибки,  которую вы обнаружили, пока использовали
одно из окон вашей программы?

     В случае прикладной программы для DOS вы можете нажать Ctrl-
Break, чтобы прервать программу и вернуться к Турбо отладчику,од-
нако в случае Windows эта команда не работает.  Однако,  и  здесь
есть   способ   прервать  программу:  нажмите  комбинацию  клавиш
Ctrl-Alt-SysRq.  Попав обратно в TDW,  вы можете установить точки
останова для кода и сообщений,  задать выражения просмотра, прос-
мотреть все сообщения, зарегистрированные в протоколе, или выпол-
нить любые другие действия по локализации ошибки.  Как только  вы
будете готовы вернуться в отлаживаемую программу, нажмите клавишу
F9.

     Когда ваша программа прервана, нельзя делать следующее:

     - Продолжить отладку пошаговым выполнением.  Попытка пошаго-
       вого выполнения после того, как произошло прерывание, при-
       ведет к непредсказуемым результатам,  поскольку ваша прог-
       рамма  могла  выполнять код Windows.  Обычно в этом случае
       Windows завершает как вашу  прикладную  программу,  так  и
       TDW,  выводя сообщение:  "Unrecoverable application error"
       ("Невосстановимая ошибка прикладной программы").

     - Если ваша прикладная программа выполняла код  Windows,  не
       завершайте выполнение ни прикладной программы, ни отладчи-
       ка TDW.  Если вы это сделаете,  то Windows может сбиться и
       "зависнуть",  и вам придется перезагружать систему. Если в
       этой ситуации вы попытаетесь выйти из программы или  пере-
       загрузить ее, TDW выведет диалоговое окно с запросом:

       Ctrl-Alt-SysRq interrupt. System crash possible. Continue ?
       (Прерывание по Ctrl-Alt-SysRq. Возможен сбой системы. Про-
       должить?)

                  Сообщения об ошибках TDW
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Существует два сообщения об  ошибке,  возвращаемые  исключи-
тельно отладчиком TDW. Кроме того, могут возвращаться и сообщения
об ошибках Турбо отладчика,  распространяющиеся и на работу  TDW,
например "Symbol not found" в ответ на несуществующее имя оконной
процедуры.

     Ctrl-Alt-SysRq interrupt. System crash possible. Continue ?
     (Прерывание по Ctrl-Alt-SysRq.  Возможен сбой системы.  Про-
     должить?)

     Вы пытались либо выйти из TDW, либо перезагрузить отлаживае-
мую  прикладную программу,  когда программа была приостановлена в
результате нажатия клавиш Ctrl-Alt-SysRq. Поскольку в момент при-
остановки программы выполнялся код ядра Windows, выход из TDW или
перезагрузка прикладной программы может привести к  непредсказуе-
мым результатам (вероятнее всего, к зависанию системы и необходи-
мости ее перезагрузки).

     Если это возможно,  установите в коде точку останова и снова
запустите программу.  Когда ваша программа встретит эту точку ос-
танова и выйдет в TDW, вы можете завершить работу с TDW или пере-
загрузить вашу программу.

     Invalid window handle
     (Неверный логический номер окна)

     Пытаясь установить  регистрацию  сообщений  для  окна  вашей
программы, вы  ввели  имя переменной логического номера (описате-
ля), которой не был присвоен логический номер. Пройдите в пошаго-
вом режиме до оператора,  где этот логический номер присваивается
переменной, и попробуйте снова ввести это имя.

     Глава 18. Отладка прикладной программы для Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В данной главе описывается  отладка  стандартной  прикладной
программы Windows,    написанной    без    библиотечного   класса
ObjectWindow.

     Как было сказано в Главе 17,  отладка  прикладной  программы
для  Microsoft  Windows во многом похожа на отладку программы для
DOS,  особенно если речь идет об интерактивной программе для DOS.
Все методы  отладки,  описанные в Главе 14,  "Отладка программы",
применимы также и для программы для Windows.

     Поскольку прикладная программа для Windows использует интер-
фейс   прикладных   программ  для  Windows  (Application  Program
Interface - API),  существует множество  дополнительных  способов
работы с программой. Данная глава не претендует на то, чтобы нау-
чить вас способам безошибочного программирования  в  Windows.  Ее
цель состоит в том, чтобы продемонстрировать средства TDW на при-
мере отладки прикладной программы.

                      Примеры программ
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     С  отладчиком  TDW поставляются три примера программ,  и все
они требуют наличия "мыши". Это программы:

     - BCWDEMO.EXE,  выполняемый файл программы Simple Paint. Эта
       программа позволяет строить линии, эллипсы и прямоугольни-
       ки тремя цветами и тремя толщинами линии. Она устанавлива-
       ется для работы под управлением менеджера программ,  и мо-
       жет  быть  вызвана  посредством   выбора   соответствующей
       пиктограммы. Вместе с BCWDEMO.EXE также поставляются файлы
       исходного текста, BCWDEMO.C, и файл проекта, BCWDEMO.PRJ.

     - BCWDEMOA.EXE, выполняемый файл, который содержит все ошиб-
       ки.  С  ним  также  поставляются  файлы  исходного текста,
       BCWDEMOA.C, и файл проекта, BCWDEMOA.PRJ.

     - BCWDEMOB.EXE, выполняемый файл, который содержит все те же
       ошибки,  что и BCWDEMOA, кроме первой. С ним также постав-
       ляются файлы исходного текста, BCWDEMOB.C, и файл проекта,
       BCWDEMOB.PRJ.

     Кроме того,  имеется  несколько файлов,  общих для всех трех
версий программы, а именно:

     - BCWDEMO.DEF, это файл определения модуля.

     - BCWDEMO.H, это файл заголовка.

     - BCWDEMO.RC, это исходный  файл  для  получения  ресурсного
       файла.

     - BCWDEMO.RES это скомпилированный ресурсный файл.

      Компиляция и компоновка демонстрационных программ
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вам предоставляется три версии  демонстрационной  программы,
которые упрощают изучение данной главы. При желании вы можете са-
ми внести  изменения  в  эти  программы.  С  помощью  компилятора
Borland C++ вы можете скомпилировать и скомпоновать их в интерак-
тивной среде разработки разработки  программ  Borland,  используя
имеющиеся файлы проекта.

     Более подробную информацию о компиляции программ для Windows
с  использованием файлов проекта см.  в "Руководстве пользователя
для Borland C++."

                 Отладка программы BCWDEMOA
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

          Примечание: Прежде чем начать сеанс отладки,  вы можете
     немного  поэкспериментировать  с BCWDEMO.EXE,  чтобы понять,
     что собственно должна делать эта программа.

     Первая отлаживаемая программа называется BCWDEMOA. Запустите
Windows,  TDW и запустите BCWDEMOA.  Когда в окне Module появится
исходный  код  программы,  нажмите клавишу F9 для запуска примера
программы.

     На экране появится курсор в виде "песочных  часов",  который
означает,  что программа работает и выполняет некоторые действия.
Обычно курсор в виде часов скоро исчезает, и на его месте появля-
ется курсор в виде стрелки.  Если песочные часы не исчезают, зна-
чит, что-то происходит неверно.

     Чтобы перейти  в  TDW  для выяснения причин неверной работы,
нажмите клавиши Ctrl-Alt-SysRq,  чтобы  приостановить  выполнение
программы.

           Принятие решения о дальнейших действиях
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     После того, как вы оказались в TDW, следующим шагом вы долж-
ны решить,  каким именно образом выяснить, что в программе невер-
но.  Обычно если прикладная программа для Windows зависает  и  не
позволяет судить о ходе ее выполнения,  вы перезагружаетесь и на-
чинаете пошаговую отладку подпрограмм инициализации  окна.  Дойдя
до  цикла  сообщений,  вы  можете  задать  регистрацию  сообщений
Windows, можете установить их регистрацию,  чтобы  затем  посмот-
реть, какие сообщения поступают в программу.

     Так как  исходный  экран программы все же был отображен,  вы
знаете, что программа дошла до цикла сообщений, поскольку для то-
го, чтобы нарисовать этот экран, она должна была обрабатывать со-
общения Windows.  Следовательно,  вы можете вместо пошагового вы-
полнения сразу же перейти к регистрации  сообщений.  Зная,  какие
сообщения  были  обработаны,  вы как минимум будете знать,  какие
участки кода программы были выполнены.

                     Завершение BCWDEMOA
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В этой точке вы можете задать, какие сообщения вы хотите ре-
гистрировать,  и вернуться к программе,  нажав клавишу F9, однако
выйдя из программы и снова запустив ее, вы сможете получить более
точную картину происходящего. Поскольку с помощью клавиш Ctrl-Alt
-SysRq вы только приостановили выполнение программы,  то выход из
программы в этой точке может привести к зависанию системы (если в
момент  приостановки  выполнялось  ядро Windows).  Для завершения
программы выполните следующие шаги:

     1. Перезагрузите   программу   командой   RunіProgram  Reset
        (ВыполнениеіСброс программы) (клавиши Ctrl-F2).

     2. После перезагрузки вы получите окно модуля с WinMain. Ес-
        ли все так и произошло, вы можете пропустить все дальней-
        шие шаги и перейти к разделу "Регистрация сообщений".

     3. Если  же  вы  получили  окно с сообщением "Ctrl-Alt-SysRq
        Interrupt. System Crash possible. Continue?" ("Прерывание
        по Ctrl-Alt-SysRq.  Возможен сбой системы.  Продолжить?",
        выберите No (Нет),  чтобы отменить выход из программы.  В
        этом случае выход должен выполняться в точке  останова по
        сообщению.

     4. Вызовите  команду  ViewіWindows  Messages,  чтобы вызвать
        окно Windows Message (Сообщения Windows).

     5. Курсор  находится  в  верхней   левой   области,   Window
        Selection (Выбор  окна).  Вызовите  локальное меню (нажав
        Alt-F10) и в нем выберите команду Add (Добавление).

     6. Введите имя подпрограммы,  в которой обрабатываются сооб-
        щения  для данного окна.  В этой программе имеется только
        одно окно,  и следовательно, только одна подпрограмма об-
        работки сообщений, WndProc.

     7. Нажмите клавишу Enter, чтобы подтвердить ввод.

     8. При  помощи клавиши Tab или "мыши" перейдите в правую об-
        ласть, Message Class (Класс  сообщений),  затем  вызовите
        локальное  меню  этой  области и выберите там команду Add
        (Добавление).

     9. В окне диалога Set Message Filter (Установка фильтра  со-
        общений) выберите All Messages (Все сообщения) в качестве
        класса сообщений и Break (Прерывание)  в  качестве  дейс-
        твия,  и нажмите Enter, чтобы добавить этот класс сообще-
        ний.  TDW затем прекратит выполнение программы на  первом
        же сообщении.

    10. Для возобновления работы программы нажмите F9. На следую-
        щем же сообщении программа прервется,  и управление возв-
        ратится в TDW.

    11. В  TDW  установите курсор на WinMain и при помощи команды
        RunіProgram Reset (ВыполнениеіСброс программы) перезагру-
        зите программу. Затем вы сможете продолжить отладку.

                    Регистрация сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     На этот раз, прежде чем запустить программу, вы зададите TDW
регистрацию всех сообщений. Откройте окно Windows Messages (Сооб-
щения Windows) при  помощи  команды  ViewіWindows  messages  (Об-
зоріСообщения   Windows)  и  добавьте  в  верхней  левой  области
WndProc. В правой верхней области должна  появиться  надпись  Log
all messages (Регистрация всех сообщений). Это именно то, что вам
нужно, и работа с этим окном закончена.

     Поскольку заранее число регистрируемых сообщений неизвестно,
может случиться так,  что до выхода из программы предельное число
регистрируемых сообщений (200) будет превышено, поэтому вы должны
обеспечить запись сообщений в файл. Для этого:

     1. Перейдите  в  нижнюю область окна Windows Messages (Сооб-
        щения Windows) и вызовите локальное меню.

     2. Выберите команду Send To Log Window (Пересылка в окно ре-
        гистрации). Если  эта  установка имеет значение No (Нет),
        переключите ее на Yes (Да), нажав клавишу Enter.

     3. Перейдите  в  окно  Log  (Регистрация),  выбрав   команду
        ViewіLog (ОбзоріРегистрация), и вызовите локальное меню.

     4. Выберите команду Open Log File (Открыть файл регистрации)
        и нажмите клавишу Enter,  чтобы подтвердить имя файла ре-
        гистрации (журнала) по умолчанию, BCWDEMOA.LOG.

     Теперь вы готовы запустить программу, нажав клавишу F9. Ког-
да появится экран, нажмите клавиши Ctrl-Alt-SysRq, чтобы вернуть-
ся к TDW.

                  Анализ протокола сообщений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В нижней  области  окна Windows Messages (Сообщения Windows)
вы увидите множество сообщений WM_PAINT, и вероятно, больше ника-
ких других.  Для того,  чтобы просмотреть все сообщения, выберите
команду ViewіFile  (ОбзоріФайл)  и  получите список всех файлов в
текущем каталоге.  Выберите из этого  списка  файл  BCWDEMOA.LOG,
представляющий собой протокол сообщений.

     При этом вы получите достаточно  короткий  список  сообщений
инициализации окна (16 или около этого), за которым следует очень
длинный  список  сообщений  WM_PAINT.  причиной является то,  что
Windows начала посылать сообщения,  чтобы установить исходный эк-
ран,  но "застряла" на сообщении WM_PAINT. Данный анализ отражает
то, что вы видели при запуске программы: экран появился, но боль-
ше ничего не происходило.

                        Поиск ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Итак, что делать дальше? Можно начать с просмотра кода, что-
бы  найти  там  тот,  участок,  который  отвечает  за   обработку
WM_PAINT.  Однако, существует более привлекательная альтернатива,
которая состоит в том, чтобы установить точку останова по сообще-
нию, позволяющую сразу выйти на нужный участок программы, а затем
начать пошаговое выполнение, которое позволит точно выяснить при-
чину ошибки.

     Установка точки останова по сообщению также отменит действие
выхода по Ctrl-Alt-SysRq,  который делает небезопасным дальнейшее
пошаговое выполнение программы или выход из TDW.  Так как сообще-
нием, на котором "застряла" программа, является WM_PAINT, устано-
вите  для  TDW прерывание по сообщению WM_PAINT и снова запустите
программу, следующим образом:

     1. Снова   войдите   в   окно  Windows  Messages  (Сообщения
        Windows),  перейдите в правую верхнюю  область,  вызовите
        локальное меню и выберите Add (Добавление).

     2. Появится блок диалога Set Message Filter (Задание фильтра
        сообщений)  с уже выбранным значением Single Message (От-
        дельное сообщение), а курсор в это время будет находиться
        в текстовом поле ввода Single Message Name (Имя отдельно-
        го  сообщения).  Введите WM_PAINT (только заглавными бук-
        вами,  иначе TDW не сможет найти соответствие),  а в  ка-
        честве действия выберите Break (Прерывание).

     3. Для запуска программы нажмите F9.

     Программа немедленно  прервется,  и  вы  окажитесь на первой
строке WndProc.  (Чтобы получить полный  обзор  кода,  вы  должны
очистить с экрана окно Windows Messages). Эта подпрограмма состо-
ит из оператора switch для сообщений, специальным образом обраба-
тываемых программой.

     Подпрограмма WndProc:

     long FAR PASCAL WndProc (HWND hWnd, unsigned Message,
                              WORD wParam, LONG lParam)
     {
        switch(Message)
        {
           case WM_COMMAND:
              return DoWMCommand(wParam, hWnd);
           case WM_LBUTTONDOWN:
              DoLButtonDown(hWnd,lParam);
              break;
           case WM_LBUTTONUP:
              DoLButtonUp(hWnd,lParam);
              break;
           case WM_MOUSEMOVE:
              DoMouseMove(hWnd,lParam);
              break;
           case WM_PAINT:
              DoPaint(hWnd);
              break;
           default:
              return DefWindowProc(hWnd,Message,wParam,lParam);
        }
        return 0;
     }

               Пошаговое выполнение программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для пошагового  выполнения  программы нужно нажимать клавишу
F7.  Маркер текущей строки дойдет до оператора case  WM_PAINT,  и
наконец до подпрограммы DoPaint.

     Подпрограмма DoPaint:

     void DoPaint(HWND hWnd)
     {
        int     i,
                saveROP;

        HDC     hdc,
                hMemDC;

        RECT    theRect,
                destRect;

        HBITMAP      the Bitmap;
        PAINTSTRUCT  ps;

        if (CurrentPoint >= 0)
        {
           hdc = BeginPaint(hWnd,&ps);
        /*
         * Определить, какая прямоугольная область отмечена
         * как недопустимая.
         * Если ни один прямоугольник не помечен как
         * недопустимый, то экран будет полностью перерисован.
         */

        GetUpdateRect(hWnd,&theRect,0);
        if (IsRectEmpty(&theRect))
            GetClientRect(hWnd,&theRect);
        /*
         * Создание DC (контекста устройства) и области
         * того же размера, что и обновляемый прямоугольник.
         */

         hMemDC = CreateCompatibleDC(hdc);
         theBitmap = CreateCompatibleBitmap(hdc,
                           theRect.right-theRect.left
                           theRect.bottom-theRect.top);
         SelectObject(hMemDC,theBitmap);

        /*
         * Стирание memBitmap
         */

         BitBlt(hMemDC, 0, 0,
                theRect.right-theRect.left
                theRect.bottom-theRect.top,
                hdc, 0, 0, SCRCOPY);

        /*
         * Рисование только тех фигур, которые находятся
         * внутри обновляемого прямоугольника.
         */

         for (i = 0; i <= CurrentPoint; ++i)
         {
            IntersectRect(&destRect, &thisShape[i].Points,
                            &theRect);
            if (!IsRectEmpty(&destRect))
                DrawShape(hMemDC,
                   thisShape[i].Points.left-theRect.left,
                   thisShape[i].Points.top-theRect.top,
                   thisShape[i].Points.right-theRect.left,
                   thisShape[i].Points.bottom-theRect.top,
                   thisShape[i].theShape,thisShape[i].PenWidth,
                   thisShape[i].PenColor,thisShape[i].slope);

        /*
         * Отметим, что при рисовании фигуры программа переместила
         * ее точку начала координат т.о., что она оказалась в
         * верхнем левом углу обновляемого прямоугольника.
         * Это точка (0,0) области, в которую будет выполнено
         * отображение (theRect.left,theRect.right).
         */
         }

        /*
         * И наконец, копирование области в область обновляемого
         * прямоугольника.
         */

         BitBlt(hdc, theRect.left, theRect.top,
                theRect.right-theRect.left,
                theRect.bottom-theRect.top,
                hMemDC, 0, 0, SRCCOPY);

         DeleteDC(hMemDC);
         DeleteObject(theBitmap);
         EndPaint(hWnd,&ps);
        }
     }

     По мере продолжения пошагового выполнения  вы  увидите,  что
единственная строка кода, выполняемая внутри DoPaint, это:

     if (CurrentPoint >= 0)

     Затем управление  возвращается  в цикл сообщений,  в котором
программа принимает следующее сообщение,  WM_PAINT, и затем снова
уходит на цикл с WndProc и DoPaint.  Подпрограмма DoPaint, безус-
ловно, что-то делает не так, и нужно сначала выяснить, что же она
должна делать на самом деле?

                       Анализ DoPaint
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Назначение данной подпрограммы состоит либо в рисовании все-
го экрана при первом вызове подпрограммы,  либо в перерисовке об-
ласти  экрана,  текущего  прямоугольника,  если  на  экране  было
что-либо нарисовано. Чтобы определить, было ли что-нибудь нарисо-
вано,  DoPaint проверяет значение переменной Currentpoint, перво-
начально устанавливаемой в -1.  (CurrentPoint указывает число на-
рисованных объектов).  Если CurrentPoint имеет  значение  -1,  то
есть  значение,  которое было установлено при запуске и рисовании
исходного экрана,  то брать и перерисовывать содержимое  текущего
прямоугольника нет необходимости,  поэтому все коды внутри опера-
тора if опускается, и происходит возврат, а Windows перерисовыва-
ет все окно.

     Если вы   будете  проверять  значение  CurrentPoint  в  окне
ViewіWatches (ОбзоріПросмотр),  то вы увидите,  что оно  остается
равным  -1 при пошаговом прохождении программы.  Это так и должно
быть, поскольку нарисовать что-либо вы не имели возможности.

                      Нахождение ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь, если  вы обратитесь к книге Чарльза Петцольда "Прог-
раммирование  для   Windows"   ("Charles   Petzold,   Programming
Windows"),  то причина ошибки станет вам ясна.  Минимальная реак-
ция,  которая нужна Windows в ответ на сообщение WM_PAINT, должна
состоять в вызове BeginPaint,  за которым следует EndPaint.  Если
эти подпрограммы не вызываются, то Windows не знает, что было по-
лучено  сообщение WM_PAINT,  и продолжает посылать WM_PAINT прог-
рамме.

     Обратите внимание,  что вызов  BeginPaint  находился  внутри
оператора if,  и подпрограмма при первой прорисовке экрана не вы-
зывалась. Чтобы решить проблему, вы должны вынести оператор с вы-
зовом BeginPaint за пределы условного оператора if.

     Как обстоит  дело  с оператором EndPaint?  Он тоже находится
внутри if, вместе с вызовом подпрограммы ReleaseDC, которая осво-
бождает hdc,  логический  номер (описатель) контекста устройства,
устанавливаемый вызовом BeginPaint.  Эти две строки должны  нахо-
диться вне конструкции if.

                     Завершение BCWDEMOA
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В BCWDEMOB,  второй версии программы, которую вы будете изу-
чать,  ошибка,  связанная с WM_PAINT,  уже исправлена. Прежде чем
загружать эту программу,  нужно завершить работу BCWDEMOA,  чтобы
освободить используемые ей ресурсы.  Поскольку единственная проб-
лема с этой программой состояла в том,  что при первом проходе не
выполнялся  код  внутри оператора if,  установка CurrentPointer в
ноль приведет к выполнению этого кода,  что  позволяет  нормально
выйти из программы.  Для завершения программы выполните следующие
шаги:

     1. В окне Windows Messages (Сообщения Windows)  уберите  имя
        оконной  процедуры WndProc в левой верхней области, чтобы
        программа  не  была  прервана  при  получении   сообщения
        WM_PAINT.

     2. Нажимайте F7, пока на дисплее не появится следующая стро-
        ка:

                  if (Currentpointer >= 0)

     3. Выделите  CurrentPoint,  затем  нажмите  клавиши Ctrl-F4,
        чтобы перейти к экрану Evaluate/Modify  (Вычисление/Моди-
        фикация).

     4. Выберите Eval (Вычисление).

     5. Поместите  курсор  на  поле ввода New Value (Новое значе-
        ние),  введите 0,  а затем выберите Modify (Модификация),
        чтобы изменить значение переменной. Теперь при выполнении
        программы оператор if при вычислении условия даст  значе-
        ние True,  а  BeginPaint  и  EndPaint будут выполнены при
        первом же проходе.

     6. Выберите клавишу F9 для выполнения программы.

     7. Выберите Quit для выхода из программы.  Чтобы эта команда
        сработала,  вам  может понадобиться нажать клавишу,  пос-
        кольку Windows может отказаться освободить сообщения вво-
        да от "мыши" из системной очереди.  Нажатие клавиши осво-
        бодит из очереди все находящиеся там в текущий момент со-
        общения ввода от "мыши".

                      Отладка BCWDEMOB
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Завершив работу  программы  BCWDEMOA,  вы  можете  загрузить
программу BCWDEMOB.  Когда программа появится на экране,  нажмите
для  ее  запуска  клавишу  F9,  и попробуйте немного поработать с
программой.

     Если вы нарисовали большое число объектов,  и  особенно  при
интенсивном перемещении  "мыши" при нажатой кнопке,  вы увидите в
конце-концов, что с программой начинают происходить странные  ве-
щи. Сначала вы сможете заметить,что программа стала медленнее ра-
ботать,  а затем объекты исчезают или изменяется цвет или толщина
линий,  а экраны перемешиваются.  И наконец,  все зависает, и вам
приходится перезагружаться аппаратным образом.

     Наиболее вероятная причина состоит в ошибочном использовании
памяти. Чтобы проверить, так ли это, и найти местоположение ошиб-
ки,  повторите загрузку Windows,  выполните только менеджер прог-
рамм и TDW, если это возможно (чтобы минимизировать использование
памяти), и загрузите BCWDEMOB и TDW снова.

                  Переключение из программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Прежде чем продолжить сеанс отладки, может потребоваться ор-
ганизовать  отладку  таким   образом,   чтобы   не   использовать
Ctrl-Alt-SysRq для  переключения  из перекладной программы в TDW,
поскольку использование данного метода требует осторожности.  Ре-
шение состоит в том,  чтобы установить единственное сообщение, по
которому должно выполняться прерывание,  и которое вы  по  своему
желанию можете генерировать в программе, и которое обычно само по
себе не появляется.

     Так как BCWDEMO - это работающая с "мышью" графическая прог-
рамма, не принимающая графического ввода, то работа с клавиатурой
здесь обычно не нужна.  Следовательно,  лучше всего  организовать
прерывание по сообщению WM_KEYFIRST.  После задания этого сообще-
ния в окне ViewіWindows Message (ОбзоріСообщения  Windows)  прог-
рамма  будет  прерываться при каждом нажатии клавиши.  (Поскольку
программа не реагирует и на нажатие  правой  кнопки  "мыши",  для
этой цели можно использовать и сообщение WM_RBUTTONDOWN).

                   Тестирование программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь вы можете нажать клавишу F9,  чтобы начать выполнение
программы BCWDEMOB. Прежде чем сделать что-либо в программе, про-
верьте, какой процент системной памяти  доступен  программам  для
Windows,  переключившись  на  менеджер программ,  выбрав "кнопку"
Help (Справка) и затем выбрав About Program Manager  (О менеджере
программ). Появится информационный блок, в котором будет показана
текущая версия Windows, объем свободной памяти и в нижней части -
интересующие  вас  статистические данные,  процентные соотношения
свободной памяти для системных ресурсов.

     Теперь вернемся в программа Simple Paint и немного порисуем.
Затем  снова перейдем на экран About Program Manager (О менеджере
программ),  и вы увидите,  что доступная память для системных ре-
сурсов  уменьшилась.  Если  вы и дальше продолжите рисование,  то
объем этой памяти будет продолжать уменьшаться до нуля,  и вы по-
лучите тот же эффект, что и ранее.

                      Принятие решения
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Что вам известно в данный момент?  Прежде  всего,  программа
явно распределяет  глобальную  память,  так  как она в результате
расходует все системные ресурсы, доступные Windows. С этого можно
начать: вы можете перезагрузить программу, воспользоваться средс-
твами TDW контроля глобальной памяти для сохранения списка объек-
тов глобальной памяти в файл регистрации (протокол),  немного по-
рисовать в Simple Paint и затем снова  получить  список  объектов
глобальной памяти, записав его в другой файл.

     Так как Windows за это время, вероятно, перемещала объекты в
памяти,  то два полученных списка могут не совпадать.  Вы  должны
просмотреть каждый объект в списке и сопоставить его с объектами,
имеющими того же владельца в другом списке,  чтобы найти  несоот-
ветствия.

     Поскольку этот метод занимает много времени, то предлагается
он только как упражнение по просмотру глобальной  памяти.  Метод,
которым вы будете пользоваться фактически,  состоит в том,  чтобы
просмотреть объекты памяти,  выделяемые программой,  и проверить,
выполняет ли программа и их освобождение.

       Сравнение списков объектов глобальной памяти
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для получения списка объектов глобальной памяти нужно выпол-
нить следующие действия:

     1. Перезапустите Windows,  чтобы обеспечить очистку глобаль-
        ной памяти от  любых  объектов,  выделенных  BCWDEMOB.  И
        опять,  избегайте  запускать  ненужные  программы,  чтобы
        уменьшить число объектов глобальной памяти.

     2. Если  вы  находитесь  в  TDW и загрузили BCWDEMOB,  снова
        установите прерывание программы по сообщению WM_KEYFIRST.

     3. Нажмите клавишу F9 для запуска программы, а затем нажмите
        клавишу для выхода обратно в TDW.

     4. Выберите  команду ViewіLog (ОбзоріРегистрация) и вызовите
        локальное меню.

     5. Выберите  команду  Open  LogіFile (Открыть файліРегистра-
        ция), введите в появившемся окне диалога имя файла журна-
        ла и нажмите клавишу Enter.

     6. Снова вызовите локальное меню окна Log (Регистрация), вы-
        берите команду Display  Windows  Info  (Вывод  информации
        Windows),  а затем нажмите клавишу Enter,  когда появится
        окно диалога Windows  Information  (Информация  Windows).
        Нажатие  Enter принимает установки по умолчанию, задающие
        вывод списка объектов глобальной памяти,  начиная с верх-
        них адресов памяти.

     7. Когда  отладчик  TDW  закончит листинг глобальной памяти,
        снова вызовите список объектов глобальной памяти и  выбе-
        рите команду Close Log File (Закрытие файла регистрации),
        чтобы закрыть файл.

     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, который сохраняет сде-
ланный вами выбор в переменной программы. Эти переменные хранятся
в сегменте данных BCWDEMO и не влияют на глобальную память.

                      Рисование фигуры
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для того,  чтобы нарисовать фигуру, вы устанавливаете курсор
в предназначенную для графического ввода пользователя область ок-
на,  удерживая нажатой левую кнопку "мыши" перемещаете  курсор  в
другую точку и там отпускаете кнопку "мыши".  Если вы перемещаете
"мышь" при ненажатой левой кнопке, вы можете заметить, что фигура
по мере перемещения рисуется, стирается и снова рисуется. Остает-
ся она на экране только при отпускании левой кнопки.

                   Нажатие левой кнопки "мыши"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При нажатии левой кнопки в области пользовательского  графи-
ческого   ввода   Windows  посылает  сообщение  WM_LBUTTONDOWN  в
WndProc,  что приводит к вызову  DoButtonDown.  Эта  подпрограмма
сохраняет текущую   позицию   "мыши"   (которая  далее  именуется
меткой) и  выполняет  установки  характеристик  пера  в структуре
thisShape. Эта структура представляет собой  переменную программы
и влияет только на сегмент данных программы BCWDEMO.

                       Перемещение "мыши"
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы перемещаете "мышь" при нажатой левой кнопке в поль-
зовательской области ввода, Windows посылает WM_MOUSEMOVE (или WM
_MOUSEFIRST,  что  то  же  самое)  в  WndProc,  которая  вызывает
DoMouseMove. Эта подпрограмма вызывает DrawShape для стирания фи-
гуры от  предыдущей  позиции "мыши" до исходной,  а затем снова -
для рисования фигуры от текущей позиции  до  метки.  Единственное
использование глобальной памяти в DoMouseMove состоит в получении
контекста устройства для текущего окна,  который освобождается  в
конце подпрограммы вызовом ReleaseDC.

       Рисование фигуры (и нахождение позиции ошибки)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Теперь рассмотрим подпрограмму DrawShape, которая дважды вы-
зывается из DoMouseMove. DrawShape запоминает перо, которым рисо-
валась предыдущая фигура,  создает новое перо и рисует линию, эл-
липс или прямоугольник.  В конце своей работы она восстанавливает
сохраненное на входе перо.

     Поскольку перо - это объект интерфейса графических устройств
(GDI), выделяемый в глобальной памяти, подпрограмма DrawShape мо-
жет содержать код, вызывающий проблемы с памятью. Эта подпрограм-
ма вызывает особенное подозрение,  так как она вызывается  дважды
при каждом перемещении мыши.  Если она создает перья и не удаляет
их, то она "съест" память очень скоро.

     Действительно, недалеко  от  начала  DrawShape выделяет перо
вызовом SelectObject, но не освобождает выделенную ему память вы-
зовом DeleteObject в конце. Чтобы исправить эту ошибку, вы должны
заменить последнюю строку DrawShape следующим кодом:

     DeleteObject(SelectObject(hdc,saveObject));

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

                     Отпускание левой кнопки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При отпускании  левой кнопки "мыши" BCWDEMOB рисует фигуру в
последний раз и оставляет ее на экране. Отпускание кнопки застав-
ляет  Windows  послать сообщение WM_LBUTTONUP в WndProc,  которая
вызывает DoLButtonUp.  Эта подпрограмма сохраняет текущий прямоу-
гольник  из  пользовательской  области  в  массив  текущей фигуры
thisShape,  вызывает InvalidateRect для добавления области в  об-
ласть обновления окна, а затем вызывает UpdateWindow, которая по-
сылает сообщение WM_PAINT прямо в главное окно.  Эта подпрограмма
не использует глобальную память.

     При выходе  из  DoLButtonUp  сообщение  WM_PAINT находится в
очереди и готово к обработке в WndProc.

                     Перерисовка экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда WndProc  получает  сообщение  WM_PAINT,  она  вызывает
DoPaint для перерисовки соответствующей области  экрана  (описана
выше в этом разделе). При перерисовке обновляемого прямоугольника
DoPaint вызывает две подпрограммы Windows, влияющие на глобальную
память:  CreateCompatibleDC и SelectObject. В конце DoPaint вызы-
ваются DeleteDC и DeleteObject,  которые освобождают выделенную в
начале подпрограммы память.

                         Заключение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

     Не мешает также и более  подробное  тестирование  программы.
Хорошо зная программу, вы могли бы не искать ошибку в части прог-
раммы, связанной с меню, так как обнаружили бы, что сбой програм-
мы  наступает  и при одном только перемещении курсора по экрану с
помощью "мыши".  Кроме  того,  обнаружив,  что проблема возникает
только при перемещении "мыши" в области пользовательского  графи-
ческого  ввода  при нажатой левой кнопке (это вы могли бы обнару-
жить,  нажав кнопку и перемещая курсор до тех пор,  пока не прои-
зойдет  сбой  программы),  вы  могли  бы сразу предположить,  что
проблема связана с подпрограммой DoMouseMove и на ней  сосредото-
чить свои усилия.

    Глава 19. Отладка программы, использующей ObjectWindows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Пример объектно-ориентированной  программы  данной главы был
написан с помощью класса ObjectWindows,  который существенно  об-
легчает  программирование в Windows.

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

     Перед тем,  как продолжить изучение,  полезно  запустить  из
Windows программу  TDODEMO  и немного поэкспериментировать с ней,
чтобы получить представление, как она работает. Вы можете исполь-
зовать для запуска TDODEMO.EXE команду FileіRun (ФайліВыполнение)
менеджера программ или добавить ее к программной группе в качест-
ве пиктограммы.

          Примечание: При   отсутствии  файлов  .EXE  для  файлов
     TDODEMO и TDODEMOB вам потребуется открыть их файлы проектов
     и перекомпилировать эти файлы с включением отладочной инфор-
     мации.

                      О программе
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     TDODEMOB -   это   программа,  написанная  с  использованием
ObjectWindows,  позволяющая рисовать на экране различными цветами
с помощью "мыши".  Когда вы нажимаете левую кнопку "мыши" и пере-
мещаете "мышь", то программа рисует на экране линию. Нажав правую
кнопку "мыши",  вы можете очистить окно.  Программа TDODEMO имеет
строку меню,  которая позволяет вам выбрать один из 4 цветов: Red
(красный), Green (зеленый), Blue (голубой) или Black (черный).

     Вы можете рисовать,  нажимая кнопку "мыши", перемещая "мышь"
и освобождая кнопку "мыши".  Программа легко выполняет эту задачу
с помощью библиотеки ObjectWindows и динамических виртуальных ме-
тодов.  Динамический виртуальный метод - это метод с  присвоенным
ему числовым идентификатором.

     Поскольку Borland  C++  определяет  имена сообщений Windows,
как числовые константы,  вы можете использовать номера  сообщений
Windows в качестве идентификатора динамического метода.  При этом
ObjectWindows может вызывать данный метод,  когда окно, для кото-
рого объявлен метод, получает совпадающее с идентификатором мето-
да сообщение. Если нет метода, идентификатор которого совпадает с
идентификатором  метода,  ObjectWindows  вызывает используемую по
умолчанию процедуру окна.

     Например, чтобы создать метод, который отвечает на сообщения
WM_MOUSEMOVE,  вы можете определить метод в объекте окна, который
выглядит следующим образом:

     procedure WMMouseMove(var Msg: TMessage); virtual WM_MOUSE;

     Как вы можете видеть,  идентификатор WM_MOUSEMOVE можно при-
соединить  к  процедуре  с помощью оператора virtual <идентифика-
тор>, который непосредственно следует за описанием процедуры.

     Параметры процедуры окна Windows wParam  и  lParam  содержит
тип TMessage.  Эти параметры часто содержат дополнительную инфор-
мацию о сообщении, например, где позиционируется "мышь".

     В следующих  нескольких  разделах  поясняется,  как работает
программа TDODEMOB.  В нее преднамеренно внесены ошибки,  которые
вы сможете обнаружить позднее. Полезно также запустить Турбо Пас-
каль для Windows и открыть файл TDODEMOB.PAS,  после чего вы смо-
жете следовать по коду программы.

          Определение оконного типа ScribbleWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Тип ScribbleWindow определяется следующим образом:

     class ScribbleWindow : public TWindow
     {
     public:
          HDC HandleDC;       // вывод содержимого для рисования
          BOOL ButtonDown;    // флаг левой кнопки
          HPEN ThePen;        // перо, которое используется для
                              // рисования цветом

     ScribbleWindow(PTWindowObject AParent, LPSTR ATitle);
         -ScribbleWindow();
         void GetWindowClass(WNDCLASS &AWndClass);

         virtual void WMLButtonDown(RTMessage
     Msg)=[WN_First+WM_LBUTTONDOWN];
         virtual void WMLButtonUp(RTMessage MSG)=(WM_FIRST+
                       WM_LBUTTONUP);
         virtual void WMLMouseMove(RTMessage MSG)=(WM_FIRST+
                       WM_MOUSEMOVE);
         virtual void WMLButtonDown(RTMessage MSG)=(WM_FIRST+
                       WM_LBUTTONDOWN);
     virtual void SelectRedPen(RTMessage Msg)=(CM_FIRST+
                                                CM_RED);
     virtual void SelectGreenPen(RTMessage Msg)=(CM_FIRST+
                                                 CM_GREEN);
     virtual void SelectBluePen(RTMessage Msg)=(CM_FIRST+
                                                 CM_BLUE);
     virtual void SelectBlackPen(RTMessage Msg)=(CM_FIRST+
                                                 CM_BLACK);
     virtual void SetupWindow();
     };

     Класс ScribbleWindow определяет определяет объект окна,  ко-
торый отвечает на следующий ввод пользователя:

     - перемещение "мыши";

     - нажатие и освобождение левой кнопки "мыши";

     - нажатие правой кнопки "мыши";

     - цвет и позицию пера.

     Имеются три  экземпляра  переменных  -  HandleDC,  ThePen  и
ButtonDown, которые содержат класс устройства,  текущее перо, ко-
торым рисует  пользователь,  и  состояние кнопки "мыши" соответс-
твенно.

                 Конструктор ScribbleWindow
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Конструктор ScribbleWindow  присоединяет  меню к программе и
инициализирует элемент  данных  ButtonDown  значением  FALSE,   а
ThePen - значением CM_BLACK.

                       GetWindowClass
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Функция-элемент GetWindowClass вызывает  стандартную функцию
TWindow CegWindowClass устанавливает окно таким образом,  что оно
ведет себя аналогично любому другому окну TWindow, а затем иници-
ализирует пиктограмму программы.

                        WMRButtonDown
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь  нажимает  в  окне  ColorScribble  правую
кнопку "мыши"  и  собирается  рисовать,  окно  получает сообщение
WM_LBUTTONDOWN, которое приводит к тому,  что ObjectWindows вызы-
вает  подпрограмму WMLButtonDown (так как она имеет идентификатор
WM_FIRST+WM_LBUTTONDOWN).  Подпрограмм  WMLButtonDown  перемещает
перо   в   текущую  позицию  "мыши"  и  устанавливает  переменную
ButtonDown, чтобы указать,  что кнопка нажата,  а затем  выбирает
ThePen в текущий контекст устройства. В Windows имеются также до-
полнительные вызовы данной функции,  о чем будет рассказано ниже.

                         WMLButtonUp
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь заканчивает рисование и освобождает кноп-
ку "мыши",  окно получает сообщение WM_LBUTTONUP,  которое в свою
очередь приводит  к  тому,  что  ObjectWindows  вызывает  функцию
WMLButtonUp. Программа присваивает переменной ButtonDown значение
False и освобождает класс устройства, связанный с данным окном.

                        WMRButtonDown
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь  нажимает  правую  кнопку  "мыши",  чтобы
очистить экран, ObjectWindows вызывает функцию WMRButtonDown, ко-
торая, в свою очередь, вызывает функцию Windows UpdateWindow. Вы-
зов данной функции предназначен для очистки окна.

                         WMMouseMove
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь  начинает перемещать курсор по окну, окно
получает сообщение WM_MOUSEMOVE,  которое приводит  к  тому,  что
ObjectWindows вызывает функцию WMMouseMove. Если пользователь на-
жал левую кнопку "мыши", то программа рисует при каждом перемеще-
нии "мыши" линию. Если пользователь не нажимает кнопку "мыши", то
ничего не происходит.

                   Подпрограммы цвета пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Имеются также  четыре  функции,  устанавливающие  цвет пера,
удаляя текущее перо и создавая новое перо с  нужным  цветом.  Эти
функции отличаются только устанавливаемыми цветами.

                Создание прикладной программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы создать прикладную программу,  которая использует окно
окно ColorScribble,  необходимо  создать  класс  на основе класса
ObjectWindow в  TApplication.  Назначение  этого  класса  (класса
CSribbleApplication) состоит в следующем:

     - Переопределении  функции  InitMainWindow,  благодаря  чему
       прикладная программа сможет  создавать  основное  окно  со
       свойствами окна CSribbleWindows.

     - Обеспечении  объектного  типа MyApp,  который используется
       для установки окна и запуска программы.

          Примечание: 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
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как сбой в программе происходит при нажатии левой кнопки
"мыши", вероятно проблема заключается в функции WMLButtonUp.  Од-
нако существует  другой  метод,  который  можно  использовать для
определения того,  где  находилась  ваша  программа - трассировка
стека.

     Для выполнения  трассировки стека выберите с помощью команды
ViewіStack (ОбзоріСтек) окно Stack (Стек) и прокрутите вниз  спи-
сок шестнадцатиричных  инструкций,  пока вы не дойдете до строки,
указывающей подпрограмму вашей  программы  (имя  подпрограммы  вы
увидите в коде ASCII).  Эта строка находится в так называемом яд-
ре Windows.

     Как можно видеть в окне Stack,  подпрограммой, которую нужно
рассмотреть,  в  самом  деле является подпрограмма WMLButtonDown.
Чтобы перейти к данной подпрограмме в окне Module,  сначала щелк-
ните в  этом  окне кнопкой "мыши".  Затем нажмите клавиши Ctrl-S,
наберите WMLButtonDowm и нажмите  для  поиска  этой  подпрограммы
клавишу Enter.  Если вы увидите сообщение "Search expression  not
found" ("Искомое выражение не найдено"), перейдите к началу файла
и клавиши Ctrl-N,  чтобы снова выполнить поиск (в TDW  вы  можете
выполнять  поиск  только от текущей позиции курсора до конца фай-
ла).  Возможно, перед тем как вы найдете функцию, вам потребуется
несколько раз нажать Ctrl-N.

                Отладка функции 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,  то
либо описатель (контекста устройства) установлен неверно, либо не
устанавливался вовсе.  На самом деле он не устанавливался.  Прог-
рамма  должна инициализировать контекст дисплея с помощью следую-
щего вызова 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);
                               // выбрать перо для контекста
                               // устройства
      }
     }

                    Проверка исправлений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В Borland C++ добавьте в ScribbleWindow::WMLButtonUp  опера-
тор инициализации контекста. Далее скомпилируйте проект с включе-
нием отладочной информации (выбрав  команду  (CompileіBuild  All)
(КомпиляторіПолное построение)).

     Поскольку в нашем случае имеются другие ошибки, снова загру-
зите в TDW программу, затем при выводе окна Module нажмите клави-
шу F9.

      Теперь, если  вы  рисуете с помощью пера,  то линия рисуется
назначенным по умолчанию цветом - черным.Попробуйте рисовать раз-
личными цветами,  выбирая из меню цвет пера.  Красный,  зеленый и
голубой будут работать прекрасно,  но когда вы попытаетесь  изме-
нить цвет обратно на черный,  то цвет пера не изменится.  Похоже,
вы нашли другую ошибку.

             Поиск ошибки назначения цвета пера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Наиболее вероятным  местом   этой  ошибки  является  функция
SCribbleWindow, который создает цвет пера SelectBlackPen. Выйдите
из ColorScribble,  затем  для  сброса  программы  нажмите клавиши
CtrlF2.  Установите точку останова на открывающей фигурной скобке
функции CScribbleWindow::SelecrBlackPen. Затем запустите програм-
му и выберите команду PenіBlack.  (Чтобы  получить  сообщение  от
Windows, возможно  придется  нажать клавишу.) Отладчик TDW должен
остановить выполнение на точке останова.  Поскольку этого не про-
исходит, здесь что-то неверно.

     Вероятно, функция SelectBlackPen никогда не вызывается. Пос-
кольку данная подпрограмма работает на основе динамически диспет-
черизуемой виртуальной таблице, возможно что-то не так с ее иден-
тификатором.

         Установка точки останова по сообщению окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда пользователь  выбирает элемент меню,  Windows посылает
сообщение WM_COMAND тому окну,  которому данное меню принадлежит.
Параметр сообщения wParam содержит идентификатор выбираемого эле-
мента  меню.  Когда   окно   ObjectWindows   получает   сообщение
WM_COMMAND, оно просматривает индексы диспетчеризации объекта ок-
на в поиске значения CM_FIRST + wParam.  SelectBlackPen имеет ин-
декс CM_FIRST + CM_BLACK, где CM_BLACK имеет значение 104.

     Чтобы определить,  каким является параметр wParam командного
сообщения PenіBlack,  вам нужно сообщить TDW, что он должен оста-
навливать выполнение при получении сообщения WM_COMMAND. Тогда вы
можете запустить программу,  сделать выбор в меню и проверить па-
раметр wParam,  чтобы посмотреть, не совпадает ли он с константой
CM_BLACK.

     Перед тем, как установить точку останова, вам нужно вернуть-
ся  обратно   в   TDW.   Закройте   окно   прикладной   программы
ColorScribble, затем, когда вы вернетесь в окно Module, для пере-
загрузки программы  TDODEMOB  используйте клавиши Ctrl-F2.  Когда
выведется окно Module, следующим шагом будет установка точки ост-
анова по сообщению окна с помощью одного из двух методов, в зави-
симости  от   того,    разрешена    или    запрещена    поддержка
ObjectWondows.

     По умолчанию    специальная    поддержка    сообщений   окон
ObjectWondows отсутствует.  Вы не можете использовать описанный в
вашей программе объект окна для установки точки останова по сооб-
щению.  Вместо этого нужно использовать описатель окна.  Если  вы
хотите использовать оконный объект (что легче, но может замедлить
отладку при наличии точки останова по сообщению), то нужно запус-
тить утилиту TDINST с параметром командной строки -w, выбрать ко-
манду OptionsіSource Debugging (ПараметрыіОтладка исходного кода)
и проверить параметр OWL Message Window.

          Примечание: Информация о TDINST содержится в Приложении
     D.

    Задание точки останова по сообщению окна по описателю
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если поддержка  ObjectWindows у вас не разрешена,  вы должны
установить точку прерывания по сообщению окна с помощью  описате-
ля. Поскольку    большинство   установок   окон   выполняются   в
ObjectWindow, для получения указателя придется пойти окольным пу-
тем.

     Начальные установки      окна      выполняются      функцией
InitMainWindow, но описатель устанавливается позднее.  Чтобы  уп-
равление снова вернулось в TWD,  вы можете установить точку оста-
нова на  одной   из   функций   работы   с   "мышью"   (например,
WMLButtonDown), запустить  программу,  затем использовать "мышь",
чтобы программу остановилась на точке останова. (Если точка оста-
нова находится  на  WMLButtonDown,  вы можете нажать левую кнопку
"мыши".)

     Другой метод   заключается   в    переопределении    функции
ObjectWindows SetupWindow, которая инициализирует описатель, бла-
годаря чему вы можете получить управление после каждой  инициали-
зации указателя.  Данная функция переопределяется в TDODEMOB, как
виртуальная функция. Она определяется следующим образом:

     void ScribbleWindow::SetupWindow():
     {
            TWindow::SetupWindow();
     }

     Чтобы воспользоваться  этим, позиционируйте курсор на закры-
вающей скобке функции SetupWindow,  затем нажмите клавишу F4  для
выполнения программы до этой точки.

     Независимо от используемого метода, когда TDW вновь получает
управление, для установки точек останова по  сообщению WM_COMMAND
сделайте следующее:

     1. Выберите команду DataіInspect (ДанныеіПроверка) и  прове-
        рьте объект окна MainWindow. Поскольку он в данный момент
        находится вне  области  действия,  вам нужно использовать
        следующий синтаксис переопределения:

           WinMain#MyAppMainWindow

        Так как MyApp имеет тип  SCribbleWindow  (порожденный  от
        класса  TApplication,  элементом данных которого является
        MainWindow), MainWindow является элементом MyApp.

     2. Увеличьте окно Inspector, благодаря чему в верхней облас-
        ти  вы можете видеть элементы данных.  HWindow - это эле-
        менты данных, который содержит описатель окна.

     3. Позиционируйте курсор на HWindow,  затем нажмите  клавиши
        Shift-F3 и скопируйте его в окно Clipboard.

     4. Выберите  команду  ViewіWindows Message  (ОбзоріСообщения
        Windows) для вывода диалогового окна Windows Massage (Со-
        общения Windows).

     5. Для  вывода  диалогового  окна Add (Добавление) в верхней
        левой области нажмите клавиши Ctrl-A.  Выберите  "кнопку"
        Handle (Описатель),  затем позиционируйте курсор на текс-
        товом поле ввода.

     6. Нажмите для вывода окна Clipboard клавиши Shift-F4. Пози-
        ционируйте курсор на HWindow,  выберите "кнопку" Contents
        (для копирования HWindow - значения описателя), затем вы-
        берите "кнопку"  OK для копирования описателя в текстовое
        поле ввода.

     7. В текстовом поле ввода добавьте перед значением описателя
        Ox, чтобы указать, что это шестнадцатиричное число, затем
        нажмите Enter.

     8. Перейдите в правую верхнюю область и наберите WM_COMMAND.
        Вы увидите, что как только вы начнете набор символов, вы-
        выдается диалоговое окно  Set Message  Filter  (Установка
        фильтра сообщения).

    9. Установить  параметр Action (Действие) для данного сообще-
       ния в значение Break  (Прерывание),  затем  для  установки
       точки  прерывания  по  данному  сообщению  нажмите клавишу
       Enter.

     Программа будет возвращать управление в TDW всякий раз, ког-
да вы делаете выбор меню, поскольку при этом генерируется команда
WM_COMMAND.

   Установка точки прерывания по сообщению на объекте окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы  используете для разрешения поддержки точки прерыва-
ния по сообщению окна в ObjectWindows программу TDINST, то можете
использовать для  установки  точки  останова по сообщению оконный
объект MainWindow.

     1. Переместите курсор на закрывающую фигурную скобку функции
        InitMainWindow  и нажмите клавишу F4 для выполнения прог-
        раммы до этой точки.

     2. Когда вы снова увидите окно Module, для вывода диалогово-
        го окна   OWL   Windows   Messages   используйте  команду
        ViewіWindows Messagges (ОбзоріСообщения Windows).

     3. В левой верхней области  наберите  MainWindow  и  нажмите
        клавишу F4.

     4. В  верхней  правой области наберите WM_COMMAND,  выберите
        "кнопку" Break,  затем нажмите клавишу Enter, чтобы уста-
        новить точку останова по данному сообщению.

     Теперь программа  будет  возвращать  управление в TDW каждый
раз когда вы делаете выбор меню,  поскольку при этом генерируется
сообщение WM_COMMAND.

                       Проверка wParam
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Вы можете возобновить выполнение  программы,  нажав  клавишу
F9.

     Выберите в  меню команду PenіBlack (Черный цвет пера). После
того, как вы выберите черное перо, TDW останавливает выполнение и
выводит  на  экран окно CPU,  показывая,  что в момент прерывания
программа выполняла код ядра Windows.  Закройте окно  CPU,  нажав
клавиши Alt-F3.

     Если это  необходимо,  снова  выведите окно Windows Messages
(Сообщения Windows). Увеличьте окно до полного размера, благодаря
чему вы сможете видеть в нижней области все сообщение.  Вы можете
видеть, что окно получает сообщение  WM_COMMAND  со  значением  в
wParam   204  (шестнадцатиричное  значение  00CC).  Но  константа
CM_BLACK имеет значение 104,  а не 204. Это является причиной то-
го, что  не вызывалась виртуальная функция - прикладная программа
искала идентификатор CM_FIRST + 204,  а его действительным значе-
нием было CM_FIRST + 104.

     Значение 204  было  задано  в  определении файла TDODEMO.RC.
Данной ошибки можно было бы избежать,  используя для меню тот  же
идентификатор, что  и  в  файле  заголовка,  и  поместив оператор
#INCLUDE для этого файла заголовка в  начало  файла  .RC.  Вместо
этого значения были использованы в определении меню. При этом от-
ветственность за перекрестную проверку  значений  возлагается  на
программиста.

     Если вы  отредактируете TDODEMOB.H измените CM_BLACK на 204,
то выбор черного пера будет работать корректно. Когда вы сделаете
это  изменение,  описание констант в начале программы должно быть
следующим:

        #define        PenWidth        1
        #define        MenuID          100
        #define        IconID          100
        #define        CM_RED          101
        #define        CM_GREEN        102
        #define        CM_BLUE         103
        #define        CM_CLACK        204

                    Проверка исправления
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Запустите ColorScribble  и  выйдите оттуда,  затем выйдите в
TDW.  Когда вы вернетесь в Borland C++,  загрузите файл заголовка
TDODEMOB.H,  измените определение константы CM_BLACK, затем пере-
компилируйте программу (проект) и запустите ее по TDW.

     Теперь когда вы рисуете в окне,  то можете  заметить  другую
проблему.  Если при рисовании вы смещаете "мышь" за пределы окна,
то при возврате в окно в другом месте вы увидите,  что  программа
рисует линию,  соединяющую то место,  где вы вышли из окна, с тем
местом, где вы в него вернулись.

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

          Поиск ошибки рисования за пределом экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поиск этой ошибки неплохо начать с сообщение Windows,  кото-
рые получает данное окно.  Выйдите из программы  ColorScribble  и
загрузите в TDW (в окне Module) программу TDODEMOB.CPP.

                Регистрация сообщений Windows
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В зависимости от того, запрещена или разрешена поддержка со-
общений ObjectWindows, для инициализации окна используйте один из
двух описанных выше методов. Затем укажите в верхней левой облас-
ти окна  Windows  Messages  (Сообщений Windows),  для какого окна
нужно отслеживать сообщения (используя  объект  окна  или  описа-
тель).

     Далее переместите курсор в правую верхнюю область и добавьте
в качестве точки останова по сообщению WM_LBUTTONUP. Это позволит
TDW вновь получить управление, когда вы закончите рисовать.

     Желательно также просматривать все поступающие сообщения, но
установка WM_LBUTTONUP стирает установку Log  All  Messages  (Ре-
гистрация всех сообщений).  Чтобы восстановить установки, нажмите
для вывода диалогового окна Set Message Filter (Установка фильтра
сообщения) клавиши Ctrl-A.

                     Обнаружение ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Возобновите выполнение программы TDODEMOB, нажав клавишу F9.
Начните рисовать,  затем выведите "мышь" за пределы области поль-
зователя и вернитесь в нее в другом месте.  Чтобы уменьшить число
сообщений,  просто  переместитесь  вовне и снова вернитесь назад,
затем освободите левую кнопку "мыши",  чтобы управление вернулось
в TDW.

     Перед тем, как взглянуть на окно Windows Messages (Сообщения
Windows),  увеличьте его до полного размера (клавишей F5), благо-
даря чему вы сможете видеть больше сообщений. Когда вы посмотрите
на нижнюю область окна Windows Messages, то увидите множество со-
общений WM_NCHITEST и WM_SETCURSOR, среди которых будет сообщение
WM_LBUTTONDOWN, WM_MOUSEMOVE, после них будет несколько сообщений
WM_NCMOUSEMOVE, далее еще сообщения WM_MOUSEMOVE и, наконец, зак-
лючительное сообщение WM_LBUTTONUP.

     Похоже, что когда курсор не находится в области  пользовате-
ля,  то  сообщения WM_MOUSEMOVE не поступают,  а поступают только
сообщения WM_NCMOUSEMOVE.

     Теперь яcно, что представляет собой ошибка. Программа рисует
от  точки последнего сообщения WM_MOUSEMOVE до точки текущего со-
общения WM_MOUSEMOVE. Когда "мышь" выходит из области пользовате-
ля,  программа не получает сообщений WM_MOUSEMOVE. Таким образом,
когда "мышь" возвращается в область пользователя,  последней точ-
кой будет та точка,  где она покинула экран, и программа ошибочно
рисует линию от точки выхода за пределы экрана до  текущей точки.

                     Исправление ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Одним из  возможных  решений  могло бы быть определение того
места, где "мышь" выходит за область пользователя, благодаря чему
программа  сможет  игнорировать  последнюю позицию "мыши" и снова
начать рисование,  когда "мышь" возвращается в область  пользова-
теля.  Но  это потребовало бы сложной логики определения позиции,
где "мышь" покидает пределы экрана и где она возвращается  в  об-
ласть пользователя. К счастью, есть более простой способ.

     Функция Windows SetCapture делает как раз то, что требуется.
Данная функция указывает Windows,  что до  вызова  ReleaseCapture
нужно посылать все сообщения Windows, связанные с "мышью", в ука-
занное окно,  что приводит к  получению  окном  вместо  сообщений
WM_NCMOUSEBUTTON    ("вне    области   пользователя")   сообщений
WM_MOUSEMOVE.

     Если вы  поместите  в   ScribbleWindow::WMButtonDown   вызов
SetCapture,  а в WMLButtonUp - ReleaseCapture,  WMMouseMove будет
на самом деле рисовать вне окна,  но Windows будет отсекать  этот
вывод программы, что будет давать нужный результат.

     Эти изменения отражены в следующем исходном коде:

     void ScribbleWindow::WMLButtonDown(RTMessage Msg);
     {
        if ( ButtonDown )
        {
          ButtonDown = True;     // пометить кнопку "мыши"
                                 // как нажатую, благодаря чему
                                 // при перемещении "мыши" будет
                                 // рисоваться линия

          SetCapture(HWindow);   // сообщить Windows, что в окно
                                 // нужно посылать все сообщения
                                 // от "мыши"; отменять этот
                                 // перехват будет вызов
                                 // WMLButtonUp

          HandleDC = GetDC(HWindow); // создать контекст
                                     // изображения для вывода

          MoveTo(HandleDC, Msg.LP.LO,     // переместить точку
                 Msg.LP.Hi);              // рисования в ту
                                     // точку, где была нажата
                                     // кнопка "мыши"
       }
     }
     void Scribblewindow::WMLButtonUp(RTMessage)
     {
       if  ( Buttondown )
       {
         ReleaseCapture();
         ReleaseDC(HWindow,handleDC);
         ButtonDown = False;
       }
     }

                    Проверка исправлений
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Запустите программу ColorScribble и выйдите  из  нее,  затем
выйдите в TDW.  Когда вы вернетесь в Borland C++, внесите измене-
ния в две подпрограммы, затем перекомпилируйте программу и запус-
тите ее. Теперь,когда вы рисуете в окне, все будет работать прек-
расно,  но когда вы попытаетесь стереть экран,  используя  правую
кнопку "мыши", то ничего не произойдет. Вы нашли еще одну ошибку.

                Поиск ошибки стирания экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поскольку нажатие  правой   кнопки   "мыши"   обрабатывается
WMRButtonDown, то  возможно  ошибка как то связана с данной подп-
рограммой. Либо WMRButtonDown не вызывается, либо в ней ошибка.

     Выйдите из  ColorScrible  и  загрузите   в   TDW   программу
TDODEMOB. Чтобы выполнить ее до подпрограммы WMRButtonDown, в ко-
торой возможно содержится ошибка,  нажмите клавиши Alt-F9 и набе-
рите WMRButtonDown.  Порисуйте немного в окне, затем нажмите пра-
вую  кнопку  "мыши".  TDW  останавливает   программу   в   начале
функции WMRButtonDown, откуда видно, что она вызывается..

     Используя клавишу F7, войдите в WRMButtonDown и остановитесь
на вызове UpdateWindow. Единственным параметром является HWindow.
Вы можете предположить,  что параметр HWindow установлен правиль-
но, поскольку другие методы успешно используются. Поскольку ниче-
го  очевидно неверного здесь нет,  вы можете проверить следующее:
принимается ли действительно окном  сообщение  WM_PAINT,  которое
должно посылаться в окно при вызове UpdateWindow?

     Теперь вы наверное знаете,  как установить точку останова по
сообщению WM_PAINT. Если нет, то прочтите выше описание установки
точки останова по сообщению WM_COMMAND.

     Установив точку останова по сообщению, для выполнения выпол-
нения вызова UpodateWindow нажмите  F7.  Поскольку  программа  не
прерывается и не возвращает управления, сообщение WM_PAINT в окно
не посылается.

     Вы можете проверить,  что сообщения WM_PAINT не принимались,
путем нажатия   правой   кнопки   "мыши",   возврата   в  TDW  из
WMRButtonUp,  и последующей проверки нижней  области  диалогового
окна View іWindows Messages (ОбзоріСообщения Windows).  Здесь нет
сообщений WM_PAINT.  По каким-то причинам вызов  UpdateWindow  не
работает так, как ожидается.

                    Анализ причины ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Эта ошибка требует некоторого понимания  того,  как  Windows
работает с функцией UpdateWindow. Когда программа вызывает данную
функцию, Windows проверяет, является ли какая-либо часть окна не-
допустимой, и требуется ли отображать ее заново. Если это так, то
Windows посылает окну сообщение WM_PAINT. Если же нет, но незачем
попусту  тратить системные ресурсы на ненужное сообщение, поэтому
Windows ничего не делает.  Но откуда Windows знает, что окно тре-
буется обновить?

     Прикладная программа уведомляет Windows, что по крайней мере
часть окна  недопустима,  с  помощью  вызова  InvalidateRect  или
InvalidateRgn.  Эти  две  функции помещают в окно обновленную об-
ласть и уведомляют Windows,  что окно следует обновить с  помощью
сообщения   WM_PAINT.   Однако,   Windows  присваивает  сообщению
WM_PAINT,  которое оно посылает в ответ на  эти  вызовы  функций,
низкий приоритет, поэтому, если вы хотите, чтобы окно обновлялось
немедленно, следует воздерживаться от вызова UpdateWindow.

                     Исправление ошибки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Добавление в  WMRButtonDown  вызова  InvalidateRect устранит
проблему.  Функция  InvalidateRect  воспринимает  три  параметра:
идентифицирующий окно описатель окна,  указатель на прямоугольную
область,  отмечающий требующий обновления прямоугольник,  и пара-
метр типа Boolean, который определяет, следует ли стирать прямоу-
гольную область.  В качестве параметра,  задающего  указатель  на
прямоугольную  область,  вы можете передать значение nil,  указав
Windows,  что к обновляемому прямоугольнику следует добавить  все
окно.   В   следующем   исходном   коде  показано,  как  выглядит
WMRButtonDown с несколькими добавленными вызовами функций:

     void ScribbleWindow::WMRButtonDown(RTMessages);
     {
        InvalidateRect(HWindow, NULL, TRUE);
        UpdateWindow(HWindow);
     }

                    Проверка исправления
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Запустите программу  ColorScribble  и выйдите из нее,  затем
выйдите в TDW.  Когда вы вернетесь в Borland C++, внесите измене-
ния в WMRButtonDown, затем перекомпилируйте программу и запустите

лава 20. Отладка резидентных программ и драйверов устройств
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     С помощью Турбо отладчика вы  можете  отлаживать  не  только
обычные выполняемые файлы, но также резидентные в памяти програм-
мы (TSR) и драйверы устройств. Вы можете кроме того выполнять сам
отладчик, как резидентную программу (в то время, как работаете на
уровне DOS или запускаете другие программы).

     В Турбо отладчике в меню File (Файл) имеется три  новых  ко-
манды,  которые  предназначены специально для отладки резидентных
программ  и  драйверов  устройств.  Это   команды   FileіResident
(ФайліРезидент),  FileіSymbol Load (ФайліЗагрузка таблицы иденти-
фикаторов) и FileіTable Relocate (ФайліПеремещение таблицы  иден-
тификаторов).

     В данной  главе вы найдете краткое описание того,  что такое
резидентная программа и драйверы  устройств, и  дается  пояснение
того, как отлаживать их с помощью Турбо отладчика.

              Что такое резидентная программа?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Резидентными (TSR) называют такие программы,которые остаются
в оперативной памяти после того,  как  они  завершат  управление.
Например, SideKick  и  SuperKey - это резидентные программы,  они
все время находятся в памяти и вызываются с  помощью  специальных
оперативных клавиш.  Другие  резидентные  программы вызываются из
программ, которые выполняют соответствующее программное  прерыва-
ние. В Borland Си  и  С++,  например,  предусмотрена  специальная
функция  geninterrupt,  которая выдает такое программное прерыва-
ние.

     Резидентная программа состоит из двух частей - рабочей части
и резидентной части. Рабочая часть выполняет загрузку резидентной
части в память и устанавливает вектор прерываний, который опреде-
ляет характер  вызова резидентной в памяти программы.  Если рези-
дентная программа должна вызываться с помощью программного преры-
вания, то рабочая часть программы помещает адрес резидентной час-
ти кода в соответствующий  вектор  прерывания.  Если  резидентная
программа должна вызываться с помощью оперативной клавиши, то ре-
зидентная часть должна модифицировать обработчик  прерывания  DOS
для обработки нажатия соответствующих клавиш (клавиши) на клавиа-
туре.

     Когда рабочая часть завершает выполнение, она вызывает функ-
цию DOS,  которая позволяет части файла .EXE оставаться резидент-
ной в  оперативной  памяти  после завершения выполнения программы
(то есть программа завершила выполнения и  осталась  резидентной,
отсюда и  название  таких  программ  TSR  -  terminate  and  stay
resident). Рабочая часть резидентной программы знает размер рези-
дентной части, а также ее адрес в памяти, и передает эту информа-
цию DOS.  Операционная системе DOS при этом резервирует специаль-
ный блок памяти,  но может свободно записывать информацию в неза-
щищенную часть памяти.  Таким образом, резидентная часть остается
в памяти, а рабочая часть может быть "затерта".

     Тонкость отладки резидентных программ состоит в том,  что вы
должны иметь возможность  отлаживать  и  резидентную,  и  рабочую
часть программы.  Когда выполняется  файл  .EXE,  то  выполняется
только код рабочей части TSR. Поэтому, когда вы как обычно запус-
каете Турбо отладчик, задав имя файла, вы видите выполнение толь-
ко рабочей части кода программы:  то,  как он устанавливает рези-
дентную  часть  и обработчики прерываний.  Чтобы отлаживать рези-
дентную  часть,  вы  должны  задать  точку  останова  и   сделать
резидентным  сам  Турбо отладчик.  Подробнее мы расскажем об этом
дальше.

           Отладка резидентной в памяти программы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

          Примечание: С помощью TD вы можете  отлаживать  драйвер
     клавиатуры.

     Давайте рассмотрим процесс отладки резидентной программы:

     1. При компиляции или ассемблировании  резидентной программы
        обеспечьте  наличие в ней отладочной информации (информа-
        ции об идентификаторах).  Используйте для  этого  команды
        типа TASM /ZI или BCC -v, либо TPC /V.

     2. Если  вы выполняете компоновку резидентной программы, для
        обеспечения включения  информации для отладки используйте
        параметр компоновщика /v. Для того, чтобы поместить отла-
        дочную  информацию  в отдельный файл,  можно использовать
        утилиту TDSTRIP с параметром -s (однако,  этого не требу-
        ется  делать,  если  программа  представляет  собой  файл
        .EXE).

        Примечание: Программа TDSTRIP описывается  в поставляемом
        на  диске  файле  документации.  Имя и расположения этого
        файла указано в файле README.

     3. Теперь загрузите резидентную программу с Турбо отладчиком
        и установите точку останова в  начале  резидентной  части
        кода (с помощью клавиши F2). Вместо этого вы можете уста-
        новить точки останова (если хотите) в других местах рези-
        дентной части.

     4. После этого можно загрузить резидентную программу с Турбо
        отладчиком и выполнить ее рабочую часть с помощью команды
        RunіRun (ВыполнениеіВыполнение), как обычно. Дальше можно
        обычным образом отлаживать рабочую часть. Когда вы закон-
        чите выполнять рабочую часть, резидентная часть будет ус-
        тановлена в оперативной памяти.

     5. Выберите  команду  FileіResident  (ФайліРезидент),  чтобы
        сделать резидентным сам отладчик.  Это не  нарушит  рези-
        дентности вашей программы:  когда она будет выполняться в
        Турбо отладчике, она сама станет резидентной, как если бы
        вы запускали ее из командной строки. Единственная причина
        того,  что отладчик делается резидентным,  заключается  в
        том,  что  вы можете перейти обратно в DOS и вызвать вашу
        резидентную программу. При этом начнет выполняться ее ре-
        зидентная часть.

     6. Когда вы вернетесь снова к командной строке DOS, выполни-
        те резидентную часть вашей программы TSR, нажав соответс-
        твующую оперативную клавишу,  или  активизировав  ее  ка-
        ким-либо другим образом.  Выполняйте вашу программу,  как
        обычно.

     7. Когда в вашей программе встретится точка останова, иници-
        ализируется Турбо отладчик,  а код вашей программы  выве-
        дется  в  соответствующей точке.  Теперь вы можете начать
        отладку резидентной части программы.  (Кроме того, вы мо-
        жете повторно войти в отладчик из DOS,  дважды нажав кла-
        виши Ctrl-Break.)

     Второй метод отладки резидентной части программы  состоит  в
выполнении резидентной части из командной строки DOS, и последую-
щего использования Турбо отладчика для отладки области  оператив-
ной памяти, содержащей TSR.

     При использовании  данного  метода  вам  понадобится утилита
TDMEM,  которая выводит на экран схему использования  оперативной
памяти, и TDDEV, которая дает адрес сегмента, где загружена рези-
дентная часть вашей программы TSR.

     Чтобы использовать данный метод:

     1. Выполните шаг 1 и 2 первого метода для компиляции или ас-
        семблирования  кода  программы  и  для  выделения таблицы
        идентификаторов (если это необходимо) и  помещения  ее  в
        файл .TDS.  Если нужно, запустите также утилиту TDSTRIP с
        параметром -s для преобразования вашей резидентной  прог-
        раммы из формата .EXE в формат.COM.

     2. Запустите вашу резидентную программу в ответ на подсказку
        DOS, набрав ее имя. Например, если ваша резидентная прог-
        рамма называется TSR.EXE,  наберите TSR в ответ на  подс-
        казку DOS и нажмите клавишу Enter.

     3. Запустите утилиту TDMEM,  которая выводит схему использо-
        вания памяти. Запомните адрес сегмента, где загружена ре-
        зидентная  часть  вашей программы (мы обозначим его,  как
        Seg).

     4. Далее нужно определить объем  таблицы  идентификаторов  в
        памяти,  которую  требуется  выделить Турбо отладчику при
        его вызове.  Для этого  запомните  размер  вашей  таблицы
        идентификаторов  (то есть размер файла .TDS),  воспользо-
        вавшись командой DOS DIR.

        Данный размер представляет собой минимальный объем опера-
        тивной  памяти,  которую нужно выделить при запуске Турбо
        отладчика,  поскольку,  кроме хранящейся там  информации,
        Турбо  отладчик  при загрузке таблицы идентификаторов сам
        создает несколько таблиц (рабочих и других).

        Обычно нужно выделять примерно в 1.5 раза  больше памяти,
        чем занимает на диске файл .TDS.  Турбо отладчик сообщает
        вам,  когда вы выделяете слишком мало памяти для  таблицы
        идентификаторов, выводя сообщение:  "Not enough memory to
        load symbol table" ("Для загрузки таблицы идентификаторов
        недостаточно памяти"). Обычно это происходит при выполне-
        нии команды FileіSymbol Load (ФайліЗагрузка таблицы иден-
        тификаторов).

     5. Загрузите Турбо отладчик,  не задавая имя файла и выделив
        память для таблицы идентификаторов  с  помощью  параметра
        командной  строки -sm.  В этом параметр указывается аргу-
        мент,  определяющий объем (в килобайтах) памяти,  которая
        будет  выделяться для таблицы идентификаторов.  Например,
        если вы хотите зарезервировать для таблицы  идентификато-
        ров 3К, введите в ответ на подсказку DOS команду:

                TD -sm3

        Когда вы  загружаете  Турбо отладчик,  не задавайте имени
        файла, так как вы отлаживаете то, что уже находится в па-
        мяти.  В  используемом по умолчанию каталоге у вас должны
        присутствовать файл резидентной программы и файл  .TDS, к
        которым отладчик  может обращаться для получения информа-
        ции об идентификаторах.

     6. Теперь вы можете начать  отладку  резидентной  программы,
        задав точки останова, сделав Турбо отладчик резидентным и
        выполнив некоторые действия на уровне команд DOS, которые
        приведут  к  срабатыванию  точки останова.  Это переводит
        Турбо отладчик в соответствующее место  вашего  исходного
        кода.  Однако,  задача отладка может для вас упроститься,
        если вы сначала вызовите информацию  об  идентификаторах,
        которая  имеется  в  таблице идентификаторов,  и исходный
        файл.

     7. Когда появляется экран Турбо отладчика,  очистите индика-
        ционное сообщение,  нажав клавишу Esc,  и загрузите с по-
        мощью команды  FileіSymbol  Load  (ФайліЗагрузка  таблицы
        идентификаторов) таблицу идентификаторов. Если вы получи-
        те сообщение,  в котором говорится, что для загрузки таб-
        лицы идентификаторов не хватает памяти,  выйдите из Турбо
        отладчика и запустите его снова из командной  строки  DOS
        задав  в  качестве аргумента параметра -sm большее значе-
        ние.
     8. Таблица идентификаторов содержит  набор  идентификаторов,
        связанный с ячейками памяти в вашем коде. В качестве пре-
        фикса идентификаторов в таблице  указывается #имя_файла#,
        где  "имя_файла"  -  это имя файла резидентной программы.
        Например, если ваша резидентная программа называется TSR.
        ASM  (исходный  файл) и содержит метку Intr,  то ячейку в
        памяти отмечает идентификатор #TSR#INTR.

        Идентификаторы в таблице идентификаторов представляют со-
        бой  смещения (один от другого) на корректное число байт,
        но абсолютный адрес первого идентификатора  не определен,
        так  как DOS может загрузить вашу резидентную программу в
        другое место памяти (а не по тому адресу, как она ассемб-
        лировалась).  По  этой причине вы должны использовать ко-
        манду,  чтобы явным образом найти первый идентификатор  в
        памяти.

     9. Используйте команду FileіTable Relocate (ФайліПеремещение
        таблицы идентификаторов) для помещения первого  идентифи-
        катора из таблицы идентификаторов в соответствующую ячей-
        ку памяти. Таким образом, имеющаяся информация об иденти-
        фикаторах  будет соответствовать вашему коду (программе).
        Для этого в ответ на подсказку  Турбо  отладчика  задайте
        адрес  сегмента Seg вашей резидентной программы,  который
        определен с помощью утилиты TDMEM, плюс шестнадцатиричное
        значение 10 (для PSP размером 256 байт).

        Дизассемблированные из памяти  операторы синхронизированы
        с информацией из таблицы идентификаторов. В  случае нали-
        чия исходного файла исходные операторы выводятся  на  той
        же строке, что и информация из таблицы идентификаторов.

    10. Для перехода к сегменту оперативной памяти, где находится
        ваша  резидентная  программа,  используйте  команду  Goto
        (клавиши Ctrl-G). Это можно сделать, используя адрес сег-
        мента вашей программы TSR,  за которым  следует  смещение
        0000H,  или  с помощью перехода на конкретную метку вашей
        программы.

     После этого дальнейшие действия будут  эквивалентны  первому
методу, начиная с пункта 4.

                Что такое драйвер устройства?
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
     Драйвер устройства -  это  набор  подпрограмм,  используемых
операционной системой DOS для управления на нижнем уровне функци-
ями ввода-вывода.  Устанавливаемые драйверы устройств (в  отличие
от драйверов, встроенных в DOS) устанавливаются с помощью включе-
ния соответствующих строк, например:

        device = clock.sys

в файл CONFIG.SYS.  Когда DOS выполняет операцию ввода-вывода для
отдельного символа, она просматривает связанный список заголовков
устройств, выполняя поиск устройства с соответствующим логическим
именем (например,COM1). В случае драйверов блочно-ориентированных
устройств, таких, как драйвер диска, DOS отслеживает, сколько ус-
тановлено драйверов блочно-ориентированных устройств, и обознача-
ет каждый из них буквой:  A - первый установленный  драйвер  уст-
ройства, B  -  второй и т.д.  Когда вы,  например,  ссылаетесь на
дисковод C, DOS знает, что нужно вызвать драйвер третьего блочно-
ориентированного устройства.

     Связанный список  двух заголовков драйвера содержит смещение
двух компонентов самого драйвера устройства: подпрограмму функции
и подпрограмму обработки прерывания.

     Когда DOS  определяет,  что требуется вызвать данный драйвер
устройства, она вызывает драйвер дважды.  При первом вызове драй-
вера DOS общается с подпрограммой функции и передает ей указатель
на буфер в памяти,  который называется заголовком  запроса.  Этот
заголовок запроса содержит информацию о том, какие функции требу-
ет  выполнить DOS от драйвера  устройства.  Подпрограмма  функции
просто просто сохраняет данный указатель для последующего исполь-
зования. При втором вызове драйвера устройства DOS вызывает подп-
рограмму обработки  прерывания,  которая выполняет реальные функ-
ции, заданные  DOS  в  заголовке  запроса,  например,   пересылку
символов с диска.

     В заголовке запроса с помощью байта,  который называется ко-
дом команды,  определяется, что должен делать драйвер устройства.
Код команды определяет одну из предопределенных операций из набо-
ра операций, которые должны выполнять все драйверы устройств. На-
бор кодов команд (операций) для драйверов символьно-ориентирован-
ных и блочно-ориентированных устройств различен.

     Проблема при отладке драйверов устройств состоит в  том, что
файл .EXE  отсутствует,  так  как  для выполнения соответствующих
функций драйвер должен быть загружен во время загрузки  системы с
помощью  команды  DEVICE  = DRIVER.EXT,  где EXT - это расширение
.SYS,  .COM или .BIN. Это означает, что отлаживаемый драйвер уст-
ройства уже резидентен в памяти до начала отладки. Следовательно,
функции по выполнению загрузки и перемещения таблицы  идентифика-
торов весьма полезны, поскольку они могут восстановить информацию
об идентификаторах для дизассемблированного сегмента памяти (ког-
да драйвер загружен).  Как мы увидим далее, команда FileіResident
(ФайліРезидент) также очень полезна.

                 Отладка драйвера устройства
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Опишем теперь,  как  можно отладить драйвер устройства с по-
мощью утилиты TDREMOTE:

     1. При компиляции или  ассемблировании  драйвера  устройства
        убедитесь, что  вы включаете в него отладочную информацию
        (информацию об идентификаторах).  Используйте  для  этого
        команды типа TASM /ZI или BCC -v, либо TPC /V.

     2. Чтобы  включить в него отладочную информацию, скомпонуйте
        драйвер устройства с параметром /v.

     3. Для перемещения отладочной информации  из  файла  .EXE  в
        файл .TDS и для преобразования файла .EXE в файл .COM ис-
        пользуйте утилиту TDSTRIP:

               TDSTRIP -s -c имя_файла

        где "имя_файла" - имя отлаживаемого вами драйвера.

     4. Скопируйте файл .COM на удаленную систему.

     5. Измените файл CONFIG.SYS на удаленной системе,  включив в
        него строку:

           device = имя_файла.COM

     6. Убедитесь, что в имени файла указан корректный маршрут.

     7. Перезагрузите систему для загрузки драйвера устройства.

     8. Запустите утилиту TDDEV,  которая сообщит вам об адреса в
        памяти на  удаленной  системе,  по которому DOS загрузила
        драйвер устройства.  Запомните этот адрес.  Сегмент, ука-
        занный в данном адресе, мы будем обозначать, как Seg.

     9. Далее  нужно  определить  объем таблицы идентификаторов в
        памяти,  которую требуется выделить Турбо  отладчику  при
        его  вызове.  Для  этого  запомните  размер вашей таблицы
        идентификаторов (то есть размер файла  .TDS),  воспользо-
        вавшись командой DOS DIR.

        Данный размер представляет собой минимальный объем опера-
        тивной  памяти,  которую нужно выделить при запуске Турбо
        отладчика, поскольку,  кроме  хранящейся  там информации,
        Турбо отладчик при загрузке таблицы  идентификаторов  сам
        создает несколько таблиц (рабочих и других). Обычно нужно
        выделять примерно в 1.5 раза больше памяти,  чем занимает
        на диске файл .TDS. Турбо отладчик сообщает вам, когда вы
        выделяете слишком мало памяти для  таблицы  идентификато-
        ров, выводя сообщение:  "Not enough memory to load symbol
        table" ("Для загрузки таблицы идентификаторов недостаточ-
        но памяти"). Обычно это происходит при выполнении команды
        FileіSymbol Load (ФайліЗагрузка таблицы идентификаторов).

    10. Загрузите на удаленной системе утилиту TDREMOTE.

    11. Загрузите Турбо отладчик (используя в случае необходимос-
        ти параметры -r, -rp или -rs), не задавая имя файла и вы-
        делив память для таблицы идентификаторов с помощью  пара-
        метра  командной строки -sm.  В этом параметр указывается
        аргумент, определяющий объем (в килобайтах) памяти, кото-
        рая будет выделяться для таблицы идентификаторов.  Напри-
        мер, если вы хотите зарезервировать для таблицы идентифи-
        каторов 3К, введите в ответ на подсказку DOS команду:

                    TD -sm3

        Когда вы  загружаете  Турбо отладчик,  не задавайте имени
        файла, так как вы отлаживаете то, что уже находится в па-
        мяти.  В  используемом по умолчанию каталоге у вас должны
        присутствовать файла резидентной программы и файл .TDS, к
        которым отладчик  может обращаться для получения информа-
        ции об идентификаторах.

    12. Теперь вы можете начать отладку вашего драйвера  устройс-
        тва,  задав  точки останова,  сделав Турбо отладчик рези-
        дентным и выполнив некоторые действия  на  уровне  команд
        DOS,  которые приведут к срабатыванию точки останова. Это
        переводит Турбо отладчик в соответствующее  место  вашего
        исходного кода.  Однако, задача отладки может для вас уп-
        роститься, если вы сначала вызовите информацию об иденти-
        фикаторах,  которая имеется в таблице идентификаторов,  и
        исходный файл.

    13. Когда появляется экран Турбо отладчика,  очистите индика-
        ционное сообщение,  нажав клавишу Esc,  и загрузите с по-
        мощью команды  FileіSymbol  Load  (ФайліЗагрузка  таблицы
        идентификаторов) таблицу идентификаторов. Если вы получи-
        те сообщение,  в котором говорится, что для загрузки таб-
        лицы идентификаторов не хватает памяти,  выйдите из Турбо
        отладчика и запустите его снова из командной  строки  DOS
        задав  в  качестве аргумента параметра -sm большее значе-
        ние.

    14. Таблица  идентификаторов  содержит набор идентификаторов,
        связанный с ячейками памяти в вашем коде. В качестве пре-
        фикса  идентификаторов в таблице указывается #имя_файла#,
        где "имя_файла" - это имя  файла  резидентной  программы.
        Например,   если   ваш   драйвер   устройства  называется
        DRIVER.ASM (исходный файл)  и  содержит  метку  Intr,  то
        ячейку в памяти отмечает идентификатор #DRIVER#INTR.
        Идентификаторы в таблице идентификаторов представляют со-
        бой смещения (один от другого) на корректное  число байт,
        но  абсолютный адрес первого идентификатора не определен,
        так как DOS может загрузить ваш драйвер устройства в дру-
        гое место памяти (а не по тому адресу, как он ассемблиро-
        вался).  По этой причине вы должны использовать  команду,
        чтобы  явным образом найти первый идентификатор в памяти.

    15. Используйте команду FileіTable Relocate (ФайліПеремещение
        таблицы идентификаторов) для помещения первого  идентифи-
        катора из таблицы идентификаторов в соответствующую ячей-
        ку памяти. Таким образом, имеющаяся информация об иденти-
        фикаторах  будет соответствовать вашему коду (программе).
        Для этого в ответ на подсказку  Турбо  отладчика  задайте
        адрес  сегмента Seg вашей резидентной программы,  который
        определен на шаге 6.

    16. Диcассемблированные из памяти  операторы синхронизированы
        с информацией из таблицы идентификаторов. В  случае нали-
        чия исходного файла исходные операторы выводятся  на  той
        же строке, что и информация из таблицы идентификаторов.

    17. Задайте в вашем исходной файле точку останова.

    18. Выберите  команду  FileіResident  (ФайліРезидент),  чтобы
        сделать резидентным сам отладчик. Это не имеет ничего об-
        щего и не нарушит резидентности вашего драйвера: когда он
        будет выполняться в Турбо отладчике,  он сам станет рези-
        дентным  при  загрузке удаленной системы в результате вы-
        полнения файла CONFIG.SYS. Единственная причина того, что
        отладчик делается резидентным,  заключается в том, что вы
        можете перейти обратно в DOS и вызвать ваш  драйвер  уст-
        ройства.

    19. Когда вы вернетесь снова к командной строке DOS  на  уда-
        ленной системе,  сделайте что-либо для активизации вашего
        драйвера устройства. Например, выведите информацию на со-
        ответствующее устройство.

    20. Когда в вашей программе-драйвере встретится точка остано-
        ва, инициализируется Турбо отладчик, а код вашей програм-
        мы  выведется  в соответствующей точке.  Теперь вы можете
        начать отладку вашей программы.  (Кроме того,  вы  можете
        повторно  войти  в отладчик из DOS,  дважды нажав клавиши
        Ctrl-Break.)

                  Завершение сеанса отладки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для завершения сеанса отладки выйдите обычным путем из Турбо
отладчика, выбрав команду FileіQuit (ФайліВыход или нажав клавиши
Alt-X. Если вы отлаживаете резидентную программу, ее можно завер-
шить следующим образом:

     - Если вы  отлаживаете  резидентную  программу,  загруженную
       Турбо отладчиком, она будет разгружена автоматически.

     - Если вы отлаживаете программу, загруженную непосредственно
       из DOS,  запустите ее, пока Турбо отладчик не станет снова
       резидентным.  После того,  как Турбо отладчик станет рези-
       дентным, дважды нажмите клавиши Ctrl-Break для вывода Тур-
       бо отладчика, затем используйте клавиши Alt-X, чтобы выйти
       из Турбо отладчика, но оставить программу резидентной.

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

            Приложение A. Параметры командной строки
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда вы запускаете Турбо отладчик с помощью командной стро-
ки DOS,  его можно одновременно настроить,  используя  для  этого
различные параметры. Общий формат командной строки имеет вид:

        TD [параметры] [имя_программы [аргументы_программы] ]

     Элементы, заключенные в квадратные скобки, являются необяза-
тельными. Если за параметром указывается минус (-), то данный па-
раметр запрещается (если он разрешен в файле конфигурации).

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і   Параметр                 Функция                            і
ГДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і-cимя_файла і Файл конфигурации, активизирующийся при загрузке.і
і            і                                                  і
і-do         і Другой дисплей.                                  і
і            і                                                  і
і-dp         і Переключение страниц.                            і
і            і                                                  і
і-ds         і Переключение на содержимое экрана пользователя.  і
і            і                                                  і
і-h          і Вывод справочного экрана.                        і
і            і                                                  і
і-?          і Вывод справочного экрана.                        і
і            і                                                  і
і-i          і Обработка переключения идентификатора процесса.  і
і            і                                                  і
і-k          і Разрешает запись нажатий клавиш.                 і
і            і                                                  і
і-l          і Запуск кода инициализации Ассемблера.            і
і            і                                                  і
і-mN         і Размер динамически распределяемой области памяти.і
і            і                                                  і
і-p          і Разрешает работать с "мышью".                    і
і            і                                                  і
і-r          і Отладка на удаленных системах, COM1 (быстр.).    і
і            і                                                  і
і-rnлок;удал і Разрешает сетевую отладку.                       і
і            і                                                  і
і-rpN        і Порт COM для удаленной связи.                    і
і            і                                                  і
і-rsN        і Скорость связи: 1 - медленная, 2 - средняя, 3 -  і
і            і быстрая.                                         і
і            і                                                  і
і-sdкаталог  і Каталог исходного файла.                         і
і            і                                                  і
і-sc         і Отмена проверки на строчные/прописные буквы.     і
і            і                                                  і
і-smN        і Задает объем памяти для таблицы идентификаторов  і
і            і (в килобайтах).                                  і
і            і                                                  і
і-vn         і Запрещение режима 43/50 строк.                   і
і            і                                                  і
і-vg         і Полное сохранение графики.                       і
і            і                                                  і
і-vp         і Сохранение палитры EGA.                          і
і            і                                                  і
і-yN         і Задает размер оверлейного буфера.                і
і            і                                                  і
і-yeN        і Устанавливает оверлейную область EMS  в значение і
і            і N (N страниц по 16 килобайт).                    і
АДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Приложение B. Технические замечания
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Данное приложение  предназначено  для опытных пользователей,
которые хотят понять некоторые технические детали,  лежащие в ос-
нове операций Турбо отладчика.  Не отчаивайтесь,  если изложенный
здесь материал сначала покажется вам совершенно непонятным. Чтобы
успешно пользоваться отладчиком, разбираться во всем этом не обя-
зательно.

     Часть тем,  которые освещаются в данном приложении, позволят
вам понять, каким образом отладчик взаимодействует с операционной
системой DOS,  аппаратным обеспечением,  и вашей программой.  Это
поможет вам определить,  как может  различаться  поведение  вашей
программы во время отладки и во время выполнения.

     Вы узнаете также, как легко можно вызвать сбой системы и как
можно этого избежать.

        Измененный адрес загрузки и свободная память
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Когда Турбо отладчик загружает вашу программу,  она размеща-
ется в памяти после отладчика.  Из  этого вытекает два важных ре-
зультата:  ваша  программа  загружается в сегмент с более старшим
адресом,  и у нее будет меньше свободной памяти. Учитывая измене-
ния объема свободной памяти, может оказаться трудно воспроизвести
ошибки из-за ее распределения.

     Если вы используете компьютер, основанный на процессоре 386,
то для устранения этих проблем можно использовать программу  вир-
туальной отладки TD386 (об этом рассказывается в Главе 15).

                        Сбой системы
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Так как Турбо отладчик может может выполнять в вашей системе
чтение и запись в память по любому адресу,  непреднамеренно моди-
фицировав определенные ячейки памяти (например, внутренние облас-
ти DOS или таблицу прерываний,  которая начинается с ячейки с ну-
левым адресом), вы можете вызвать сбой системы.

     Например, изменение аппаратного вектора прерывания от тайме-
ра в ячейке 0000h:0020h почти всегда приводит к проблемам.

  Трассировка в DOS и переключение идентификатора процесса
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Турбо отладчик отслеживает выполняющийся процесс  (это может
быть сам отладчик или ваша программа), поэтому он может открывать
и закрывать файлы,  не взаимодействуя с описателями файлов  вашей
программы.  Такое  переключение осуществляется с помощью функцио-
нального вызова DOS.  Переключение выполняется каждый раз,  когда
ваша программа запускается из отладчика,  или когда управление из
нее опять передается отладчику.  Поскольку  операционная  система
DOS не реентерабельна,  то при задании точек останова или трасси-
ровке внутри DOS вы можете столкнуться с проблемами.

     Если вы хотите углубиться в DOS,  то для запрещения переклю-
чения  идентификатора  процесса  используйте  параметр  командной
строки -i-.  Однако при этом ваша  программа  будет  использовать
описатели файлов совместно с Турбо отладчиком, что может привести
к тому, что программа или отладчик исчерпают их число.

      Использование сопроцессора 8087/80287 и эмулятора
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

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

          Прерывания, используемые Турбо отладчиком
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы обеспечить  возможность отладки вашей программы, Турбо
отладчик перехватывает некоторые  векторы  прерываний.  Следующие
описания  позволят  определить,  возможны ли взаимодействия между
вашей программой и Турбо отладчиком.

                   Прерывание 1/Прерывание3
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Отладчик использует эти прерывания (INT1/INT2) для обработки
точек  останова  и пошагового выполнения инструкций.  Если данные
прерывания модифицируются вашей программой,  то отладчик может не
получить управления на следующей точке останова.  Обычно приклад-
ные программы не используют эти прерывания,  так как они резерви-
руются для других программ (таких, как отладчики), которые должны
управлять их выполнением.

                        Прерывание 2
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Многие аппаратные  отладчики  используют  данное  прерывание
(INT2) для сообщения о том,  что удовлетворено указанное условие.
Если ваша программа работает с этим прерыванием,  то такие  аппа-
ратные платы и соответствующие аппаратные драйверы не смогут пра-
вильно работать. Если вам необходимо использовать это прерывание,
и вы не хотите его обслуживать, нужно организовать цепочку с пре-
дыдущим его пользователем.

                        Прерывание 9
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Это аппаратное прерывание от клавиатуры (INT9),  которое ис-
пользуется  для отслеживания кодов нажатий и освобождений клавиш.
При выполнении программы пользователя отладчик ведет список  (це-
почку) этих прерываний, поэтому от может получить управление, ес-
ли программа входит в цикл.  При каждом запуске  вашей  программы
отладчик вновь устанавливает этот вектор, что позволяет программе
для продолжения правильной работы модифицировать данное  прерыва-
ние.

       Отладка при использовании прерываний INT3 и INT1
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы хотите отладить программу,  которая  использует  эти
прерывания,  версия  отлаживаемой вами программы должна загружать
эти векторы прерываний только в случае абсолютной необходимости и
восстанавливать  их содержимое,  как только она закончит работу с
ними.  Этот метод позволяет минимизировать  объем  кода,  который
нельзя  отлаживать.  Когда ваша программа загрузит данные векторы
прерываний, то для выполнения ее кода отладчик использовать нель-
зя.

     Сохранение содержимого и переключение режима экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Обычно отладчик пытается при выполнении участка вашей  прог-
раммы сохранять  и  восстанавливать режим экрана программы.  Если
для изменения режима экрана вы используете только стандартные об-
ращения  к базовой системе ввода-вывода,  то все будет нормально.
Если вы работаете с регистрами контроллера дисплея непосредствен-
но, то отладчик может нарушить установленные вами значения.

                    Потребности в памяти
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При первоначальном запуске отладчика  DOS  загружает  его  в
первую  свободную область памяти,  расположенную выше DOS и всеми
резидентными программами.  После этого отладчик  над  программным
стоком выделяет рабочий стек и динамически распределяемую область
памяти.  Далее в памяти  следует  таблица  идентификаторов  вашей
программы, а за ней - сама отлаживаемая отлаживаемая программа.

     Когда вы  возвращаетесь в DOS,  отладчик освобождает память,
используемую для таблицы идентификаторов и отлаживаемой  програм-
мы.  Если  ваша  программа с помощью функции выделения памяти DOS
(48) выделяла какие-либо блоки памяти,  то эта память также осво-
бождается Турбо отладчиком.

                        Поддержка EMS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если в вашей системе имеется плата расширенной памяти (EMS),
Турбо отладчик будет использовать ее для хранения таблицы иденти-
фикаторов отлаживаемой программы. Это позволяет освободить больше
памяти для самой программы.  Отладчик сохраняет и восстанавливает
состояние  драйвера EMS,  что позволяет вам отлаживать программы,
использующие память EMS.

     Если ваша  программа должна использовать всю память EMS, или
вы сталкиваетесь с проблемами при взаимодействии  вашей программы
с Турбо отладчиком, когда оба они используют EMS, нужно запретить
отладчику использование EMS (для этого  можно  применить  утилиту
TDINST или использовать параметр -ye0 для  запрещения буферизации
оверлеев в расширенной памяти).

       Сохранение и восстановление вектора прерываний
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Турбо отладчик поддерживает три различные  копии  первых  48
векторов прерываний в младших адресах памяти (от 00 до 2F).

     При первоначальном  запуске  Турбо  отладчика  из  командной
строки DOS делается копия векторов.  Эти векторы восстанавливают-
ся,  когда  вы  возвращаетесь  обратно  в  DOS  с помощью команды
FileіQuit (ФайліВыход) или клавиш  Alt-X.  Данные  векторы  также
восстанавливаются, если вы во время отладки программы используете
команду F10іFileіDOS Shell (ФайліКомандный процессор операционной
системы) для того, чтобы дать команду DOS.

     Второй набор  векторов  -  это векторы Турбо отладчика.  Они
действуют,  когда Турбо отладчик работает и выводит информацию на
экран.  Каждый раз,  когда отладчик получает управление после вы-
полнения вашей программы, они восстанавливаются.

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

    Приложение C. Ключевые слова встроенного Ассемблера
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В этом приложении приведен перечень мнемонических  обозначе-
ний  команд и специальных обозначений,  которые можно вставлять в
программу с помощью встроенного Ассемблера.  Приведенные ниже за-
резервированные слова полностью совпадают с теми, которые исполь-
зуются в Турбо Ассемблере.

   Мнемонические обозначения команд процессоров 8086/80186/80286
                                                      Таблица B.1
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і  FAA              INC               LIDT**             REPNZ  і
і  FAD              INSB*             LLDT**             REPZ   і
і  FAM              INSW*             LMSW**             RET    і
і  FAS              INT               LOCK               REFT   і
і  FDC              INTO              LODSB              RQL    і
і  FDD              IRET              LODSW              ROR    і
і  FND              JB                LOOP               SAHF   і
і  FRPL**           JBE               LOOPNZ             SAR    і
і  FOUND*           JCXZ              LOOPZ              SBB    і
і  FALL             JE                LSL**              SCASB  і
і  FLC              JL                LTR**              SCASW  і
і  FLD              JLE               MOV                SGDT** і
і  FLI              JMP               MOVSB              SHL    і
і  FLTS**           JNB               MOVSW              SHR    і
і  FMC              JNBE              MUL                SLDT** і
і  FMP              JNE               NEG                SMSW** і
і  FMPSB            JNLE              NOP                STC    і
і   MPSW            JNO               NOT                STD    і
і   WD              JNP               OR                 STI    і
і   AA              JO                OUT                STOSB  і
і   AS              JP                OUTSB*             STOSW  і
і   EC              JS                OUTSW*             STR**  і
і   IV              LAHF              POP                SUB    і
і   NTER*           LAR**             POPA*              TEST   і
і   SC              LDS               POPF               WAIT   і
і   LT              LEA               PUSH               VERR** і
і   DIV             LEAVE*            PUSHA*             VERW** і
і   MUL             LES               PUSHF              XCHG   і
і   N               LGDT**            RCL                XLAT   і
і                                                        XOR    і
і                                                               і
і** - доступны только при работе с процессорами 186 и 286       і
і                                                               і
і * - доступны только при работе с процессором 286              і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

    Отладчик TDW поддерживает все мнемоники инструкций и регистры
процессора 80386 и сопроцессора 80387:

      Мнемонические обозначения команд процессора 80386
                                                      Таблица C.2
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і  BSF               LSS               SETG                SETS і
і  BSR               MOVSX             SETL                SHLD і
і  BT                MOVZX             SETLE               SHRD і
і  BTC               POPAD             SETNB               CMPSDі
і  BTR               POPFD             SETNE               STOSDі
і  BTS               PUSHAD            SETNL               LODSDі
і  CDQ               PUSHFD            SETNO               MOVSDі
і  CWDE              SETA              SETNP               SCASDі
і  IRETD             SETB              SETNS               INSD і
і  LFS               SETBE             SETO                OUTSDі
і  LGS               SETE              SETP                JECXZі
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

немонические обозначения команд процессора 80486   Таблица C.3
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і              BSWAP               INVLPG                       і
і              CMPXCHG             WBPINVD                      і
і              INVD                XADD                         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                 Регистры процессора 80386         Таблица C.4
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і              EAX                 EDI                          і
і              EBX                 EBP                          і
і              ECX                 ESP                          і
і              EDX                 FS                           і
і              ESI                 GS                           і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Регистры центрального процессора      Таблица C.5
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іБайтовые регистры            AH, AL, BH, BL, CH, CL, DH, DL    і
іРегистры размером в слово    AX, BX, CX, DX, SI, DI, SP, BP    і
іСегментные регистры          CS, DS, ES, SS                    і
іРегистры с плавающей         ST, ST(0), ST(1), ST(2), ST(3),   і
іточкой                       ST(4), ST(5), ST(6), ST(7)        і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

            Специальные зарезервированные слова    Таблица C.6
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                   WORD PTR            TBYTE PTR               і
і                   BYTE PTR            NEAR                    і
і                   DWORD PTR           FAR                     і
і                   QWORD PTR           SHORT                   і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

 Мнемонические обозначения команд сопроцессора 8087/80287
                                                      Таблица C.7
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і FABS             FIADD              FLDL2E            FST     і
і FADD             FICOM              FLDL2T            FSTCW   і
і FADDP            FICOMP             FLDPI             FSTENV  і
і FBLD             FIDIV              FLDZ              FSTP    і
і FBSTP            FIDIVR             FLD1              FSTSW*  і
і FCHS             FILD               FMUL              FSUB    і
і FCLEX            FIMUL              FMULP             FSUBP   і
і FCOM             FINCSTP            FNOP              FSUBR   і
і FCOMP            FINIT              FNSTS**           FSUBRP  і
і FDECSTP          FISTP              FPREM             FWAIT   і
і FDISI            FISUB              FPTAN             FXAM    і
і FDIV             FISUBR             FRNDINT           FXCH    і
і FDIVP            FLD                FRSTOR            FXTRACT і
і FDIVR            FLDCW              FSAVE             FYL2X   і
і FDIVRP           FLDENV             FSCALE            FYL2XP1 і
і FENI             FLDLG2             FSETPM*           F2XM1   і
і FFREE            FLDLN2             FSQRT                     і
і                                                               і
і*  - доступны только при работе с числовым сопроцессором 287   і
і                                                               і
і** - при работе с сопроцессором 80287 в командах fstsw  и      і
і     fnstsw кроме обычных операндов,  расположенных в памяти,  і
і     в качестве операнда может использоваться регистр AX.      і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

немонические обозначения команд сопроцессора 80387 Таблица C.8
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                   FCOS                FUCOM                   і
і                   FSIN                FUCOMP                  і
і                   FPREM1              FUCOMPP                 і
і                   FSINCOS                                     і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

           Приложение D. Настройка Турбо отладчика
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Турбо отладчик будет готов к работе,  как только вы получите
рабочую копию дистрибутивного диска.  Однако,  вы можете изменить
многие  используемые  по умолчанию параметры,  запустив программу
(утилиту) установки TDINST.EXE.  Некоторые параметры можно  изме-
нять также при запуске Турбо отладчика из командной строки DOS (с
помощью параметров командной строки).  При  частом  использовании
для работы с Турбо отладчиком одних и тех же параметров вы можете
зафиксировать их с помощью программы установки.

     Программа установки позволяет  вам  устанавливать  следующие
элементы:

     - цвета окон, диалоговых окон и меню;

     - параметры вывода:  начальный экран, режим переключения эк-
       ранов,  формат вывода целых чисел,  длину списка регистра-
       ции,  размер табуляции,  максимальный размер окна  Watches
       (Просмотр),  контроль  за  возникновением  помех на экране
       ("снег"), режим 45/50 строк и сохранение графики, обновле-
       ние экрана пользователя и длину списка регистрации;

     - команду  запуска  редактора и каталоги для поиска исходных
       файлов, а также справочных файлов Турбо отладчика и файлов
       конфигурации;

     - параметры клавиатуры:  клавишу прерывания программы и сок-
       ращения для клавиши Ctrl;

     - параметры ввода пользователя  подсказки:  звуковой  сигнал
       при подсказке, необходимость нажатия клавиши Esc для сбро-
       са ошибки и длину протокола команд,  возможность использо-
       вания "мыши" и сокращений с клавишей Ctrl;

     - параметры отладки на уровне исходного кода: параметры язы-
       ка,  различимость  регистра  символов  и  (для  отладки  в
       Windopws)  поддержку  для  отладки  программ ObjectWindows
       Windows Message (Сообщения Windows);

     - прочие  параметры:  использование расширенной памяти (EMS)
       для таблицы идентификаторов, перехвата прерываний NMI, об-
       работку DOS переключения идентификатора,  удаленной отлад-
       ки, область свопинга командного процессора DOC, размер па-
       мяти для таблицы идентификаторов, порядок сортировки в со-
       ответствии с различными национальными алфавитами.

                   Запуск программы TDINST
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для запуска  программы установки TDINST введите TDINST в от-
вет на подсказку DOS. После этого программа установки выводит ос-
новное меню.  Вы можете нажать подсвеченную первую букву элемента
меню  или использовать для перемещения к нужному элементу клавиши
управления курсором (стрелки) и нажать клавишу  Enter.  Например,
для  изменения параметров экрана нажмите D.  Элементы других меню
программы установки выбираются точно также. Для возврата в преды-
дущее  меню нажмите клавишу Esc.  Чтобы вернуться в основное меню
вам может потребоваться нажать Esc несколько раз.

                               ЪДДДДДДДДДДДДДДДДДДДДДДДДДї
          Цвета                і Colors                > і
          Дисплей              і Display...              і
          Параметры            і Options               > і
          Режим дисплея        і Mode for display      > і
          Сохранение           і Save                  > і
          Выход                і Quit                    і
                               АДДДДДДДДДДДДДДДДДДДДДДДДДЩ

             Параметры командной строки TDWINST
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     В TDINST для задания файла конфигурации,  настройки конфигу-
рации TDW,  включения  или  выключения поддержки "мыши" вы можете
использовать параметры командной строки.  Можно  также  задавать,
настройку конфигурации какого выполняемого файла вы хотите выпол-
нять.

     Команда вызова программы TDINST имеет следующий синтаксис:

     tdinst [параметры] [выполняемый_файл]

     Например для настройки конфигурации  TD286.EXE  из  каталога
программы можно ввести:

     tdinst td286.exe

                         Параметр -C
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Чтобы задать при запуске TDINST файл  конфигурации,  исполь-
зуйте параметр -c. При этом используется следующий синтаксис:

     tdinst -cимя_файла

     С помощью данного параметра вы можете модифицировать текущий
существующий файл конфигурации или создать новый.  Если  параметр
-c не указывается, то вы можете задать имя файла конфигурации при
его сохранении.  По умолчанию файл конфигурации  Турбо  отладчика
называется   TDCONFIG.TD.   Файл   конфигурации   TDW  называется
TDCONFIG.TDW.  (Для создания файла конфигурации,  совместимого  с
отладчиком TDW, нужно запускать программу TDINST с параметрами -c
и -w.)

                         Параметр -W
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для настройки конфигурации TDW или  файла  конфигурации  TDW
запустите TDINST  с  параметром -w.  В этой версии TDINST имеется
меньше параметров,  так как TDW не поддерживает всех средство  TD
(например, клавиатурные макрокоманды).  Если параметр недоступен,
вы не сможете его выбирать.

                         Параметр -P
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Этот параметр вы можете использовать для разрешения или зап-
рещения поддержки "мыши".  Чтобы запретить поддержку "мыши",  ис-
пользуйте после параметра дефис:

     TDINST -P-

                   Установка цветов экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для вывода меню выбора цвета выберите команду Colors (Цвета)
основного меню.  После  этого вам будет предоставлена возможность
выбора из 2 наборов цветов: настраиваемый и используемый по умол-
чанию набор номер 2.

                   Настройка цветов экрана
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы выбираете команду Customize (Настроить), то выводит-
ся третье  меню,  параметры  которого позволяют настраивать окна,
диалоговые окна, меню и экраны.

                            Окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для настройки окон выберите команду меню Windows (Окна). При
этом будет открыто четвертое меню, из которого вы сможете выбрать
тип настраиваемого  окна:  Text (текстовое),  Data (окно данных),
Low Level (нижний уровень,  например, окно CPU), и Other (прочие,
например, окно Breakpoints). Выбор одного из этих параметров при-
водит к выводу еще одного меню со списком элементов окон, а также
с парой окон-примеров (активным и неактивным),  по которым вы мо-
жете проверить сочетание цветов.  Экран выглядит следующим  обра-
зом:

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іTurbo Debugger Installation V3.0   1991 Borland Int. Corp. MENUі
іЪДДДДДДДДДДДДДДїДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
іі±Colors±±±±±±>і°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
ііЪДДДДДДДДДДДДДДДДДДДї°°°°°°°°°°°°°°Ъ[*]ДДДДДText WindowДДДДДї°і
ііі±Customize±±±±±±±±>і°°°°°°°°°°°°°°іNormal text             ^°і
ііі ЪДДДДДДДДДДДДїset і°°°°°°°°°°°°°°іSelected text           І°і
іАі і±Windows±±±>іset і°°°°°°°°°°°°°°іBreakpoint              І°і
і°АДі ЪДДДДДДДДДДДДДДДДї°°°°°°°°°°°°°і                        v°і
і°°°АДі±Text±±±±±±±±±±>і°°°°°°°°°°°°°А<ІІІІІІІІІІІІІІІІІІІІІІ>Щ°і
і°°°°°і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї°ЪДДДAnother WindowДДДДДДДї°і
і°°°°°і і±Window±Background±±±±±±±±і°і                        і°і
і°°°°°АДі Selected text background і°і                        і°і
і°°°°°° і Breakpoint               і°і                        і°і
і°°°°°° ГДДДДДДДДДДДДДДДДДДДДДДДДДДґ°і                        і°і
і°°°°°° і Standord foreground      і°і                        і°і
і°°°°°° і Selected text foreground і°АДДДДДДДДДДДДДДДДДДДДДДДДЩ°і
і°°°°°° і Current window border    і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Non-current border       і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Button                   і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Scroll bar               і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° АДДДДДДДДДДДДДДДДДДДДДДДДДДЩ°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і Alt: X - exit±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. D.1. Настройка цветов окон

     Colors - цвета;  Customize - настройка; Windows - окна; Text
- текст;  Window background - фоновый цвет  окна;  Selected  text
background - цвет выбранного текста;   Breakpoint - точка остано-
ва; Standard foreground - стандартный цвет переднего раздела (ос-
новной цвет);  Selected  text foreground - цвет переднего раздела
для выбранного текста;  Current window border - граница  текущего
окна; Button  - "кнопка";  Scroll bar - полоса прокрутки;  Normal
text - обычный текст;  Selected  text  -  выбранный  текст;  Text
window - текстовое окно; Another window - другое окно.

     Выбор каждого  из  этих элементов приводит к выводу окна па-
литры. Для перемещения по палитре можно использовать клавиши  уп-
равления курсором (клавиши стрелок). Справа от области меню и па-
литры вы увидите все окна или рамки того вида,  который будет из-
менен.  При перемещении подсветки меню по различным цветам, окно,
цвет которого вы выбираете, будет изменяться, чтобы показать, как
это будет выглядеть. Когда вы выберете нужные цвета, нажмите кла-
вишу Enter (при этом цвета будет восприняты).

            Примечание: Турбо отладчик обслуживает  три  цветовых
     таблицы: одну для цветного дисплея, другую - для черно-бело-
     го,  и третью - для монохромного.  Одновременно можно менять
     только  один  набор цветов (на основе текущего видеорежима и
     аппаратного обеспечения дисплея). Поэтому, если вы работаете
     на цветном дисплее и хотите использовать при настройке черно
     -белую таблицу,  наберите перед запуском TDINST в  ответ  на
     подсказку DOS BW80.

                       Диалоговые окна
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При выборе   команды   Dialogs   (Диалоговые  окна)  в  меню
Customize (Настройка) выводится меню со списком диалоговых окно и
элементов меню,  примером  диалогового окна,  с которым вы можете
экспериментировать. Экран выглядит следующим образом:

ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
іTurbo Debugger Installation V3.0   1991 Borland Int. Corp. MENUі
іЪДДДДДДДДДДДДДДїДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДі
іі±Colors±±±±±±>і°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
ііЪДДДДДДДДДДДДДДДДДДДї°°°°°°°°°°°°°°Ъ[*]ДДДДДDialog BoxДДДДДДДїі
ііі±Customize±±±±±±±±>і°°°°°°°°°°°°°°іBox title                іі
ііі ЪДДДДДДДДДДДДїset і°°°°°°°°°°°°°°іText entry    List item 1іі
іАі і±Windows±±±>іset і°°°°°°°°°°°°°°іHistory item  Higlight   іі
і°АДі ЪДДДДДДДДДДДДДДДДї°°°°°°°°°°°°°іCurrent item Current itemіі
і°°°АДі±Text±±±±±±±±±±>і°°°°°°°°°°°°°і              List item 2іі
і°°°°°і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї°і [ ] Check box           іі
і°°°°°і і±Window±Background±±±±±±±±і°і [ ] Current item        іі
і°°°°°АДі List and group backgroundі°і ( ) Radio button        іі
і°°°°°° і Text and entry backgroundі°і                         іі
і°°°°°° і Highlight background     і°і Information text        іі
і°°°°°° і Button background        і°і                         іі
і°°°°°° ГДДДДДДДДДДДДДДДДДДДДДДДДДДґ°і Button  Default  Active іі
і°°°°°° і Window border            і°і ±±±±±±  ±±±±±±±  ±±±±±± іі
і°°°°°° і Standard text            і°АДДДДДДДДДДДДДДДДДДДДДДДДДЩі
і°°°°°° і Information text         і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Active item              і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Default item             і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Current list item        і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і List item                і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Hot Letter               і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Scroll bar               і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° і Close button             і°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°° АДДДДДДДДДДДДДДДДДДДДДДДДДДЩ°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°і
і Alt: X - exit±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

     Рис. D.2. Настройка цветов диалоговых окон

     Colors - цвета;  Customize - настройка; Windows - окна; Text
- текст;  Window background - фоновый цвет  окна;  Selected  text
background - цвет выделенного текста;  Breakpoint - точка остано-
ва; Standard foreground - стандартный цвет переднего раздела (ос-
новной цвет);  Selected text foreground - цвет переднего  раздела
для выбранного текста;  Scroll bar - полоса прокрутки; Dialog box
- диалоговое окно; Box title - заголовок окна; Text entry - текс-
товая запись; History item - запись протокола; Current item - те-
кущая запись;  List item - элемент списка; Highlight - подсветка;
Current item - текущий элемент;  Check box - блок проверки (пара-
метр);  Radio button - селективный переключатель; Button - "кноп-
ка"; Default  - по умолчанию;  Active - активный;  List and group
background -  фоновый  цвет  списков  и  групп;  Text  and  entry
background - фоновый цвет текста и записей;  Highlight background
- фоновый цвет подсвеченного элемента:  Button background - фоно-
вый цвет "кнопки";  Window border - граница окна; Standard text -
стандартный  текст;  Information  text  -  информационный  текст:
Active item - активный элемент; Default item - элемент, использу-
емый по умолчанию;  Current list item - текущий  элемент  списка;
List  item  -  элемент  списка;  Hot Letter - оперативная клавиша
(буква);  Scroll bar - полоса прокрутки;  Close button - "кнопка"
закрытия.

     Как и в меню Windows, выбор элемента текущего меню открывает
палитру, из которой вы можете выбирать цвет для данного элемента.

                            Меню
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы выбираете в меню Customize (Настройка) команду Menus
(Меню),  то  открывается меню настройки параметров меню,  а также
выводится образец меню.  Выбор элемента меню  приводит  к  выводу
обычной палитры цветов.

                                  ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     Фоновый цвет меню            і Menu background             і
     Фоновый цвет стандартного    і Standatd item background    і
      /активного элемента         і Active item foreground      і
     Оперативная клавиша          і Hot letter                  і
                                  ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
     Основной цвет строки         і Status foreground           і
      состояния                   і Status backgropund          і
     Фоновый цвет строки          АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
      состояния

                            Экран
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Выбор команды  Screen  (Экран)  в меню Customize (Настройка)
открывает меню,  из которого вы можете получить доступ к  другому
меню с образцами экрана и палитрами для элементов экрана, а также
примером фонового цвета экрана,  на котором вы можете  их  прове-
рить.

                                    ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДї
     Образец фонового цвета         і Pattern for background  > і
                                    ГДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
     Образец фона                   і Pattern background        і
     Образец основного цвета        і Pattern foreground        і
     Перемещение окна               і Window move               і
                                    АДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

              Цвета, используемые по умолчанию
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если вы выберите  в  меню  Colors  (Цвета)  команду  Default
Colors Set (Набор цветов, используемый по умолчанию), то на экран
выводятся активное и неактивное текстовые окна,  и вы можете  ви-
деть заданные по умолчанию цвета для их элементов.

         Установка параметров экрана Турбо отладчика
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для вывода  диалогового  окна  параметров  экрана   (Display
options)  выберите в основном меню команду Display (Экран).

   ЙН[*]ННННННННННННННННDisplay optionsНННННННННННННННННННННННН»
   є Display swapping      Integer format    Beginning display є
   є                                                           є
   є ( ) None               ( ) Hex          (*) Source        є
   є (*) Smart              ( ) Decimal      ( ) Assembler     є
   є ( ) Always             (*) Both                           є
   є                                                           є
   є Screen lines           Tab size         Max tiled watch   є
   є (*) 25 ( ) 43/80        8                6                є
   є                                                           є
   є                   User screen updating  Log list length   є
   є [ ] Fast screen update ( ) Other display 50               є
   є [X] Permit 43/80 lines (.) Flip pages                     є
   є [ ] Full graphics save ( ) Swap              OK   Cancel  є
   є                                             ±±±±± ±±±±±±  є
   ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

     Рис. D.3 Диалоговое окно Display Options

     Display options - параметры экрана;  Display swapping -  пе-
реключение  экрана;  Integer  format - формат вывода целых чисел;
Beginning display - начальный экран; None - никакого; Smart - эф-
фективное;  Always - постоянное; Hex - шестнадцатиричный; Decimal
- десятичный;  Both - оба; Source - исходный; Assembler - Ассемб-
лер;  Screen lines - строки экрана;  Tab size - размер табуляции;
Max tiled  watch  -  максимальный  размер окна просмотра;  Screen
updating - обновление экрана;  Log list length - длина списка ре-
гистрации;  Fast screen update - быстрое обновление экрана; Other
display - другой дисплей;  Permit 43/80 lines - разрешение режима
43/80  строк;  Flip  pages - переключение страниц;  Full graphics
save - полное сохранение графики;  Swap - переключение;  OK - вы-
бор; Cancel - отмена.

     Эти устанавливаемые параметры вывода включают в себя те  па-
раметры, которые вы можете указывать в ответ на подсказку DOS при
запуске Турбо отладчика,  а также те,  которые  можно  установить
только с  помощью  программы  TDINST.  Параметры командной строки
Турбо отладчика и соответствующие  установки  TDINST  описываются
ниже.

               Переключатели Display Swapping
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Селективные переключатели Display Swapping (Переключение эк-
рана) можно выбрать в меню Display Options (Параметры экрана) для
того, чтобы при отладке Турбо отладчик переключался соответствую-
щим  образом между своим экраном и экраном программы. Допускается
выбор одного из следующих значений:

None (Отсутствует)      Отладчик не переключается между экранами.
                        Используйте данный параметр,  если вы от-
                        лаживаете программу,  которая не  выводит
                        информацию на экран.

Smart (Эффективное)     Переключение на экран пользователя проис-
                        ходит  только в случае вывода информации.
                        Турбо отладчик будет  переключать  экраны
                        каждый раз, когда вы выполняете шаг прог-
                        раммы или инструкцию (либо исходную стро-
                        ку), которая осуществляет запись в видео-
                        память или  чтение  из видеопамяти.  Этот
                        параметр используется по умолчанию.

Always (Постоянное)     Переключение в  экран пользователя проис-
                        ходит каждый раз, когда выполняется прог-
                        рамма.  Используйте данный параметр, если
                        параметр Smart  не  позволяет  "отловить"
                        все моменты вывода вашей программы данных
                        на экран.  При выборе этого параметра эк-
                        ран будет переключаться каждый раз, когда
                        вы выполняете  шаг  программы,  поскольку
                        экран  Турбо  отладчика на короткое время
                        будет заменяться экраном программы.

                Переключатель Integer Format
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Селективный переключатель Integer Format (Формат  целых  чи-
сел)  управляет  режимом вывода целый чисел.  С помощью TDINST вы
можете выбрать один из следующих вариантов:

Hex (Шестнадцатиричный) Целые числа  будут  выводиться на экран в
                        шестнадцатиричном формате.

Decimal (Десятичный)    Целые числа будут выводиться в десятичном
                        виде.

Both (Оба)              Целые числа  будут  выводится  на экран в
                        обоих форматах.

                 Параметр Beginning Display
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Переключатель Beginning Display (Начальный экран)  определя-
ет,  как будет выглядеть экран при запуске Турбо отладчика.  Этот
переключатель позволяет выбрать один из следующих вариантов:

Assembler (Ассемблер)     Запуск в режиме Ассемблера.  Ни одна из
                          ваших программ не выполняется, а в окне
                          CPU  выводится  первая инструкция прог-
                          раммы.

Source (Исходный модуль)  Запуск в  режиме исходного модуля.  Вы-
                          полняется код  инициализации  соответс-
                          твующего компилятора,  и вы  перемещае-
                          тесь  в  окно Module (Модуль) на начало
                          исходного модуля.

                 Переключатель Screen Lines
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Этот селективный  переключатель  позволяет задать,  будет ли
Турбо отладчик запускаться с режимом 25 строк на экране или 43/50
строк.

     Режим 43/50  строк доступен только при использовании адапте-
ров EGA и VGA.

                           Tab Size
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поле ввода Tab Size (Размер позиции табуляции)  меню Display
Options (Параметры экрана) программы TDINST позволяет задать чис-
ло позиций между табуляциями при выводе исходного текста. Вам бу-
дет  выведена  подсказка для ввода соответствующего значения (до-
пустимые  ответы  -  от  1  до  32  включительно).  По  умолчанию
используется значение 8.

                     Maximum Tiled Watch
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поле ввода Maximum Tiled  Watch  (Максимальный  размер  окна
просмотра) меню Display (Экран) программы TDINST позволяет задать
число строк,  до которого может расширяться окно  Watches  (Прос-
мотр) при выводе без перекрытия окон. Вам будет выведена подсказ-
ка для ввода соответствующего значения (допустимые ответы -  от 1
до 20 включительно).

                 Параметр Fast Screen Update
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Блок проверки Fast Screen Update (Быстрое обновление экрана)
меню  Display Options (Параметры экрана) программы TDINST опреде-
ляет режим обновления экрана.  Включите данный параметр,  если вы
хотите,  чтобы цветной дисплей обновлялся быстро.  Выключите этот
параметр, если при разрешении быстрого обновления на экране видны
помехи в виде "снега" (однако некоторые предпочитают все же быст-
рое обновление экрана даже при наличии помех).

               Параметр Permit 43/50-Line Mode
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Блок проверки  Permit  43/50-Line  Mode  (Разрешение  режима
43/50 строк) служит для разрешения соответствующего  режима. Если
вы  хотите использовать эту возможность,  включите его.  Запретив
ее, вы сохраните примерно 8К памяти, так как для режима с большим
экраном  в  отладчике требуется буфер окна большего объема.  Этот
параметр может оказаться полезным при отладке  больших  программ,
для  выполнения  которых  требуется много памяти.  При запрещении
указанного режима вы не сможете перейти в режим 43/50 строк, даже
если система может с ним работать.

                 Параметр Full Graphics Save
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Блок проверки Full Graphics Save (Полное сохранение графики)
управляет  сохранением  графики.  Ecли вы включите его,  то буфер
графического экрана будет сохраняться при переключении между  эк-
раном программы и экраном Турбо отладчика.  При запрещении данной
возможности вы сэкономите около 12К памяти. Это может быть полез-
но при отладке больших программ,  для которых требуется много па-
мяти.  В общем случае это приведет лишь к  небольшому  количеству
запорченных элементов экрана вашей программы, что обычно не меша-
ет при отладке.

             Переключатель User Screen Updating
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Селективный переключатель  User  Screen Updating (Обновление
экрана пользователя) можно выбрать из меню Display Options (Пара-
метры экрана), чтобы задать, как будет переключаться дисплей меж-
ду экраном вашей программы и экраном Турбо отладчика.  Этот пара-
метр позволяет выбрать один из следующих вариантов:

Other Display           Запускает Турбо  отладчик на другом дисп-
(Другой дисплей)        лее вашей системы. Если у вас имеется как
                        цветной,  так  и  монохромный  дисплейный
                        адаптер,  эта возможность  позволяет  вам
                        наблюдать  экран программы на одном дисп-
                        лее, а экран Турбо отладчика - на другом.

Flip Pages              Вывод Турбо  отладчика  помещается на от-
(Переключение           дельную страницу дисплея. Эта возможность
страниц)                будет  реализована  только  в том случае,
                        если ваш дисплейный  адаптер  имеет  нес-
                        колько страниц (как адаптеры CGA, EGA или
                        VGA).  Для монохромного дисплея эту  воз-
                        можность использовать нельзя.  Данный па-
                        раметр работает в большинстве возникающих
                        при  отладке ситуаций.  Обмен выполняется
                        быстро, и возможно нарушение работы толь-
                        ко тех программ,  которые используют нес-
                        колько дисплейных страниц и часто  перек-
                        лючаются между ними.

Swap (Обмен)            Используется один  дисплейный  адаптер  и
                        одна страница.  Переключение экрана поль-
                        зователя и Турбо отладчика осуществляется
                        программным путем.  Это  самый  медленный
                        метод переключения экрана, но он наиболее
                        надежен и не вносит  нарушений  в  работу
                        программы. Если вы отлаживаете программу,
                        которая использует  несколько  дисплейных
                        страниц, укажите этот параметр.

                 Поле ввода Log List Length
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Поле ввода  Log  List Length (Длина списка регистрации) меню
Display Options (Параметры экрана) программы TDINST позволяет за-
дать,  сколько  предыдущих  ответов  будет сохраняться для каждой
подсказки. Вам будет выведена подсказка для ввода соответствующе-
го значения (допустимые ответы - от 4 до 200 включительно).

                Поле ввода Floating Precision
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Используйте данное поле ввода для установки  точности (числа
цифр после десятичной точки) при просмотре в TDW данных с плаваю-
щей точкой.  Это число может иметь значения в диапазоне от  1  до
32.

                  Поле ввода Range Inspect
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Используйте данное поле ввода для установки  числа элементов
TDW,  выводимых обычно для указателя после того, как вы выбираете
в окне Inspector (Проверка) команду локального меню Range (Диапа-
зон).  По умолчанию это значение равно 5.  Это означает, что TDW,
если вы не укажете диапазон с  помощью  команды  локального  меню
Range,  выводит только первые 5 из указываемых элементов.  Макси-
мальное значение, которое вы может задавать, равно 4096.

            Установка параметров Турбо отладчика
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Для вывода меню Options (Параметры) программы TDINST выбери-
те команду основного меню Options (Параметры).

      ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДї
      і Directories...            і    Каталоги
      і Input & prompting...      і    Ввод и подсказки
      і Source debugging...       і    Отладка исходного кода
      і Miscellaneous...          і    Разное
      АДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ

                   Параметр Directories...
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     При выборе параметра Directories (Каталоги) выводится диало-
говое окно, в поле ввода которого вы можете ввести:

Editor program name   Данный параметр  программы TDINST позволяет
(Имя программы-       задать команду DOS, которая будет запускать
редактора)            ваш редактор.  Это позволит Турбо отладчику
                      запускать редактор,  с которым вы  привыкли
                      работать,  когда во время отладки нужно из-
                      менить что-либо в файле. Турбо отладчик бу-
                      дет добавлять к концу этой команды имя фай-
                      ла  который  вы хотите редактировать (через
                      пробел).

Source Directories    Выбор параметра Source Directories (Катало-
(Каталоги исход-      ги  исходных файлов) меню Options (Парамет-
ных файлов)           ры)  программы  TDINST  позволяет  изменять
                      список каталогов,  в которых Турбо отладчик
                      ищет исходные файлы.

Turbo Directory       Выбор параметра  Turbo  Directory  (Каталог
(Каталог Turbo)       Turbo)  меню  Options (Параметры) программы
                      TDINST позволяет задать каталог,  в котором
                      Турбо отладчик будет искать файл конфигура-
                      ции и справочный файл.

               Параметр Input and Prompting...
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Выбор параметра Input and prompting (Ввод и  подсказки) меню
Options (Параметры) программы TDINST позволяет вам управлять вво-
димой в Турбо отладчик информацией и  характером подсказок  Турбо
отладчика.  Таким  образов программы TDINST позволяет определить,
как вам будет выводиться подсказка для ввода информации и  как вы
будете отвечать на нее.

   ЙН[*]ННННННННННННННННUser Input and PromptingННННННННННННННН»
   є History list length                                       є
   є  10                           [X] Mouse enabled           є
   є                                                           є
   є Interrupt Key                                             є
   є  (*) Break                    [ ] Beep on error           є
   є  ( ) Escape                                               є
   є  ( ) Num Lock                 [ ] Keystroke recording     є
   є  ( ) Other                                                є
   є                               [X] Control key shortcuts   є
   є                                                           є
   є Set Key                       OK               Cancel     є
   є                             ±±±±±±             ±±±±±±     є
   є [ ] Full graphics save ( ) Swap                           є
   є                                                           є
   ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

     Рис. D.4 Диалоговое окно User Input and Prompting

     User input  and  prompting  - ввод пользователя и подсказки;
History list  length - длина списка регистрации;  Mouse enabled -
разрешение использования "мыши"; Interrupt key - клавиши прерыва-
ния;  Other - прочая; Beep on error - звуковой сигнал при ошибке;
Keystroke  recording  -  запись  нажатий  клавиш;   Control   key
shortcuts - сокращения с клавишей Ctrl;  OK - выбор; Cancel - от-
мена.

     Можно выбрать следующие варианты:

History List Length             Позволяет вам задать, сколько ра-
(Длина списка регистрации)      нее введенных строк будет  сохра-
                                няться для  каждой подсказки. Для
                                ввода значения   выводится   окно
                                ввода.

Interrupt key (Клавиша          Позволяет задать,  какая  клавиша
прерывания)                     должна  быть  нажата  с  клавишей
                                Сtrl  для  прерывания  выполнения
                                программы по умолчанию.

Set Key (Задание клавиши)       При выборе значения Other (Прочая)
                                выберите  переключатель  Set  Key
                                для назначения  клавиши  прерыва-
                                ния.  Вам выведется подсказка для
                                ввода клавиши.

Mouse Enabled (Разрешение       Этот параметр  позволяет  опреде-
работы с "мышью")               лить,  будет ли Турбо отладчик по
                                умолчанию поддерживать "мышь".

Beep on Error                   Запрещает или  разрешает звуковой
(Звуковой сигнал при ошибке)    сигнал.  При  разрешении  сигнала
                                при выводе  сообщений  об  ошибке
                                или  нажатии  недопустимых клавиш
                                будет раздаваться  звуковой  сиг-
                                нал.

Keystroke recording             Регистрация нажатий клавиш позво-
(Регистрация нажатий клавиш)    ляет будет ли  в  окне  Execution
                                History  (Протокол выполнения) по
                                умолчанию  выполняться  автомати-
                                ческая запись нажатий клавиш.

Control-key Shortcuts (Сокра-   Переключает между  разрешением  и
ращения для клавиши Ctrl)       запрещением использования  сокра-
                                шений с клавишей Ctrl.  Когда ис-
                                пользование   данных   сокращений
                                разрешено, вы можете вызывать лю-
                                бую команду локального меню,  на-
                                жав  клавишу  Ctrl  в сочетании с
                                первой буквой элемента меню.  Од-
                                нако  при  этом вы не сможете ис-
                                пользовать такие управляющие кла-
                                виши как команды перемещения кур-
                                сора в стиле  редактора WordStar.

             Диалоговое окно Source Debugging...
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

            ЙН[*]НННННННННSource DebuggingНННННННННННН»
            є                                         є
            є Language                                є
            є   (*) Source Module                     є
            є   ( ) C                                 є
            є   ( ) Pascal                            є
            є   ( ) Assembler                         є
            є                                         є
            є [ ] Ignore symbol case                  є
            є [ ] OWL window message                  є
            є                                         є
            є    OK                    Cancel         є
            є  ±±±±±±                  ±±±±±±         є
            є                                         є
            ИНННННННННННННННННННННННННННННННННННННННННј

     Рис. D.5 Диалоговое окно Source Debugging

     Диалоговое окно Source Debugging (Отладка на уровне исходно-
го кода) программы TDINST позволяет вам задать,  какой язык Турбо
отладчик будет использовать для вычисления выражений.  Можно выб-
рать одну из следующих возможностей:

Source Module           Выбор языка будет осуществляться на осно-
(Исходный модуль)       ве языка текущего исходного модуля.

C (Язык Си)             Будут всегда   использоваться   выражения
                        языка  Си,  независимо от того,  на каком
                        языке написан текущий модуль.

Pascal (Паскаль)        Будут всегда   использоваться   выражения
                        Паскаля,  независимо  от  того,  на каком
                        языке написан текущий модуль.

Assembler (Ассемблер)   Будут всегда использоваться выражения Ас-
                        семблера,  независимо  от того,  на каком
                        языке написан текущий модуль.

                 Параметр Ignore Symbol Case
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Выбор параметра Ignore Symbol Case  (Игнорирование  регистра
идентификаторов)  диалогового  окна  Source  Debugging  программы
TDINST позволяет управлять различной интерпретацией букв верхнего
и нижнего регистра.

                Параметр OWL window messages
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Если этот параметр не установлен (по умолчанию),  в програм-
мах, использующих ObjectWindows отсутствует специальная поддержка
для отладки с помощью сообщений Windows, a TDW не будет распозна-
вать  оконные  объекты  вашей  программы,  как процедуры Windows.
Вместо этого для установки точек останова по  сообщениям  Windows
требуется  использовать  описатели окна (а чтобы найти указатель,
нужно достаточно хорошо разбираться в ObjectWindows.

     Если этот блок проверки включен,  TDW обеспечивает для уста-
новки точек  прерывания по сообщениям в программах,  использующих
ObjectWindows, специальную поддержку. Эта поддержка позволяет вам
для установки  точек останова по сообщениям использовать имя объ-
екта окна вашей программы. Однако отладка с установленными точка-
ми останова  по  сообщениям  Windows будет происходить медленнее,
чем когда этот параметр выключен.

          Диалоговое окно Miscellaneous Options...
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

     Диалоговое окно Miscellaneous Options (Прочие параметры) со-
держит параметры,  управляющие  прерываниями  NMI  (немаскируемые
прерывания),  памятью EMS, переключением идентификатора процесса,
размером области  командного  процессора  DOS,  размером  таблицы
идентификаторов и удаленной отладкой.

   ЙН[*]ННННННННННННННННUser Input and PromptingННННННННННННННН»
   є                                                           є
   є [ ] NMI intercept                   Remote debugging      є
   є [X] Use expanded memory         (*) COM1    ( ) COM2      є
   є [X] Change process ID                                     є
   є [ ] Full trace history          Link speed                є
   є [ ] International support       ( ) 9600 baud             є
   є                                 (*) 19200 baud            є
   є DOS Shell swap size (Kb)        ( ) 38400 baud            є
   є  128                            ( ) 115000 baud           є
   є Spare symbol memory (Kb)                                  є
   є  0                              Network local name        є
   є                                            є
   є Remote type                                               є
   є  (*) None                       Network remote name       є
   є  ( ) Serial                                є
   є  ( ) Network                                              є
   є                                    OK        Cancel       є
   є                                  ±±±±±±      ±±±±±±       є
   ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј

      Рис. D.7 Диалоговое окно Miscellaneous options.

      Miscelleneous options - прочие параметры:  NMI interсept  -
перехват немаскируемого прерывания; Use expanded memory - исполь-
зование расширенной памяти; Change process ID - смена идентифика-
тора процесса;  Remote debugging - удаленная отладка; Remote link
port - порт удаленной связи;  DOS Shell swap size - размер перек-
лючения в командный процессор DOS; Link speed - скорость коммуни-
каций;  Spare symbol memory - память для таблиц  идентификаторов;
Network local name - локальное имя в сети; not avaliable - недос-
тупно;  Network remote name - удаленное имя в сети; Remote type -
тип  удаленной  связи;  None  -  нет;  Serial - последовательная;
Network - сетевая.



Яндекс цитирования