Четвертый Borland C++ и его окружение

         

Написание переносимого кода Windows


В данном разделе обсуждаются конструкции (введенные в

Windows 3.1), обеспечивающие переносимость кода Windows. Существующий 16-разрядный код Windows можно переносить с минимальными

изменениями в Win32 и Windows NT. Большинство изменений предусматривают подстановку вместо старых новых макрокоманд и типов и

замену специфических 16-разрядных вызовов API аналогичными API

Win32. После внесения этих изменений ваш программный код сможет

компилироваться и выполняться в 16-разрядной и 32-разрядной среде

Windows.

Чтобы облегчить создание переносимого кода, предусмотрена

переменная среду этапа компиляции STRICT. Windows 3.1 поддерживает определение STRICT в windows.h. Например, если не определена

переменная STRICT, то передача HWND функции, требующей HDC, не

приведет к выводу компилятором предупреждающего сообщения. Если

вы определите STRICT, то получите ошибку компиляции.

Использование STRICT позволяет:

выполнять строгую проверку типов;

корректировать и согласовывать описания типа параметра и

возвращаемого значения;

создавать прототипы определений типов для функций обратного вызова (оконные, диалоговые и специальные процедуры);

согласовывать с ANSI описания структур COMM, DCB и

COMSTAT.

STRICT обладает обратной совместимостью с Windows 3.0, то

есть ее можно использовать для создания приложений, работающих в



Windows 3.0. Определение STRICT поможет вам находить и корректировать несовместимость типов при переносе программ в 32-разрядную среду и поможет обеспечить переносимость между 16- и 32-разрядной Windows.

Чтобы вы могли изменить свою программу в соответствии со

STRICT, предусмотрены новые типы, константы и макрокоманды

Типы и константы Описание

CALLBACKИспользуется вместо FAR PASCAL в подпрограммах обратного вызова (например, оконных и диалоговых процедурах).
LPARAM Описывает все 32-разрядные полиморфические параметры.
LPCSTR То же, что LPSTR, но используется для доступ-

ных только по чтению строковых указателей.

LRESULT Описывает все 32-разрядные возвращаемые значения.
UINT Переносимый беззнаковый целочисленный тип,

размер которого определяется целевой средой.

(В Windows 3.1 представляет 16-битовое значение, а в Win32 - 32-битовое.)

WINAPI Используется вместо FAR PASCAL для описаний API. Если вы пишете DLL с экспортируемыми точками входа API, то можете использовать ее для описаний API.
WPARAM Описывает 16-битовые полиморфические параметры.
<


Макрокоманда Описание






RELDOFFSET(тип, поле) Вычисляет смещение поля в структуре. "Тип" - это тип структуры, а "поле" - это имя поля.
WAKELP(селект,смещ) Воспринимая селектор и смещение, создает FAR VOID*.
WAKELPARAM(мин,макс) Из двух 16-битовых значений создает LPARAM.
WAKELRESULT(мин,макс) Из двух 16-битовых значений создает LRESULT.
OFFSETOF(указ) Выделяет из дальнего указателя смещение и возвращает UINT.
SELECTOROF(указ) Выделяет из дальнего указателя селектор и возвращает UINT.
Описатели Значение












HACCEL Описатель таблицы акселератора.
HDRVR Описатель драйвера (Windows 3.1).
HDWP Описатель DeferWindowPost().
HFILE Описатель файла.
HGDIOBJ Общий описатель объекта GDI.
HGLOBAL Глобальный описатель.
HINSTANCE Описатель экземпляра.
HLOCAL Локальный описатель.
HMETAFILE Описатель метафайла.
HMODULE Описатель модуля.
HPSRC Описатель ресурса.
HTASK Описатель задачи.
Чтобы сделать ваше приложение согласованным со STRICT, нужно:

Определить, какой программный код вы хотите согласовать

со STRICT.

Включить наивысший уровень вывода ошибок/предупреждений.

В IDE используйте команду

Options Compiler Messages Display All. В BCC32 укажите

параметр -w.

Перед включением windows.h и компиляцией определить

STRICT с помощью #define или использовать в командной

строке параметр -DSTRICT.

Перечислим некоторые рекомендации, которые могут оказаться

полезными при преобразовании вашего программного кода в соответствии со STRICT:

Измените HANDLE на соответствующий тип описателя, например, HMODULE, HINSTANCE и др.

Измените WORD на UINT (за исключением тех мест, где вы

хотите получить 16-битовое значение на 32-разрядной платформе).

Измените WORD на WPARAM.

Измените LONG на LPARAM или LRESULT.

Измените FARPROC на WNDPROC, DLGPROC или HOOKPROC.

В 16-разрядной Windows всегда описывайте указатели функций

с помощью подходящего типа функции, а не с помощью

FARPROC. При использовании MakeProcInstance,

FreeProcInstance и других функций, воспринимающих или



возвращающих FARPROC, вам нужно приводить типы указателей

функции, например:

BOOL CALLBACK DlgProc(HWND hwnd, UINT msg,

WPARAM wParam,

LPARAM lParam);

DLGPROC lpfnDlg;

lpfnDlg=(DLGPROC)MakeProcInstance(DlgProc, hinst);

...

FreeProcInstance((FARPROC)lpfnDlg);

Особое внимание обратите на HMODULE и HINSTANCE. Функции

ядра, осуществляющие управление модулями, обычно используют HINSTANCE, но некоторые API возвращают или воспринимают

только HMODULE.

Если вы копируете какие-то описания функций API из

WINDOWS.H, они могут быть изменены, и ваши описания могут

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

Приведите тип результата LocalLock и GlobalLock к соответствующему виду указателя данных. Параметры этих и других функций управления памятью должны при необходимости

приводиться к LOCALHANDLE или GLOBALHADLE.

Приведите результат GetWindowWord и GetWindowLong и параметры к SetWindowWord и SetWindowsLong.

При приведении типа SendMessage, DefWinmdowProc и

SendDlgItemMsg или любых других функций, которые возвращают LRESULT или LONG к какому-либо описателю вы должны сначала привести результат к UINT:

HBRUSH hbr;

hbr = (HBRUSH)(UINR)

SendMessage(hwnd WM_CTLCOLOR, ..., ...);

Параметр CreateWindow и CreateWindowEx функции hmenu иногда используются для передачи целочисленного управляющего

идентификатора. В этом случае вы должны привести тип к

HMENU:

HWND hwmd;

int id;

hwnd = CreateWindow("Button", "Ok", BS_PUSBUTTON,

x, y, cx, cy, hwndParent,

(HMENU)id, // здесь требуется приведение типа

hinst, NULL);

Полиморфические типы данных (WPARAM, LPARAM, LRESULT, void

FAR*) следует возможно скорее присваивать переменным. Избегайте использовать их в своих программах, когда тип значения известен. Это минимизирует число потенциально небезопасных и непереносимых в 32-разрядный режим преобразований типов. Макрокоманды API и механизмы обработки сообщений, предусмотренные в windowsx.h, будут выполнять практически всю упаковку и распаковку этих типов данных способом, обеспечивающим переносимость в 32-разрядный режим.

Ознакомьтесь с наиболее общими предупреждениями и ошибками

компилятора, которые вы можете обнаружить при переходе к

STRICT.


Наш декомпрессор в стиле фильтра


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

так:

int decompressor_next(decompressor* dc)

{

if (dc->rcnt && dc->rcnt-- > 0) /* Контроль декомпрессии */

return dc->c; /* Возврат повторного символа */

if (!dc->srclen || dc->srclen-- <= 0) /* Пропуск ... */

return -1;

dc->c = *(dc->p)++; /* Обработка следующего символа буфера */

if (dc->c == 0xff) {

dc->rcnt = (*(dc->p)++)-1; /* Сброс первого символа в записи */

dc->c = *(dc->p)++; /* Здесь повторить символ */

dc->srclen -= 2;

}

return dc->c;

}



Наследование


Наследование - это способность брать существующий - базовый

класс и порождать из него новый класс - потомок, с наследованием всех

его атрибутов и поведения. Это пожалуй самая впечатляющая возможность

объектно-ориентированного программирования и, возможно, единственное

коренное отличие С++ от Си.

Рассмотрим отвлеченный пример из реальной жизни - классификационную схему живых организмов. По этой схеме растительные и живые

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

очередь, делится на классы, отряды, семейства и далее. Группы более

низкого уровня наследуют характеристики групп более высоких уровней.

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

Так как псовые входят в отряд хищных, это утверждение говорит еще о

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

покров и регулируемую температуру тела. Наконец, так как млекопитающие являются позвоночными, мы узнаем и то, что у волков есть позвоночник.

Волк -> Псовые -> Хищники -> Млекопитающие -> Позвоночные

Подобные схемы наследования можно проследить в классификации

языков программирования, классификации типов компьютеров и других.

Рассмотрим существующие в объектно-ориентированных языках иерархии

порождаемых объектов.



и Windows NT. ObjectWindows позволяет


ObjectWindows 2.0 - это прикладная среда Borland С++ для

Windows 3.1, Win32S и Windows NT. ObjectWindows позволяет быстро

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

Легкую переносимость между 16- и 32-разрядными платформами.

Автоматизированную обработку сообщений.

Надежную обработку особых ситуаций и ошибок.

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

Инкапсулирует объекты GDI Windows.

Имеет классы Doc/View для простой абстракции и вывода данных.

Содержит классы для работы с принтером и предварительного

просмотра печатаемой информации на экране.

Поддерживает управляющие элементы VisualBasic.

Имеет средства проверки допустимости ввода.


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


Вы можете настроить конфигурацию IDE для автоматического вы-

полнения отдельных задач или обработки событий. Диалоговое окно

Options Enviroment позволяет вам настроить конфигурацию редактора, средства просмотра, отладчика, подсистемы управления проектами и других элементов IDE. Заданные параметры сохраняются в файле

BCCONFIG.BCW. Список параметров в окне можно сжимать и расширять

с помощью + и -.

Команда Options Enviroment позволяет также настроить вид

оперативной полосы окон Editor, Browser, Debugger, Project, Message, Desktop и ClassExpert. При выборе одного из этих окон выводится оперативная полоса SpeedBar с комплектом инструментальных

средств. Вы можете ее настроить. Чтобы включить в нее или удалить

командные кнопки, сделайте следующее:

Выберите в основном меню команду Options Enviroment.

Выберите слева тему SpeedBar. В правой части диалогового

окна выводятся общие параметры всех оперативных полос, с

помощью которых ее можно настроить.

Выберите под SpeedBar Customize. В параметрах справа выводится информация о полосах SpeedBar.

Выберите тип оперативной полосы, которую вы хотите изменить

Editor, Browser, Debugger, Project, Message, Desktop или

ClassExpert). В столбце Avaliable Buttons выводятся все

доступные (доступные) командные кнопки, а в столбце Active

Buttons - кнопки выбранной оперативной полосы.

Чтобы добавить командную кнопку, дважды щелкните на ней

"мышью" в столбце Avaliable Buttons, а чтобы удалить, выберите кнопку в Active Buttons и щелкните "мышью" на указывающей влево стрелке.

Для переупорядочения позиций командных кнопок в SpeedBar

используйте стрелки вверх и вниз. Выбранная в Active Buttons кнопка перемещается вверх или вниз по списку.

Кнопка Copy Layout позволяет сделать все оперативные полосы

идентичными.



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


WinSpector можно настроить таким образом, чтобы она лучше

соответствовала вашим потребностям. Это позволяет управлять выводом информации в файл WINSPCTRL.LOG.

Параметры WinSpector можно устанавливать в диалоговом окне

Preferences или с помощью ввода команд непосредственно в файл

WINSPCTR.INI.

Параметр Directory в диалоговом окне Preferences позволяет

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

Для задания каталога сделайте следующее:

Откройте диалоговое окно Preferences.

Введите в поле ввода Directory имя каталога.

Выберите командную кнопку OK.


либо добавьте запись LogDir=[каталог] в файл WINSPCTR.INI.

Параметр Viewer диалогового окна Preferences позволяет задать, какое программное средство нужно использовать для просмотра

файла регистрации. Если вы не задаете каталог, то по умолчанию

используется Windows Notepad.

Если исключительная ситуация возникает в процессе сеансе с

текущим окном Windows, чтобы увидеть файл регистрации, выберите

View Log (Просмотр файла регистрации) диалогового окна Latest UAE

или диалоговое окно Preferences. Команда View Log запускает выбранную программу просмотра и передает файл WINSPCTR.LOG в качестве аргумента командной строки.

Чтобы просмотреть предыдущий файл регистрации, выберите в

системном меню WinSpector команду View Log file.

Чтобы задать средство просмотра, сделайте следующее:

Откройте диалоговое окно Preferences.

Введите средство просмотра в текстовом диалоговом окне Viewer.

Выберите командную кнопку OK.


либо добавьте LogViewer=[имя_файла_программы_просмотра] к файлу

WINSPCTR.INI.

Параметры Append New Reports и Overwrite Previous Reports в

диалоговом окне Preferences позволяет вам либо добавить отчеты к

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

Если вы выбираете перезапись предыдущего файла регистрации,

то при первом возникновении исключительной ситуации предыдущий




файл регистрации затирается. Последующие исключительные ситуации,

возникающие в процессе текущего сеанса работы с Windows, будут

добавлять информацию к этому файлу.

Чтобы добавлять отчеты к предыдущему файлу регистрации, сделайте следующее:

Откройте диалоговое окно Preferences.

Установите Log File в Append New Reports.

Выберите командную кнопку OK.

либо нужно добавить Add CreateNewLog=0 в файл WINSPCTR.INI.

Чтобы затирать предыдущие файлы регистрации, сделайте следующее:

Откройте диалоговое окно Preferences.

Установите Log File в Overwrite Previous Reports.

Выберите командную кнопку OK.

либо добавьте Add CreateNewLog=1 в файл WINSPCTR.INI.

Параметр System Information в диалоговом окне Preferences

позволят вам добавить в файл регистрации список задач Task List,

список модулей Module List, и информацию о динамически распределяемой области памяти пользователя (USER) и GDI. По умолчанию в

отчет включается системная информация.

Чтобы включить системную информацию в файл регистрации, сделайте следующее:

Откройте диалоговое окно Preferences

В Report Information выберите System Info.

Выберите командную кнопку OK.

либо нужно добавить Add ShowSystemInfo=1 в файл WINSPCTR.INI.

Чтобы системная информация не включалась в файл регистрации,

сделайте следующее:

Откройте диалоговое окно Preferences

В Report Information отмените System Info.

Выберите командную кнопку OK.

либо нужно добавить Add ShowSystemInfo=0 в файл WINSPCTR.INI.

Параметр AUX Summary в диалоговом окне Preferences указывает

WinSpector, что на устройство AUX нужно выводить сокращенную форму отчета. Чтобы использовать данный параметр, нужно подключить к

AUX терминал или драйвер устройства, который перенаправляет AUX

на второй монитор. По умолчанию информация на AUX не выводится.

Для передачи итогового отчета на устройство AUX сделайте

следующее:

Откройте диалоговое окно Preferences.

В Report Information, выберите Summary To AUX.

Выберите командную кнопку OK.

либо добавьте LogToStdAux=1 в файл WINSPCTR.INI.



Чтобы итоговый отчет не передавался на устройство AUX сделайте следующее:

Откройте диалоговое окно Preferences.

Under Report Information, отмените Summary To AUX.

Choose OK.

либо добавьте LogToStdAux=0 в файл WINSPCTR.INI.

Параметр Stack Frame Data в диалоговом окне Preferences позволяет вам выполнить подробную трассировку стека в файл регистрации. Для кадра стека не превышающего 256 байт выполняется шестнадцатиричный дамп, начиная с SS:BP для кадра стека. Если между двумя последовательными кадрами стека больше 256 байт, то показ

памяти для этого кадра опускается. Эти данные можно использовать

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

Обычно для выявления значений параметров существенно проще

использовать утилиту DFA. Однако в тех случаях, когда вам недоступна информация отладчика, может оказаться полезной подробная

трассировка стека. Чтобы добавить данные трассировки стека в файл

регистрации, сделайте следующее:

Откройте диалоговое окно Preferences.

В Report Information, выберите Stack Frame Data.

Выберите командную кнопку OK.

либо добавьте ShowStackInfo=1 в файл WINSPCTR.INI.

Чтобы не включать данные кадра стека в файл регистрации,

сделайте следующее:

Откройте диалоговое окно Preferences.

В Report Information, отмените Stack Frame Data.

Выберите командную кнопку OK.

либо добавьте ShowStackInfo=0 в файл WINSPCTR.INI.

Параметр PostMortem Dump в диалоговом окне Preferences генерирует файл WINSPCTR.BIN.

Утилита DFA воспринимает файл WINSPCTR.BIN и информацию Турбо отладчика (файлы .TDS) и транслирует непосредственные двоичные

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

с именами функций и номерами строк, а также локальными и глобальными переменными.

Генерация файла WINSPCTR.BIN:

Откройте диалоговое окно Preferences.

В Report Information выберите PostMortem Dump.

Выберите командную кнопку OK.




либо добавьте PostMortemDump=1 в файл WINSPCTR.INI.

Чтобы не генерировать файл WINSPCTR.BIN, сделайте следующее:

Откройте диалоговое окно Preferences.

В Report Information, отмените PostMortem Dump

Выберите командную кнопку OK.

либо добавьте PostMortemDump=0 в файл WINSPCTR.INI.

Параметр User Comments в диалоговом окне Preferences позволяет вам ввести информацию о том, что происходило во время возникновения исключительной ситуации. Диалоговое окно выводится

немедленно после записи файла регистрации, и в это время можно

ввести комментарии о том, что произошло. Ваши комментарии будут

добавляться к файлу регистрации.

Чтобы добавить комментарии пользователя в файл регистрации,

сделайте следующее:

Откройте диалоговое окно Preferences.

В Report Information, выберите User Comments.

Выберите командную кнопку OK.

либо добавьте ShowUserInfo=1 в файл WINSPCTR.INI.

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

Откройте диалоговое окно Preferences.

В Report Information, отмените User Comments.

Выберите командную кнопку OK.

либо добавьте ShowUserInfo=0 в файл WINSPCTR.INI.


Настройка Turbo Debugger


Вы можете конфигурировать параметры вывода Turbo Debugger и

программные установки с помощью файлов конфигурации и меню Option

отладчика. Параметры, установленные в файлах конфигурации, начинают действовать после загрузке Turbo Debugger. Чтобы изменить

параметры после загрузки, используйте команды в меню Options.



Назначение интерфейсных объектов


Одна из наибольших трудностей программирования в Windows

состоит в том, что можно запутаться в управляющих элементах.

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

операции часто различаются. ObjectWindows значительно уменьшает

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

Интерфейсные объекты предусматривают функции-элементы для

создания, инициализации, уничтожения и управления соответствующим

интерфейсным элементом. Многие детали программирования в Windows

берут на себя функции-элементы.

Интерфейсные объекты инкапсулируют также данные, необходимые

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



Нехватка памяти при выполнении


Borland С++ при компиляции не генерирует на диске никаких

промежуточных структур данных (записывая на диск только файлы

.OBJ). Вместо этого для хранения промежуточных структур данных

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

размер функций или разбейте файл с крупными функциями на несколько частей.



Неклиентные сообщения


WM_NCACTIVATE WM_NCMBUTTONDOWN
WM_NCCREATE WM_NCMBUTTONUP
WM_NCCALCSIZE WM_NCMOUSEMOVE
WM_NCDESTROY WM_NCMMOUSEMOVE
WM_NCHITTEST WM_NCPAINT
WM_NCLBUTTONDBLCLK WM_NCRBUTTONDBLCLK
WM_NCLBUTTONDOWN WM_NCRBUTTONDOWN
WM_NCMBUTTONDBLCLK WM_NCRBUTTONUP



Несколько явных правил для одного целевого файла


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

файлы объектных модулей .OBJ могут строиться по-разному (некоторые с помощью компилятора BCC, а другие, например, с помощью

TASM).

Здесь используется тот же формат, что и для обычных явных

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

двоеточие сообщает утилите MAKE, что для данного целевого файла

ожидаются дополнительные явные правила.

В следующем примере MYLIB.LIB состоит из четырех объектных

модулей, два из которых являются модулями С++. Первое явное правило компилирует модули С++ и обновляет библиотеку. Второе явное

правило ассемблирует файлы ASM и также обновляет библиотеку.

mylib.lib:: f1.cpp f2.cpp

bcc -c f1.cpp f2.cpp

tlib mylib -+f1.obj -+f2.obj

mylib.lib:: f3.asm f4.asm

tasm /mx f3.asm f4.asm

tlib mylib -+f3.obj -+f4.obj



Несколько слов о проектировании иерархии классов


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

сути, абстрактную основу - шаблоны для создания объектов. Из шаблона,

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

вы напишете хотя бы одну строку программы на С++, необходимо хорошо

продумать необходимые вам классы и уровни их использования.

Не существует "идеальной" иерархии классов для каждой конкретной

программы. По мере продвижения разработки может оказаться, что вам

потребуется ввести новые классы, которые коренным образом изменят всю

иерархию классов. Каждая иерархия классов представляет собой сплав

экспериментальных исследований и интуиции, основанной на практике.

Так, потребовались сотни лет для создания классификации животных, и

тем не менее, вокруг нее, до сих пор, ведутся горячие споры и дела-

ются попытки ее изменения.

Умелое использование наследования позволяет с небольшими усилиями модифицировать огромные по объему программы. К тому же необходимо

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

Borland С++. Так что не следует "высасывать их из пальцев".



Несколько слов об идее, заложенной в книге.


Поскольку каждая новая версия Borland C++ включает самую

подробную техническую информацию, трудно написать то, чего в ней

нет. Однако, многим программистам вместо чтения толстых толмутов,

для начального программирования необходима информация, изложенная

в кратком виде, доступная по цене и удобная для чтения дома и на

работе. С другой стороны, возникает потребность и в справочной

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

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

понимания концепции языка С++, а последующие дадут более конкретизированное представление о версии языка Borland C++ 4.0.

В 1 главе книги "Азы C++" Вы бегло ознакомитесь с основными

возможностями языка С++.

Во 2 главе "Наставление пользователю по Borland С++ 4.0" вы

узнаете о порядке инсталяции и работе с интегрированными средствами компилятора Borland.

Глава 3 "Справочная информация по программированию" говорит сама за себя.

"Справочник по программированию для DOS" вы найдете в главе 4.

В главе 5 Вы вкратце ознакомитесь с отладчиком Borland C++

Turbo Debugger 4.0.

Глава 6 включает справочную информацию о функциях в таком

виде:

abort Экстренно завершает программу

DOS UNIX Win16 #include <stdlib.h>

OS/2 Win32 void abort(void);

ANSI C++ ANSI C

и т.д.


Глава 7 расскажет о Objects Windows 2.0.

Жуть сколько много информации, но оригинальная документация

содержит в 3 раза больше. Так что настраивайтесь посерьезней.

Надеюсь книга окажется полезной и нужной Вам, уважаемый Читатель!

М.Вахтеров

Содержание | Вперед



Ниже описан главный фрагмент нашей программы декомпрессии


char buff[] = {'a',0xff,3,'b','c'};

main()

{

int c;

decompressor dc;

decompressor_init(&dc, buff, sizeof(buff));

while ((c = decompressor_next(&dc)) != -1) putchar(c);

}

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

один символ за раз, может перенаправить его по множеству путей. Так,

он мог бы был выведен непосредственно на экран, как мы это делаем

здесь, передан подпрограмме поиска строки или анализатору ... в соответствии с концепцией.



- O -


object module имя_файла is invalid

Сообщение об ошибке утилиты TLIB

(недопустимый объектный модуль)

Библиотекарь не может распознать запись заголовка объектного

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

Objects of type тип cannot be initialized with {}

Сообщение об ошибке этапа компиляции:

(объект указанного типа не должен инициализироваться с помощью {})

Обычные структуры Си могут инициализироваться набором значений, заключенных в фигурные скобки. Классы С++ могут инициализироваться с помощью конструкторов (если класс имеет конструкторы,

локальных элементов, функций или базовых классов, которые являются виртуальными.

Only <<KEEP or <<NOKEEP

Сообщение об ошибке утилиты MAKE

(только <<KEEP или <<NOKEEP)

При закрытии временного встроенного файла вы задали что-то

отличное от KEEP или NOKEEP.

Only member functions may be 'const' or 'volatile'

Сообщение об ошибке этапа компиляции

(иметь тип 'const' или 'volatile' могут только функции-элементы)

Как 'const' или 'volatile' описан какой-либо другой объект,

отличный от функции-элемента.

Only one of a set of overloaded functions can be "C"

Сообщение об ошибке этапа компиляции

(только один из наборов переопределенных функций может быть

описана как "C")

Функции С++ по умолчанию являются переопределяемыми, и компилятор присваивает каждой из них новое имя. Если вы хотите переопределить присваивание компилятором нового имени, объявив функцию "C", то можете сделать это только для одного из набора функций с тем же именем (в противном случае компоновщик обнаружит более одной глобальной функции с тем же именем).

Operand of delete must be no-const pointer

Сообщение об ошибке этапа компиляции

(операндом удаления должен быть указатель, отличный от константы)

С помощью операции delete не допускается использовать указатель-константу.

Operator [] missing ]

Сообщение об ошибке этапа компиляции

(в operator[] отсутствует ])




В С++ operator[] была объявлена как operator[. Вы должны добавить недостающую квадратную скобку или еще как-либо исправить

объявление.

operator -> must return a pointer or a class

Сообщение об ошибке этапа компиляции

(operator -> должна возвращать указатель или класс)

Функция С++ операция operator-> должна быть объявлена как

возвращающая класс или указатель на класс (или структуру либо

объединение). В любом случае это должно быть нечто такое, к чему

применима операция ->.

Operator delete must return void

Сообщение об ошибке этапа компиляции

(Операция delete должна возвращать void)

Переопределенная операция С++ operator delete была объявлена

иначе.

Operator delete[] must return void

Сообщение об ошибке этапа компиляции

(Операция delete должна возвращать void)

Переопределенная операция С++ operator delete была объявлена

иначе. Опишите delete с одним параметром void*, а другим - типа

size_t.

Operator must be declared as function

Сообщение об ошибке этапа компиляции

(операция должна описываться как функция)

Переопределяемая операция была описана с типом, отличным от

типа функции.

Operator new[] must have an initial parameter of type size_t

Сообщение об ошибке этапа компиляции

(операция new[] должна иметь параметр инициализации типа size_t)

Операция new может объявляться с произвольным числом параметров, но обязательно должна иметь хотя бы один параметр, в котором будет находиться размер распределяемой памяти.

Operator new must return an object of type void*

Сообщение об ошибке этапа компиляции

(операция new должна возвращать объект типа void*)

Переопределенная операция С++ operator new была объявлена

иначе.

Operator new[] must return an object of type void*

Сообщение об ошибке этапа компиляции

(операция new[] должна возвращать объект типа void*)

Переопределенная операция С++ operator new была объявлена

иначе.

Out of memory

Фатальная ошибка этапа компиляции

(недостаточно памяти)

Исчерпана общая рабочая память. Повторите компиляцию этого



файла на машине с большей доступной памятью. Если у вас и так

имеется 640К, следует упростить исходный файл.

Out of memory

Сообщение об ошибке утилиты TLIB

(недостаточно памяти)

По каким-то причинам утилита TLIB или Borland C++ исчерпали

при построении библиотеки доступную память. Во всех конкретных

случаях выводятся также детальное сообщение, а "Out of memory" -

это общая ситуация нехватки памяти в разных ситуациях. При работе

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

Если данное сообщение возникает, когда слишком большой становится таблицы идентификаторов, вы должны освободить память. Для

командной строки это предполагает удаление резидентных программ

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

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

закройте одну или более прикладных программ.

Out of memory

Сообщение об ошибке утилиты TLINK

(недостаточно памяти)

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

ситуациях, когда утилите TLINK не хватает памяти. Обычно это означает, что в компонуемых объектных файлах определено слишком

много модулей, внешних идентификаторов, групп или сегментов. Вы

можете попробовать уменьшить объем виртуальных дисков и/или активных дисковых буферов. При работе под Windows, чтобы освободить

память, закройте одну или более прикладных программ.

out of memory creating extended dictionary

Сообщение об ошибке утилиты TLIB

(не хватает памяти при создании расширенного словаря)

Библиотекарь исчерпал память при создании расширенного словаря библиотеки. Библиотека будет создана, но не будет иметь расширенного словаря.

out of memory reading LE/LIDATA record from object module

Сообщение об ошибке утилиты TLIB

(не хватает памяти при чтении записи LE/LIDATA из объектного

файла)

Библиотекарь пытается прочитать запись данных из объектного



модуля, но не может получить достаточно большой блок памяти. Если

добавляемый блок содержит большой сегмент или сегменты данных, то

возможно добавление этого модуля перед другими модулями позволит

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

добавляемых далее.

Out of space allocating per module debug struct

Сообщение об ошибке утилиты TLIB

(нет памяти при выделении структуры для модулей)

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

Output device is full

Сообщение об ошибке утилиты TLIB

(устройство вывода переполнено)

Устройство вывода переполнено (обычно нет места на диске).

Overlays generated and overlay manager included

Предупреждение утилиты TLINK

(сгенерированы оверлеи и включен оверлейный менеджер)

Это предупреждение выводится, если оверлеи создаются, но

идентификатор __OVRTRAP__ не определен ни в одном из объектных

модулей или компонуемых библиотек. Этот идентификатор определяется стандартной оверлейной библиотекой OVERLAY.LIB.

Overlays only supported in medium, large and huge memory models

Сообщение об ошибке этапа компиляции

(оверлеи допустимы только для моделей памяти medium, large и

huge)

Оверлеи допустимы только в программах с моделями памяти medium, large и huge).

Overloadable operator expected

Сообщение об ошибке этапа компиляции

(ожидается переопределяемая операция)

Почти все операции С++ могут быть переопределены. Единственными исключениями являются операции выбора поля (.), точка со

звездочкой (.*), двойное двоеточие (::) и условное выражение

(?:). Операции препроцессора # и ## не являются операциями языка

С или С++ и потому переопределяться не могут. Прочие знаки пунктуации, не входящие в число операций, например, точка с запятой,

разумеется, также не могут быть переопределены.



Overloaded имя_функции ambiguous in this context

Сообщение об ошибке этапа компиляции

(имя переопределяемой функции в данном контексте неоднозначно)

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

присваивание переменной или параметра соответствующего типа. В

данном случае переопределяемое имя функции используется в каком-то другом контексте.

Overloaded prefix 'operator операция' used as a postfix operator

Предупреждение этапа компиляции

(переопределенный префикс 'operator операция' используется

как постфиксная операция)

В последней спецификации С++ теперь можно переопределить

префиксную и постфиксную версию операций ++ и --. Чтобы можно было компилировать старый код, когда переопределенной является

только префиксная операция, но она используется в постфиксном

контексте, Borland C++ использует префиксную операцию и выводит

данное предупреждение.

Назад | Содержание | Вперед


Объект TWindow


Все интерфейсные объекты ObjectWindows являются производными

от TWindow. Этот класс определяет базовое поведение всех окон,

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

классы Windows.



Объектные элементы данных и функции


Эти элементы данных и функции используются для управления

контекстом устройства самого объекта. Они являются защищенными

(protected) и могут использоваться только в производных от TDC

классах.

Элемент данных Описание

ShouldDelete Указывает, должен ли объект удалять свой

описатель контекста устройства при вызове деструктора.

Handle Содержит фактический описатель контекста

устройства.

OrgBrush, OrgPen, OrgFont, OrgPalette Описатели исходных объектов при создании контекста устройства. В 32-разрядных приложениях присутствует также OrgTextBrush.
CheckValid Генерирует исключительную ситуацию при

недопустимости контекста устройства.

Init Устанавливает OrgBrush, OrgPen, OrgFont,

и OrgPalette при создании объекта. Если вы создаете производный от TDC класс без

явного вызова конструктора TDC, то в своем конструкторе вам следует сначала вызвать конструктор TDC::Init.

GetHDC Используя Handle возвращает HDC.
GetAttribute Используя Handle возвращает HDC. Если

создаете объект с несколькими контекстами устройства, то следует переопределить эту

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

недокументированную функцию API Windows FastWindowFrame или PatBlt.



Объекты диалоговых блоков


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

блоки, производные от TDialog. ObjectWindows поддерживает также

классы, инкапсулирующие общие диалоговые блоки Windows. Windows

предусматривает общие диалоговые блоки, позволяющие пользователям

выбирать имена файлов, шрифты, цвета и т.д.



Объекты Doc/View


ObjectWindows 2.0 предусматривает новый способ манипуляции с

данными - модель Doc/View, которая состоит из трех частей:

Объектов документов, которые могут содержать несколько

различных типов данных и предусматривают методы доступа к

этим данным.

Объекты отображаемых элементов образуют интерфейс между

объектом документа и пользовательским интерфейсом. Они управляют характером вывода данных и тем, как пользователь

взаимодействует с данными.

Администратор документа, работающий в масштабе приложения,

поддерживает координаты объектов документов и соответствующих объектов отображаемых элементов.



Объекты меню


Большинство прикладных программ Windows поддерживают меню в

составе своего главного окна. Меню обеспечивает пользователю разнообразные возможности выбора, такие как Save, Open и Help. Иногда в приложениях требуются сложные меню. Объекты меню ObjectWindows (TMenu, TSystemMenu, TMenuDescr и TPopupMenu) дают вам простой способ создания меню и манипулирования ими.



Объекты приложений


ObjectWindows 2.0 инкапсулирует приложения Windows и DLL-модули с помощью классов TApplication и TModule соответственно.

Объекты TModule инкапсулируют функции инициализации и закрытия DLL Windows. Объект TModule также содержит параметры hInstance и lpCmdLine, эквивалентные параметрам с тем же именем, передаваемых функции WinMain в приложениях, которые строятся без использования

ObjectWindows.

Объект TAplication инкапсулирует инициализацию, управление этапом выполнения и функции закрытия приложения Windows. Объект TApplication содержит также значения параметров hPrevInstance и nCmdShow, которые эквивалентны параметрам с тем же именем, передаваемых функции WinMain в приложениях, которые строятся без использования ObjectWindows. Поскольку TApplication основывается на TModule, этот объект обладает всеми его функциональными возможностями. Кроме того, объект TApplication содержит функции для

простой загрузки и использования библиотеки специализированных

управляющих элементов Borland (Borland Custom Controls Library) и

библиотеку трехмерных управляющих элементов Microsoft (Microsoft 3-D Controls Library).

Явной функции WinMain в приложения ObjectWindows 2.0 не требуется. Вместо нее используется функция OwlMain, которая позволяет вам указывать параметры int argc и char** argv и возвращать int, как и обычная программа Си и С++ с функцией main.

В данном разделе описывается, как использовать объекты TApplication. Если вы не работаете с DLL, самостоятельно создавать объект TModule вам не потребуется.

Чтобы использовать объект TApplication, вы должны включить

нужный файл заголовка, создать объект и найти объект. TApplication определяется в файле заголовка owl\applicat.h. Так как TApplication является производным от TModule, owl\applicat.h включает файл owl\module.h.

Создать объект TApplication можно с помощью одного из двух

конструкторов. Наиболее общим конструктором является конструктор,

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




TApplication содержит обычно несколько функций-элементов и

элементов данных, которые может потребоваться вызывать вне объектов приложений. Чтобы вы могли к ним обращаться, класс TWindow имеет функцию-элемент GetApplication, возвращающую указатель на объект приложения. Затем вы можете использовать этот указатель для вызова функций-элементов TApplication и доступа к элементам

данных этого класса.

Минимальное приложение ObjectWindows имеет следующий вид:

#include <owl\applicat.h>

int

OwlMain(int argc, char* argv[])

{

return TApplication("ObjectWindows!").Run();

}

Оно создает приложение Windows, основное окно которого будет

иметь заголовок "ObjectWindows!". Вы можете изменять размеры этого окна или закрыть его. В реальном приложении создается новый

производный класс приложения с большими функциональными возможностями.


Объекты принтера


В данной главе описываются классы ObjectWindows, которые

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

создание объекта принтера;

создание объекта распечатки;

печать содержимого окна;

печать документа;

выбор и настройка конфигурации принтера.

Эти задачи выполняют классы TPrinter и TPrintout.



Объекты проверки допустимости


ObjectWindows предусматривает несколько способов, которые вы

можете использовать для связи объектов проверки допустимости с

редактируемыми управляющими элементами. Объекты проверки допустимости облегчают проверку допустимости данных в существующих приложениях ObjectWindows или для изменения способа проверки данных

в поле. С помощью вызова функции-элемента CanClose объекта вы можете в любое время проверить содержимое любого редактируемого управляющего элемента.



Объекты управляющих элементов


Чтобы связать с управляющим элементом объект, нужно определить указатель на объект управляющего элемента в виде элемента

данных и построить объект управляющего элемента в конструкторе

объекта диалогового блока. Вы можете также определить собственный

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

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

какой управляющий элемент в ресурсе нужно использовать, указывая

для этого идентификатор ресурса.

Манипулировать управляющими элементами вы не сможете, пока

не будет выполнена функция SetupWindow диалогового блока, поскольку до этого момента связь управляющих элементов с соответствующими объектами отсутствует. После установления связи элемента данных HWindows для управляющих элементов становится допустимым.



Объекты управляющих элементов


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

элементов, а также обеспечивает для них интерфейсные объекты, так

что вы можете использовать их в приложения. Интерфейсные объекты

для управляющих элементов называются объектами управляющих элементов.



Объявление ближних или дальних функций


В некоторых случаях вам может потребоваться переопределить

заданное по умолчание значение типа функции для модели памяти.

Например, вы используете модель памяти large, и в программе имеется рекурсивная функция:

double power(double x,int exp)

{

if (exp <= 0)

return(1);

else

return(x * power(x, exp-1));

}

Каждый раз, когда функция power вызывает сама себя, она

должна выполнить дальний вызов, причем используется дополнительное пространства стека и число тактовых циклов. Объявив power как

near, можно ускорить выполнение ее благодаря тому, что вызовы

этой функции будут ближними:

double __near power(double x,int exp)

Это гарантирует, что функция power может вызываться только

из того кодового сегмента, в котором она компилировалась, и что

все обращения к ней будут ближними.

Это означает, что при использовании большой модели памяти

(medium, large или huge) функцию power можно вызывать только из

того модуля, в котором она определена. Прочие модули имеют свои

собственные кодовые сегменты и не могут вызывать функции near из

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

И наоборот, объявление функции как дальней означает генерацию дальнего возврата. В малых моделях кодовой памяти дальняя

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

Вернемся к примеру функции power. Хорошо также объявить

power как static, поскольку предусматривается вызывать ее только

из текущего модуля. Если функция будет объявлена как static, то

имя ее не будет доступно ни одной функции вне данного модуля.



Объявление дальних объектов


Borland С++ позволяет объявлять дальние (far) объекты. Например:

int far x = 5;

int far z;

extern int far y = 4;

static long j;

Компилятор Borland C++ создает для каждого дальнего объекта

отдельный сегмент. Параметры компилятора командной строки -zE,

-zF и -zH (которые могут также задаваться директивой #pragma option) влияют на имя, класс и группу дальнего сегмента, соответственно. Изменяя эти значения при помощи указания #pragma option, вы тем самым распространяете новые установки на все объявления дальних объектов. Таким образом, для создания в конкретном сегменте дальнего объекта, можно использовать следующую последовательность:

#pragma option -zEmysegment -zHmygroup -zFmyclass

int far x;

#pragma option -zE* =zH* -zF*

Тем самым x будет помещен в сегмент MYSEGMENT с классом

'MYCLASS' в группе 'MYGROUP', после чего все дальние объекты будут сброшены в значения, используемые по умолчанию. Отметим, что

при использовании этих параметров можно поместить несколько дальних объектов в один сегмент:

#pragma option -zEcombined -zFmyclass

int far x;

double far y;

#pragma option -zE* -zF*

И x, и y окажутся в сегменте COMBINED 'MYCLASS', без группы.



Объявление указателей near, far или huge


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

часть программы. Зачем то же самое может понадобиться для указателей? По тем же причинам, что и для функций: либо для улучшения

характеристик быстродействия (объявив __near там, где по умолчанию было бы __far), либо для ссылки за пределы сегмента по умолчанию (объявив __far или __huge там, где по умолчанию бывает

__near).

Разумеется, при объявлении функций или указателей с другим

типом, нежели используемый по умолчанию, потенциально появляется

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

void myputs(s)

char *s;

{

int i;

for (i = 0; s[i] != 0; i++) putc(s[i]);

}

main()

{

char near *mystr;

mystr = "Hello, world\n";

myputs(mystr);

}

Эта программа работает удовлетворительно, хотя объявление

mystr как __near избыточно, поскольку все указатели, как кода,

так и данных, будут ближними (near) по умолчанию.

Однако, что произойдет, если перекомпилировать эту программу

с моделью памяти compact (либо large или huge)? Указатель mystr в

функции main останется ближним (16-битовым). Однако, указатель s

в функции myputs теперь будет дальним (far), поскольку по умолчанию теперь используется far. Это означает, что попытка создания

дальнего указателя приведет к извлечению из стека двух слов, и

полученный таким образом адрес, безусловно, не будет являться адресом функции mystr.

Как избежать этой проблемы? Решение состоит в том, чтобы определить myputs в современном стиле Си:

void myputs(char *s)

{

/* тело myputs */

}

Теперь при компиляции вашей программы Borland C++ знает, что

myputs ожидает указатель на char. Поскольку компиляция выполняется с моделью large, то известно, что указатель должен быть __far.

Вследствие этого Borland C++ поместит в стек регистр сегмента

данных (DS) и 16-битовое значение mystr, образуя тем самым дальний указатель.

Если вы собираетесь явно объявлять указатели как far или near, не забывайте использовать прототипы тех функций, которые могут работать с этими указателями.

Как быть в обратном случае: когда аргументы myputs объявлены

как __far, а компиляция выполняется с моделью памяти small? И в

этом случае без прототипа функции у вас возникнут проблемы, поскольку функция main будет помещать в стек и смещение, и адрес

сегмента, тогда как myputs будет ожидать приема только одного

смещения. При наличии определений функций в прототипах main будет

помещать в стек только смещение.



Объявление виртуальных функций элементов


Фактически, мы уже видели как это делается на примере класса

shape, однако, рассмотрим еще раз этот процесс:

class shape {

public:

double xo, yo;

shape(double x, double y); // Конструктор создания shape (фигуры)

virtual double area(void); // Функция вычисляющая поверхность

virtual draw(void); // Функция рисования shape

}; ^

Ключевое слово virtual

Виртуальные функции объявляются с использованием ключевого слова

virtual. Отметим, что virtual используется только в базовом классе, а

не в классах - потомках.



Область дампа


В этой области выводится в шестнадцатиричном виде содержимое

области памяти. В левой части каждой строки показан адрес (в виде

"сегмент:смещение" или 32-разрядного адреса). Порядок регистров в

области Dump имеет вид: DS, ES, SS, CS. Справа от адреса выводятся значения элементов данных в выбранном формате.

SpeedMenu области Dump содержит команды для перемещения по

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

Goto

Выводит диалоговое окно Enter Address to Position To, где вы

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

памяти, доступный программе.

Search

Ищет строку символов или список байт, начиная с адреса, указанного курсором.
Next

Ищет следующий экземпляр элемента, заданного в команде поиска.
Change

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

Открывает меню с командами, позволяющими проверить данные по

адресам указателей near и far. TD32 содержит команды для 32-разрядной адресации.


Команда Near Code этого меню интерпретирует

слово под курсором в области данных, как смещение в текущем сегменте кода (как это задается регистром CS). Область кода становится текущей областью и позиционируется на данный адрес.
Команда Far Code интерпретирует двойное слово под курсором в области данных, как адрес дальнего типа (сегмент и смещение). Область кода

становится текущей и позиционируется на данный адрес.


Команда Offset to Data позволяет вам следовать по цепочке указателей размером в слово (ближнего типа, где используется только смещение).

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


Команда Segment:Offset to Data позволяет следовать по цепочке указателей дальнего типа размером в двойное слово (где используется сегмент

и смещение). Область данных устанавливается в соответствии со

смещением, заданным двойным словом в памяти по текущей позиции

курсора.


Команда Base Segment:0 to Data команда интерпретирует

слово под курсором, как адрес сегмента, и позиционирует область

данных на начало сегмента.

Previous

Восстанавливает адрес области данных в адрес, который был до

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

последних адресов, поэтому вы можете вернуться назад после многократного (< 5) использования команд локального меню Follow, или команды Goto.

Display As

Позволяет выбирать формат вывода в области данных. Вы можете

выбирать один из форматов данных, использующихся в языке Си, Pascal или ассемблер. Эти форматы можно выбрать из меню. Команда Byte устанавливает область данных в режим вывода шестнадцатиричных

байтовых данных. Word устанавливает область данных в режим вывода

шестнадцатиричных слов. Long задает режим вывода длинных шестнадцатиричных целых чисел. Comp устанавливает режим вывода 8-байтовых целых чисел. Выводится десятичное значение числа. Float устанавливает режим вывода 6-байтовых чисел с плавающей точкой. Выводится значение числа с плавающей точкой в научном представлении.

Double выводит 8-байтовые числа с плавающей точкой. Выводится

значение числа в научном представлении. Extended устанавливает

режим вывода 10-байтовых чисел с плавающей точкой в научном

представлении.

Block

Позволяет работать с блоками памяти. Вы можете перемещать,

очищать, присваивать значения блокам памяти, а также записывать и

считывать блоки памяти из файлов на диске. По данной команде на

экран выводится всплывающее меню. Команда Clear этого меню устанавливает непрерывный блок в памяти в значение 0. Адрес блока и

число байт, которые требуется очистить, запрашиваются в выводимой

подсказке. Move копирует блок памяти из одного адреса в другой.

Адреса исходного и целевого блока, а также число копируемых байт,

будут запрашиваться в подсказке. Set присваивает непрерывному

блоку в памяти конкретное байтовое значение. Адрес блока, число

байт, которым требуется присвоить значение, а также само значение

запрашиваются в подсказке. Read считывает все содержимое или

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

в файл. Выводится подсказка для ввода имени файла, куда требуется

записать данные, затем блока памяти, который нужно записать, и

число считываемых байт.



Область дерева окон


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

вам:

Определить, какие окна активны в оперативной области.

Просмотреть статус окон, включая скрытые окна.

Увидеть, какие окна получают сообщения.

Выбрать окна для трассировки сообщений.



Область детализации


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

подсвеченной нити (приостановлена или выполняется) и ее приоритет. Операционная система устанавливает 5 различных приоритетов

(от -2 до 2). Вторая строка показывает текущую точку выполнения

нити, а третья (если она есть) - как получил управление отладчик.



Область флагов


В области флагов показано значение каждого флага ЦП. Список

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

Буква в области Название флага

c Флаг переноса

z Флаг нуля

s Флаг знака

o Флаг переполнения

p Флаг четности

a Флаг дополнитель-

ного переноса

i Флаг разрешения

прерывания

d флаг направления

SpeedMenu этой области содержит содержит команду Toggle, переключающую значение подсвеченного флага между 0 и 1.



Область иерархии


Здесь выводятся классы загруженного модуля и их иерархии.

Базовые классы размещаются по левому полю области. Классы, наследующие из нескольких базовых классов, отмечаются звездочками

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

Локальное меню этой области содержит две команды. Команда

Inspect (или клавиша Enter) открывает для подсвеченного класса

окно Class Inspector. При отладке программ С++ с множественным

наследованием здесь доступна также команда Parents, включающая и

выключающая вывод области порождающих классов окна Hierarchy.



Область классов


Здесь перечисляются классы, найденные ClassExpert в текущем

приложении. Информация в областях событий и редактирования зависит от выбранных здесь классов. Чтобы перейти к конструктору

класса в исходном коде, вы можете дважды щелкнуть на классе

"мышью". При этом выводится область редактирования. Используя

оперативное меню, вы можете добавить классы, связать классы документов с классами отображаемых элементов, получить информацию о

классе, перейти к исходному коду класса или файла заголовка и запустить Resource Workshop.



Область классов


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

поиска класса используется средство инкрементального поиска. Если

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

начинающееся с набранных символов.

SpeedMenu этой области содержит две команды. Команда Inspect

(или клавиша Enter) открывает для текущего класса окно Class Inspector. Команда Tree активизирует область иерархии, подсвечивая

текущий класс.



Область кода


В левой части области кода выводятся адреса дизассемблированных инструкций. Для 16-разрядного кода они имеют вид "сегмент:смещение", а для 32-разрядного это 32-разрядные адреса. Стрелка (>) справа от адреса памяти указывает текущий адрес программы (следующую выполняемую инструкцию). Справа выводится шестнадцатиричный машинный код с соответствующей дизассемблированной

инструкцией. Глобальные идентификаторы выводятся в виде имени,

статические - в виде имени модуля с символов # и именем идентификатора, а номера строк представлены как имя модуля, # и номер

строки. Клавиша F2 позволяет устанавливать/отменять точки останова.

Меню SpeedMenu области кода содержит команды, позволяющие

перемещаться по ней и ассемблировать вводимые инструкции. TDW

имеет дополнительную команду ввода-вывода, а TD32 - команды Threads и OS Exceptions.

Goto

Вам выводит окно Enter Address to Position To для ввода нового адреса, на который вы хотите перейти. Вы можете ввести адрес, выходящий за пределы программы, что позволяет проверить базовую систему ввода-вывода (BIOS), внутренние области DOS и Windows.
Origin

Позиционирует вас на текущий адрес программы. Используется

для перемещения.

Follow

Позиционирует область кода по целевому адресу текущей подсвеченной инструкции. Используется в сочетании с инструкциями передачи управления (CALL, JMP, INT) и условного перехода (JZ, JNE, LOOP и др.).
Caller

Позиционирует вас на инструкцию, вызвавшую текущее прерывание или подпрограмму. Если текущая подпрограмма прерывания занесла данные в стек, то Turbo Debugger может не иметь возможности

определить, откуда она вызвана.

Previous

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

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

хотите найти. Будьте внимательны при поиске инструкций. Следует

выполнять поиск только тех инструкций, которые не изменяют байт,

в которые они ассемблируются, в зависимости от того, где в памяти

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

не представляет:

PUSH DX

POP [DI+4]

ADD AX,100

<

а попытка поиска следующих инструкций может привести к непредсказуемым результатам: JE 123 CALL MYFUNC LOOP $-10 Вместо инструкции можно вводить также список байт.
View Source Для вывода исходного кода, соответствующего текущей дизассемблированной инструкции открывает окно Module. Если соответствующего исходного кода нет (например, вы находитесь в коде Windows, или отсутствует отладочная информация), вы просто остаетесь в области кода.
Mixed Позволяет выбрать один из трех способов вывода на экран дизассемблированных инструкций и исходного кода:
No (Нет) Исходный код не выводится, выводятся только дизассемблрованные инструкции.
Yes (Да) Перед первой дизассемблированной инструкцией, со ответствующей данной строке, выводится строка исходного кода. Область устанавливается в данный режим, если исходный модуль написан на языке высокого уровня.
Both (Оба) Для тех строк, которым соответствует исходный код, дизассемблированные строки заменяются строками исходного текста. В противном случае выводятся дизассемблированные инструкции. Используйте этот режим, когда вы отлаживаете модуль на ассемблере и хотите видеть строку исходного текста, а не соответствующую дизассемблированную инструкцию. Область устанавливается в данный режим вывода, если текущим модулем является исходный модуль ассемблера.
Thread Позволяет выбрать нить, выполнение которой вы хотите отладить. Открывает диалоговое окно Pick a Thread, из которого вы можете выбрать конкретную нить программы.
OS Exceptions Позволяет выбрать исключительные ситуации операционной системы, которые вы хотите обрабатывать. Подробнее об этом рассказывается ниже.
New EIP Изменяет текущий адрес программы, подсвеченный в области кода (в TDW команда называется New CS:IP). При возобновлении выполнения программы оно начинается по этому адресу. Эта команда полезна, когда нужно пропустить некоторые машинные инструкции, но использовать ее нужно аккуратно, так как она может вызвать нестабильность системы.
Assemble



Ассемблирует инструкцию, заменяя инструкцию по текущему адресу. Используется для внесения в программу минимальных изменений. Команда выводит диалоговое окно Enter Instruction to Assemble, где вы можете ввести выражение для ассемблирования. Если вы начнете набор в области кода, данная команда вызывается автоматически.
I/O Эта команда TDW считывает или записывает значения в пространство адресов ввода-вывода ЦП и позволяет вам проверить содержимое регистров ввода-вывода и записать в них значения. При этом выводится меню, показанное ниже:
In byte Ввести байт из порта
Out byte Вывести байт в порт
Read byte Прочитать байт из порта
Write byte Записать байт в порт Учтите, что эти команды могут нарушить нормальную работу устройств.

Область нитей


В этой области перечисляются все активные нити программы,

идентифицируемые по номеру нити (назначаемому Windows NT) и имени. Turbo Debugger генерирует имя нити, когда ваша программа создает нить. Первая создаваемая нить называется Thread 1, затем Thread 2 и т.д. Это имя можно изменить.

Окно Thread содержит единое SpeedMenu, которое активизируется из всех областей и содержит перечисленные ниже команды.

Options

Открывает диалоговое окно Thread Options, позволяющее задать

параметры отдельных нитей. Кнопка Freeze этого окна позволяет

"замораживать" и "размораживать" индивидуальные нити. Включение

этой кнопки означает, что нить выполняться не будет. Для выполнения программы необходима хотя бы одна активная нить. Кнопка Notify or Tremination позволяет задать, должен ли отладчик уведомлять

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

меню All Threads. Поле ввода Thread Name позволяет изменить имя

текущей нити.

Make Current

Команда Make Current позволяет сменить нить, обрабатываемую

отладчиком. Подсветите в области Threads List нить, которую вы

хотите проверить, и нажмите Ctrl+M (или выберите Make Current).

Inspect

Открывает окно Module или CPU, которое показывает для подсвеченной нити текущую точку выполнения. Этой команде эквивалентна

клавиша Enter.

All Threads

Открывает меню, команды которого относятся ко всем нитям

программы. Это команды Thaw, Freeze, Enable Exit Notification и

Disable Exit Notification.

Step

Позволяет переключаться между All и Single. При выборе All

клавиши F7 и F8 приводят к выполнению всех нитей программы, а

Single позволяет выполнять только одну нить.



Область порождающих классов


Это окно выводит наследование классов С++ и, в зависимости

от использования в программе множественного наследования, состоит

из трех областей.




Эта область выводится только для программ с множественным

наследованием и при ее разрешении. Для классов, полученных путем

множественного наследования, она выводит все производные классы.

SpeedMenu этой области содержит единственную команду Inspect. При

ее выборе (или нажатии Enter) для подсвеченного класса выводится

окно Class Inspector.



Область редактирования


Это редактор, в котором выводится исходный код элементов,

выбранных в области классов и области событий. Это окно имеет те

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



Область регистров и флагов


В области регистров (верхняя область справа от области кода)

выводится содержимое регистров процессора. Вид этой области зависит от отладчика (TD32 или TDW). По умолчанию TDW выводит 13

16-разрядных регистров, а TD32 - всегда выводит 15 регистров процессора 80386 и старше.

С помощью команд SpeedMenu области регистров вы можете модифицировать или сбрасывать содержимое регистров. Команда Increment

добавляет 1 к текущему подсвеченному регистру, Decrement вычитает

1 из содержимого текущего подсвеченного регистр, а Change позволяет изменить содержимое регистра, выводя диалоговое окно Enter

New Value для ввода нового значения. Последняя команда вызывается

автоматически, если вы начинаете набор в области регистров.

Команда Registers 32-bit, доступная только в TDW, переключает вывод регистров с 16-битовых на 32-битовые (сегментные регистры остаются 16-битовыми).



Область селектора


В этой области (только для TDW) выводится список селекторов

защищенного режима и указывается некоторая информация для каждого

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

соответствующего адресу памяти. Если селектор недопустим, то он

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

следующее:

являются ли содержимым данные или код;

загружена ли область памяти, на которую ссылается селектор

(присутствует в памяти) или разгружена (выведена на диск);

длина сегмента памяти, на которую ссылается селектор (в

байтах).

Если селектор ссылается на сегмент данных, то имеется дополнительная информация по полномочиям доступа (Read/Write - Чтение/

Запись или Read only - только чтение) и направление расширения

сегмента в памяти (Up - вверх или Down - вниз).

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

Команда Selector выводит подсказку для ввода селектора, который нужно вывести в области. Для ввода селектора вы можете использовать полный синтаксис выражений. Если вы вводите числовое значение, то TDW подразумевает, что оно десятичное (если вы не

используете синтаксис текущего языка для указания того, что значение является шестнадцатиричным).

Другим методом ввода значения селектора является вывод окна

CPU и проверка содержимого сегментных регистров. Если регистр содержит интересующий вас селектор, то вы можете ввести имя регистра с предшествующим символом подчеркивания (_). Например, вы можете задать имя сегментного регистра данных, как _DS.

Команда Examine выводит содержимое области памяти, на которую ссылается текущий селектор, и переключается в область, где

выводится содержимое. Если селектор указывает на сегмент кода, то

содержимое выводится в области кода. Если содержимое представляет

собой данные, то оно выводится в области данных.



Область событий


В области событий (Events) перечисляются события и виртуальные функции базового класса в классе, выбранном в области классов

(Classes). Информация в области событий зависит от типа базового

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



Область списка классов


Иногда вместо выбора для трассировки конкретных окон может

потребоваться просматривать сообщения для всего класса окон. Это

можно сделать с помощью области списка классов.



Область стека


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

SpeedMenu этой области содержит команды Goto, Origin, Follow,

Previous и Change, аналогичные описанным выше командам.



Обработка данных WinSpector


Утилита DFA обрабатывает информацию Турбо отладчика,

собранную WinSpector во время возникновения исключительной ситуации. Если во время исключительной ситуации информация отчета установлена в PostMortem Dump, то WinSpector записывает файл

WINSPCTR.BIN. После этого для трансляции файла WINSPCTR.BIN в полезный формат можно использовать утилиту DFA.



Обработка ошибок в графическом режиме


Ниже приведены функции обработки ошибок в графическом режиме:

Функция Описание

grapherrormsg Возвращает строку с сообщением об ошибке

для заданного кода ошибки.

graphresult Возвращает код ошибки для последней графической операции, в которой встретилась

ошибка.

Если ошибка произошла при вызове графической библиотечной

функции (например, не найден шрифт, запрошенный функцией settextstyle), устанавливается внутренний код ошибки. Доступ к коду

ошибки для последней графической операции, сообщившей об ошибке,

выполняется при помощи функции graphresult. Вызов grapherrormsg(graphresult()) возвращает строку сообщения об ошибке из

приведенной выше таблицы.

Код возврата ошибки накапливается, изменяясь только когда

графическая функция сообщает об ошибке. Код возврата ошибки сбрасывается в 0 только при успешном выполнении initgraph, либо при

вызове функции graphresult. Таким образом, если вы хотите знать,

какая графическая функция возвратила ошибку, нужно хранить значение graphresult во временной переменной и затем проверять ее.

Код ошибки Константа графической ошибки Соответствующая строка с сообщением об ошибке

0 grOk No error (нет ошибки)
-1 grNoInitGraph (BGI) graphics not installed

(use initgraph) (графика не инсталлирована используйте функцию initgraph)

-2 grNotDetected Graphics hardware not detecte

(графическое аппаратное обеспечение не обнаружено)

-3 grFileNotFound Device driver file not found

(не найден файл драйвера устройства)

-4 grInvalidDriver Invalid device driver file

(неверный файл драйвера устройства)

-5 grNoLoadMem Not enough memory to load driver

(не хватает памяти для загрузки

драйвера)

-6 grNoScanMem Out of memory in scan fill

(кончилась память при сканирующем заполнении)

-7 grNofloodMem Out of memory in flood fill

(кончилась память при лавинном

заполнении)

-8 grFontNotFound Font file not found (файл шрифта не найден)
-9 grNoFontMem Not enough memory to load font

(не хватает памяти для загрузки

шрифта)

-10 grInvalidMode Invalid graphics mode for

selеcted driver (недопустимый графический режим

для выбранного драйвера)

-11 grError Graphics error (графическая ошибка)
-12 grIOerror Graphics I/O error

(графическая ошибка ввода-вывода)

-13 grInvalidFont Invalid font file

(неверный файл шрифта)

-14 grInvalidFontNum Invalid font number (неверный номер шрифта)
-15 grInvalidDeviceNum Invalid device number (неверный номер устройства)
-18 grInvalidVersion Invalid version of file (неправильная версия файла)



Обработка событий


В данной главе описывается, как использовать таблицы реакции

ObjectWindows 2.0. Таблицы реакции - это методы, используемые для

обработки событий в приложении ObjectWindows. Для использования

таблицы реакции ObjectWindows нужно выполнить следующие шаги:

Описать таблицу реакции.

Определить таблицу реакции.

Определить записи таблицы реакции.

Описывать и определить функции-элементы реакции.

Для использования описываемых в данном разделе макрокоманд

вы должны включить файл заголовка owl\eventhan.h. Этот файл уже

включается файлами owl\module.h и owl\window.h, поэтому явно данный файл обычно включать не требуется.

Таблицы реакции ObjectWindows 2.0 - это значительное усовершенствование по сравнению с методами обработки событий Windows и

сообщениями, включая оператор switch (как в стандартных программах Си для Windows) и схемы, используемые в других прикладных

средах. Таблицы реакции ObjectWindows 2.0 предусматривают:

Автоматическую обработку сообщений для предопределенных

командных сообщений, что устраняет необходимость вручную

обрабатывать значения WPARAM и LPARAM.

Проверку ошибок и типов на этапе компиляции, при которой

проверяются типы параметров и типы результата функции обработки событий.

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

Поддержку множественного наследования и возможность для

каждого производного класса построения таблиц реакции на

основе базового класса или классов.

Переносимость на разные продукты без специальных расширений компилятора.

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

макрокоманд таблицы реакции.



Обработка событий Doc/View


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

объекта с классом отображаемого элемента.



Обработка событий TDocManager


Если при построении объекта TDocManager вы задаете параметр

mdMenu, администратор документа обрабатывает определенные события

от имени документов. Это делается путем обработки стандартных команд меню с помощью таблицы реакции. Команды меню администратора

документа доступны даже при отсутствии открытого документа и независимо от явного добавления в приложение ресурсов. Администратор документов может обрабатывать следующие события:

Сообщение Значение

CM_FILECLOSE Закрытие файла.
CM_FILENEW Создание нового файла.
CM_FILEOPEN Открытие файла.
CM_FILEREVERT Отмена изменений файла.
CM_FILESAVE Сохранение файла.
CM_FILESAVEAS Сохранение файла под новым именем.
CM_VIEWCREATE Создание отображаемого элемента.

В некоторых экземплярах вы можете обрабатывать эти события

самостоятельно. Так как поиск в таблице событий администратора

документа выполняется в последнюю очередь, вы можете обрабатывать

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

dmMenu и предусмотреть функции для обработки этих событий (обычно

через объект приложения или другой интерфейсный объект).



Обработка событий в отображаемом элементе


Файл заголовка docview.h предусматривает ряд макрокоманд для

таблицы реакции, а также функции обработки и проверки типов. С

помощью NOTIFY_SIG и VN_DEFINE вы можете также определить собственные функции и события.

Имеется ряд предопределенных событий Doc/View. Каждое такое

событие имеет соответствующую макрокоманду таблицы реакции и сигнатуру функции-обработчика. Модель Dec/View не предусматривает

версий этих функций. Вы должны определить эти функции в своем

производном классе и задать соответствующие действия.

Макрокоманда Событие

EV_VN_VIEWOPENED Построение нового отображаемого элемента.
EV_VN_VIEWCLOSED Уничтожение нового отображаемого элемента.
EV_VN_DOCOPENED Открытие нового документа.
EV_VN_DOCCLOSED Закрытие нового документа.
EV_VN_COMMIT Изменения, внесенные в данные в отображаемом элементе должны быть зафиксированы в документе.
EV_VN_REVERT Изменения, внесенные в данные в отображаемом элементе должны быть отменены.
EV_VN_ISDIRTY Если изменения еще не зафиксированы в документе, следует возвратить True, иначе False.
EV_VN_ISWINDOWS Если параметр HWND совпадает с HWND окна отображаемого элемента, следует возвратить True.

Для генерации собственных событий отображаемых элементов и

определения соответствующих макрокоманд и функций обработки событий таблицы реакции вы можете использовать макрокоманды VN_DEFINE

и NOTIFY_SIG.

Во-первых, нужно определить имя события, которое вы хотите

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

NOTIFY_SIG, а для определения самой макрокоманды - VN_DEFINE. Эта

макрокоманда имеет три параметра: имя события, имя функции обработки события и размер параметра для функции обработки события.



Обработка событий в приложении


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

отображаемого элемента. Событие dnCreate генерируется при создании отображаемого элемента или документа, а dnClose - при их закрытии. Чтобы задать для этих событий таблицу реакции, добавьте в

нее макрокоманды EV_OWLDOCUMENT и EV_OWLVIEW.



Обработка сообщений приложения


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

выполняя обработку во время простоя.

TApplication имеет функции-элементы MessageLoop, IdleAction,

PreProcessMenu и ProcessAppMsg, обеспечивающие для любых приложений ObjectWindows функциональные возможности обработки сообщений.

Обработка во время простоя реализуется с помощью переопределения IdleAction. Такая обработка выполняется, когда пользователь

не выполняет никаких действий. Такая обработка должна быть краткосрочной. Длительные операции следует разбивать на несколько процессов.

Параметр функции IdleAction idleCount задает, сколько раз

между сообщениями должна вызываться IdleAction. idleCount можно

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

В дополнение к своей собственной обработке всегда следует

вызывать функцию IdleAction базового класса. Если вы пишете приложения для Windows NT, то можете для фоновой обработки использовать несколько нитей.



Обработка сообщений управляющих элементов VBX


Обрабатывать сообщения управляющих элементов VBX нужно через

родительский объект управляющего элемента. Чтобы родительский

объект мог обрабатывать эти сообщения, он должен быть производным

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

VBX (например, TDialog, TFrameWindow или классы, производные от

интерфейсных классов ObjectWindows) с классом TVbxEventHandler.



Обратное выполнение


Каждую выполненную инструкцию Turbo Debugger регистрирует в

протоколе выполнения (при трассировки программы). С помощью окна

протокола выполнения Execution History вы можете просмотреть выполненные инструкции и вернуться в нужную точку программы. Команда обратного выполнения Reverse Execute выполняется по клавишам

Alt+F4. Turbo Debugger может регистрировать около 400 инструкций.

Здесь действуют следующие правила:

Регистрируются только те инструкции, которые выполнены с

помощью команды Trace Into (F7) или Instruction Trace

(Alt+F7). Однако, если не выполняются отдельные инструкции

(перечисленные ниже), то регистрируются также команды Step

Over.

Инструкция INT приводит к стиранию протокола выполнения.

Если вы не трассируете прерывание с помощью Alt+F7, то об ратное выполнение этой инструкции невозможно.

После выполнения команды Run или выполнения после прерыва ния протокол удаляется. (Регистрация начинается после во зобновления трассировки.)

При выполнении вызова функции без ее трассировки обратное

выполнение за инструкцию после возврата невозможно.

Обратное выполнение инструкций работы с портами невозможно

(отменить чтение и запись нельзя).

Невозможно также обратное выполнение вызываемого програм мой кода Windows (если только вы не находитесь в окне CPU

и не отлаживаете DLL).

В окне CPU обратное выполнение доступно всегда, а для обратного выполнения исходного кода нужно установить Full History в On

(в меню Execution History). Меню Execution History содержит также

команды Inspect и Reverse Execute. Команда Inspect переводит вас

к команде, подсвеченной в области Instruction. Если это строка

исходного кода, она выводится в окне Module. При отсутствии исходного кода открывается окно CPU и подсвечивается инструкция в

области Code. Действие инструкций IN, INSB, INSW, OUT, OUTSB,

OUTSW отменить невозможно, поэтому их обратное выполнение может

давать побочные эффекты.

TD.EXE имеет в окне Execution History дополнительную область, позволяющую вам вернуться в нужную точку программы при

случайной потере протокола. Область Keystroke Recording в нижней

части этого окна активизируется при разрешении регистрации нажатий клавиш (это можно сделать с помощью TDINST или параметра -k

командной строки).

Область Keystroke Recording показывает причину передачи управления отладчику (например, точка останова) и текущий адрес

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

инструкцией. Turbo Debugger регистрирует все нажимаемые вами клавиши и записывает их в файл XXXX.TDK, где XXXX - это имя отлаживаемой программы. Локальное меню этой области содержит команды

Inspect и Keystroke Restore. По команде Inspect отладчик активизирует окно Model или CPU, в котором курсор позиционирован на ту

строку, где нажата клавиша. Команда Keystroke Restore перезагружает программу и выполняет ее до строки, подсвеченной в области

Keystroke Recording.



Общие сообщения об ошибках и предупреждения компилятора


В данном разделе описываются некоторые наиболее общие ошибки

и предупреждения, обнаруживаемые компилятором.

Call to function имя_функции with no prototype


(Вызов функции без прототипа)

Данное предупреждение означает, что функция используется перед ее прототипизацией или описанием. Это предупреждение может

выводиться также, когда функция, не воспринимающая аргументов, не

описана прототипом с void.

Conversion may lose signifigant digits


(Преобразование может привести к потере значимых цифр)

Это предупреждение является результатом преобразования компилятором значения, например, LONG в int. Оно сообщает, что вы

можете потерять информацию. Если вы уверены, что таких проблем не

возникает, то с помощью соответствующего явного приведения типа к

меньшему размеру это предупреждение можно подавить.

Function should return a value


(Функция должна возвращать значение)

Функция, описанная как возвращающая значение, значения не

возвращает. В старом коде Си, отличном от стандарта ANSI, такое

предупреждение является общим для функций, не возвращающих значения и не имеющих типа возврата:

foo(i)

int i;

{

...

}

Описанные таким образом функции интерпретируются компилятором, как возвращающие int. Если функция ничего не возвращает, ее

следует описать так:

void foo(int i)

{

...

}

Lvalue required


(Требуется именующее значение)

Type mismatch in parameter


(Несовпадение типа в параметре)

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

STRICT описателей, а также LRESULT, WPARAM и LPARAM внутренним

образом описываются как указатели, поэтому попытка передачи в качестве указателя int, WORD или LONG дает в результате подобные

ошибки.

Эти ошибки следует исправлять путем описания отличных от

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

присваивании. В случае специальных констант, таких как (HWND)1,

вам следует пользоваться новыми макрокомандами (такими как

HWND_BOTTOM). Ошибки несоответствия типов следует подавлять в




исключительных случаях ( так как часто это может дать в результате

некорректный код).

Non-portable conversion

(Не переносимое преобразование)

Вы приводите указатель или описатель ближнего типа к 32-битовому значению, такому как LRESULT, LPARAM, LONG или DWORD. Это

предупреждение практически всегда указывает на ошибку, так как

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

Чтобы избежать этого предупреждения и обеспечить размещение

в старших 16 битах 0, нужно привести тип описателя к UINT:

HWND hwnd;

LRESULT result = (LRESULT)(UINT)hwnd;

В тех случаях, когда вы хотите, чтобы 32-битовое значение

содержало указатель FAR, можно избежать предупреждения путем явного приведения типа к дальнему указателю:

char near* pch;

LPARAM lparam = (LPARAM)(LPSTR)pch;

Not an allowed type



(Не является допустимым типом)

Это сообщение об ошибке обычно выводится в результате попытки разыменования указателя void. Обычно это бывает при непосредственном использовании значения-указателя, возвращаемого GlobalLock или LocalLock. Чтобы решить данную проблему, перед использованием указателя присвойте возвращаемое значение переменной соответствующего типа (используя при необходимости приведение типа).

Size of the type is unknown or zero



(Размер типа неизвестен или равен нулю)

Вы пытаетесь с помощью + или += изменить значение пустого

указателя. Это ошибка обычно появляется в результате того, что

отдельные функции Windows (например, GlobalLock или LocalLock)

возвращающие указатели произвольных типов, определены для возврата void FAR* вместо LPSTR. Чтобы решить эту проблему, присвойте

значение void* описанной соответствующим образом переменной (приведя при необходимости тип):

BYTE FAR* lpb = (BYTE FAR*)GlobalLock(h);

lpb += sizeof(DWORD);

Type mismatch in redeclaration of имя_параметра



(Несовпадение типа при повторном описании параметра)

В вашей программе имеется несогласованное описание переменной, параметра или функции. Используя API Win32, вы можете внести

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

переносимой.


Обзор и важные концепции


Библиотека классов container, поставляемая в пакете Турбо и

Borland C++, содержит классы для часто используемых структур данных

(списки, стеки, очереди и т.д.). Классы организованы в соответствии с

иерархией классов, что позволяет иметь высокую степень модульности

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

их, получая объектно-ориентированные программные продукты, подходящие

для ваших задач.

В вершине иерархии классов conteiner находится абстрактный класс

Object. Он почти не содержит данных-элементов, а его функции элементы

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

объектов, называются реализуемыми классами (абстрактные классы заключены в кавычки.)

Чтобы лучше освоить понятие классов, посмотрите их исходные

тексты в каталоге CLASSLIB дистрибутивной поставки компилятора.

"Object" Error

"Sortable" String

"BaseDate" Date

"BaseDate" Time

Association

"Container" "Collection" "AbstractArray" Array

SortedArray

HashTable Bad Set Dictionary

List

DoubleList

Stack

Queue

Deque

"ContainerIterator" HashTableIterator

ListIterator

DoubleListIterator

ArrayIterator

DoubleListElement

ListElement

Рис. Иерархия классов в CLASSLIB



Окна Class Inspector


Эти окна позволяют вам вывести детальную информацию по классам С++. Чтобы открыть это окно, выведите окно Hierarchy, подсветите класс и нажмите Enter.

[Ч] Class LinearGauge 4 [^][v]

int Range::Low ^

int Range::High

int Screen::MaxX v

< >

class Range *Range::ctr()

int Range::GetValue()

int Range::GetLow()

int Range::GetHigh()

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

функцию-элемента, подсветите ее и нажмите Enter. Откроется окно

Function Inspector.

Если подсвеченный элемент данных представляет собой указатель на класс, то нажатие Enter открывает другое окно Class Inspector. Таким образом вы можете проверять сложные вложенные классы. Как и в случае других окон Inspector клавиша Esc закрывает

текущее окно Inspector, а Alt+F3 закрывает их все.

SpeedMenu каждой области данного окна содержит три команды,

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

Inspect

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

открывает для подсвеченной функции окно Function Inspector. Для

вывода исходного кода функции позиционируйте курсор на адрес

функции-элемента и нажмите Enter. Откроется окно Module.

Hierarchy

Во всех областях открывает окно Hierarchy для текущего подсвеченного класса.
Show Inherited

В каждой области переключается между Yes (по умолчанию) и

No. При установке в Yes Turbo Debugger показывает для подсвеченного класса все функции-элементы или элементы данных, включая

наследуемые. В противном случае выводятся только элементы данного

класса.



Окна Inspector


Выводят текущее содержимое выбранной переменной. Его можно

открыть с помощью команды Data Inspect или Inspect меню SpeedMenu. Закрывается оно обычно по Esc или щелчком "мышью" на блоке

закрытия. При последовательном открытии нескольких окон Inspector

нажатием Alt+F3 или командой Window Close вы можете закрыть сразу

все эти окна. Окна Inspector выводят простые скалярные величины,

указатели, массивы, объединения, структуры, классы и объекты. Выбором команды Inspect в этом окне вы можете создать дополнительные окна Inspector.



Окна Inspector


Эти окна предоставляют наилучший способ просмотра элементов

данных, так как они автоматически форматируются в соответствии с

типом данных. Их особенно полезно использовать при проверке сложных объектов данных (массивов или связанных списков). Чтобы просмотреть данные в шестнадцатиричном виде, в активном окне Inpsector используйте команду View Dump. Окна Inspector открываются из

команды Data Inspector или SpeedMenu окон Wathes, Variables или

Inspector.

При открытии окна Inspector выводится диалоговое окно Enter

Variable с подсказкой на ввод выражений. Введите имя переменной

или выражение. Если в момент команды Inspect курсор находится на

идентификаторе, или вы выделили выражение, то они автоматически

помещаются в поле ввода. Заголовок окна Inspector содержит проверяемое выражение.

Скалярное окно Inspector показывает значения простых элементов данных, таких как char, int или long. Оно содержит две строки: в первой указан адрес переменной, а вторая показывает ее тип и значение (в десятичном/шестнадцатиричном виде).

[*] Inspecting wordcount 3 [^][v]

05A51:AA00

unsigned int 2 (0x02)

< >

Окно Inspector для указателей выводит значения переменных,

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

указываемых данных. В нижней области показывается тип этих данных.

[*] Inspecting bufp 3 [^][v]

register ds:0874 [TCDEMO buffer] ^

[0] 'n' 110 (Ox88)

[1] '0' 111 (Ox6F)

[2] 'w' 119 (Ox77)

< >

char *

Если указатель ссылается на сложный объект данных, значения

заключаются в фигурные скобки (выводится столько данных, сколько

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

элемент символьного массива с указанием индексов и значений. Команда Range позволяет выводить несколько строк информации.

Окна Inspector для структур и объединений показывают значения элементов в сложных объектах данных. Такое окно имеет две области. В верхней области выводится адрес объекта данных с перечислением имен и значений элементов данных объекта. Нижняя область содержит одну строку. Если вы в верхней области подсветите




адрес объекта данных, в нижне выводится тип объекта и его имя. В

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

[*] Inspecting letterinfo[n] 3 [^][v]

$7937:0852 ^

count 2 (Ox2)

firstletter 2 (Ox2)

< >v

struct linfo

Область Inspector для массива показывает значения элементов

массива (каждому элементу соответствует строка). Слева выводится

индекс, справа - значение. Если значением является составной объект, Turbo Debugger выводит максимум данных объекта.

[*] Inspecting letterinfo 3 [^][v]

$7682:0852 ^

[0] {2,2}

[1] {2,0}

[2] {2,0}

[3] {1,1}

[4] {1,0}

< >

struct linfo [26]

Окно Inspector для функции показывает адрес функции, ее аргументы, а также возвращаемый функцией тип (в нижней области) и

соглашения по вызову.

[*] Inspecting analyzewords 3 [^][v]

071E9:02DD

char *bufp

< >

long ()


Окна MDI


Окна многодокументального интерфейса или окна MDI являются

частью интерфейса MDI, используемого для управления несколькими

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

редактирование файла или работу с файлом электронной таблицы.



Окна меню View


Меню View является точкой входа в большинство окон Turbo Debugger. Перечислим их кратко. С помощью команды View Another вы

можете дублировать на экране окна Dump, File и Module.



Окна Object Inspector


Это окно используется для просмотра структуры и значений

конкретного экземпляра класса. Чтобы открыть данное окно, поместите курсор на конкретный экземпляр класса (в окне Module) и нажмите Ctrl+I.

[*] Inspecting tw 3 [^][v]

@75C6:01E8 ^

Screen::MaxX 500 (Ox1F4)

Screen::MaxY 512 (Ox200) v

< >

Screen::Convert @0000:0000

Screen::VertVtoA @0000:0000

Screen::VertAtoV @0000:0000

class TextWindow

Данное окно содержит три области. Область элементов данных

(верхняя) показывает текущие значения элементов данных объектов.

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

SpeedMenu верхних двух областей содержат идентичные команды,

только область элементов данных содержит дополнительную команду

Change.

Range

Позволяет вам задать диапазон выводимых элементов массива.

Если подсвеченный элемент не является массивом или указателем, то

команда недоступна.

Change

Позволяет изменить значение подсвеченного элемента данных.
Methods

Переключается между Yes (по умолчанию) и No. В состоянии Yes

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

Show Inherited

Также переключается между Yes и No. В состоянии Yes показываются все функции-элементы, определенные в классе и наследуемые.

No позволяет вывести только функции-элементы, определенные в

классе.

Inspect

Открывает для текущего подсвеченного элемента окно Inspector. Проверка функции-элемента открывает окно Module, где курсор

позиционируется на определяющий эту функцию код.

Descend

Работает аналогично команде Inspect SpeedMenu, но заменяет

текущее окно Inspector. Это уменьшает число открытых на экране

окон inspector.

New Expression

Используется для проверки различных выражений. Данные в текущем окне Inspector заменяются данными нового вводимого выражения.
Type Cast

Позволяет задавать для текущего подсвеченного элемента данные различного типа. Эта команда полезна, если идентификатор не

имеет информации о типе и для явного задания типа указателей.

Hierarchy

Открывает окно Hierarchy с наследованием текущего класса.



Окна-рамки


Окна-рамки (объекты класса TFrameWindow) - это специализированные окна, поддерживающие клиентное окно. Они составляют основу

окон-рамок MDI и SDI, дочерних окон MDI и (вместе с TLayoutWindow) декорированных окон-рамок. Окна-рамки играют в ObjectWindows

важную роль и используются для управления такими элементами как

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

не влияет.



Окна реквизитов


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

они не могут выставлять или принимать события, непосредственно

взаимодействовать с окнами или вызывать для себя функции Windows.

Все, что требуется делать реквизиту, должно выполняться через окно реквизитов.

Реквизит практически не может управлять своим расположением

в окне реквизитов. Окно реквизитов отвечает за размещение и расположение всех реквизитов, который оно содержит. Обычно реквизиты

располагаются в одну линию (вертикально или горизонтально).

Реквизиты обычно включаются в другое окно. Родительским окном окна реквизитов является как правило декорированное окно-рамка, такое как TDecoratedFrame или TDecoratedMDIFrame, хотя класс

TToolBox использует обычно TFloatingFrame.

В конструкторе TGadgetWindow задается указатель на объект

родительского окна, направление (горизонтальное и вертикальное),

указатель на объект шрифта TFont и параметр TModule базового

конструктора (по умолчанию 0). Функция ~TGadgetWindow удаляет

каждый из реквизитов окна реквизитов, а затем удаляет объект

шрифта.

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

начальный размер на основе следующих критериев:

Установлена ли для реквизитов в окне автоматическая настройка размера.

Размера реквизитов, содержащихся в окне.

Направления расположения реквизитов в окне.

Имеет ли окно реквизитов рамку, и размера этой рамки.

Функция Create определяет на основе этих факторов подходящий

размер окна, устанавливает размеры атрибутов окна, а затем для

создания интерфейсного элемента окна вызывает базовую функцию

TWindow::Create.

Чтобы окно реквизитов выполняло полезные функции, оно должно

содержать некоторые реквизиты. Чтобы поместить реквизит в окно,




используйте функцию Insert, в параметрах которой задаются ссылка

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

Если окно реквизитов уже создано, вам нужно после вызова Insert вызвать LayoutSession. Реквизит появится в окне после задания его схемы (LayoutSession).

Чтобы удалить из окна реквизит, используйте функцию Remove.

Сам объект реквизита она не удаляет. Чтобы реквизит исчез из окна, нужно вызвать LayoutSession.

Изменить поля и схемы окна можно перед его выводом или после. Для этого используйте функции SetMargins и SetDirection. Обе

эти функции устанавливают соответствующие элементы данных, а затем вызывают функцию LayoutSession. Направление вывода реквизитов

определяется с помощью функции GetDirection.

По умолчанию функция LayoutSession проверяет создание интерфейсного элемента. Если нет, то функция не выполняет никаких

действий. Если элемент окна уже создан, то LayoutSession выводит

реквизиты без перекрытия и запрещает модифицированной область.

Сеанс задания схемы обычно начинается изменением полей, вставкой

или удалением реквизитов или изменением окна реквизитов.

TileGadget определяет необходимое каждому реквизиту пространство и поочередно их размещает. TileGadget вызывает функцию

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

схему расположения.

Если реквизит изменяет размер, он должен вызывать для окна

реквизитов функцию GedgetChangedSize со ссылкой на реквизит с измененным размером. Заданная по умолчанию версия этой функции

просто инициализирует сеанс задания схемы.

С помощью функции SetShrinkWrap вы можете задать автоматическую настройку размера окна реквизитов. Автоматическую настройку горизонтального и вертикального размера определяют параметры shrinkWrapWidth и shrinkWrapHeight.

Определить текущий шрифт и его размер можно с помощью функций GetFont и GetFontHeight.

При нажатии в ограничивающем прямоугольнике левой кнопки



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

нужно перехватить нажатие кнопки. Это можно сделать с помощью

функций GedgetSetCapture и GadgetReleaseCapture. Эти функции

обычно вызываются реквизитом через указатель на окно реквизитов.

Режим подсказки реквизита указывает, будет ли выводиться в

родительском окне окна реквизитов информация о реквизите. Этот

режим устанавливается с помощью функции SetHintMode, параметр которой может иметь значения NoHints (подсказка не выводится),

PressHints (подсказка выводится при нажатии реквизита) и EnterHints (подсказка выводится при перемещении "мыши" на реквизит).

Определить текущий режим можно с помощью функции GetHintMode.

Вывод подсказки определяет функция SetHintCommand. Обычно

она вызывается реквизитом через указатель на окно реквизитов.

Чтобы эта функция правильно работала со стандартными классами ObjectWindows, нужно чтобы:

декорированное окно-рамка (родительское окно окна реквизитов) имело строку сообщений или строку состояния;

в окне-рамке должна быть разрешена подсказка;

должен существовать строковый ресурс с тем же идентификатором, что и реквизит.

Для поиска содержащихся в окне реквизитов вы можете использовать функции FirstGadget, NextGadget, GadgetFromPoint, GadgetWidthId.


Окна схемы


Окна схемы (разметки) инкапсулируют класс TLayoutWindow, инкапсулирующий производный от TWindow класс TLayoutWindow. Как и

TFrameWindow, TLayoutWindow создает основу для декорированных

окон-рамок и возможности упорядочения элементов в области рамки.

Окна схемы (или разметочные окна) называются так потому, что

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

другого дочернего окна ("братского" окна - окна равного уровня).

Расположение дочернего окна зависит от параметров схемы, которые

включат в себя ряд правил, описывающих координаты X и Y окон, их

высоту и ширину. Эти правила обычно основываются на координатах

братского окна и, в итоге, на размере и организации окна схемы.

Параметры схемы для дочерних окон содержатся в классе TLayoutMetrics. Объекты параметров схемы состоят из ряда ограничений

схемы. Каждое ограничение описывает правило определения конкретного изменения окна, например X-координаты или ширины окна. Эти

ограничения хранятся в структуре TLayoutConstraints, но обычно

используются производные от нее классы, такие как TEdgeConstraint.

Ограничения схемы определяют соотношение между краем или

размером одного окна и краем или размером братского или родительского окна схемы. Это соотношение может быть достаточно гибким.

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

Set, которая определяется в классе TEdgeConstraint и в результате

наследуется из TEdgeOrWidthConstraint и TEdgeOrHeightConstraint.

Параметр edge функции Set определяет, какую часть окна вы

ограничиваете. Для этого используется enum TEdge с 5 возможными

значениями:

lmLeft определяет левый край окна.

lmTop определяет верхний край окна.

lmRight определяет правый край окна.

lmBottom определяет нижний край окна.

lmCenter определяет центрирование окна (горизонтальное или

вертикальное).

С помощью enum TWidthHeight можно задать ограничение высоты




или ширины окна:

lmWidth задает, что ограничением должна быть ширина окна.

lmHeight задает, что ограничением должна быть высота окна.

rel задает соотношение между краями окна (lmAsis, lmPersentOf, lmAbove, lmLeftOf, lmBelow, lmRightOf, lmSameAs, lmAbsolute).

otherWin задает окно, содержащее ваше дочернее окно. Для

спецификации родительского окна используется lmParent.

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

value имеет разный смысл в зависимости от значения rel и

Units.

TEdgeConstraint содержит также ряд функций, которые вы можете использовать для задания предопределенных соотношений, тесно

связанных с теми, которые задаются в Set.

Для задания схемы окна недостаточно одного ограничения расположения. Например, указание того, что окно должно находиться на

10 элементов изображения ниже другого окна ничего не говорит о

высоте и ширине окна, расположении его левого или правого края

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

(X и Y), TEdgeOrWidthConstraint (Width) и TEdgeOrHeightConstraint

(Height).

TLayoutMetrics - достаточно простой класс. Его конструктор

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

После построения объекта TLayoutMetrics вам нужно задать ограничения схемы нужного окна. Для установки каждого ограничения

можно использовать соответствующую функцию.

Чтобы лучше понять, как совместно работают ограничения, выполните пример приложения LAYOUT из каталога примеров программ.

Его диалоговое окно позволяет изменить ограничения каждого из

окон и увидеть результаты. Однако ограничения нужно описывать

полностью. Неполное описание может приводить к аварийному завершению.


Окна Turbo Debugger


Для вывода информации об отлаживаемой программе в Turbo Debugger используется набор окон. Для облегчения отладки служат команды управления окнами, которые находятся в меню Window и System. Каждое открываемое окно имеет номер, указанный в его правом

верхнем углу. Нажатием клавиши Alt в сочетании с номером окна вы

можете активизировать любое из первых 9 окон. Список открытых

окон содержится в нижней половине меню Window. Чтобы открыть

конкретное окно, нажмите в меню Window цифру номера окна. Если

окон больше 9, в этом меню выводится команда Window Pick, выводящая меню окон.

Клавиша F6 (или команда Window Next) позволяет циклически

перемещаться по открытым на экране окнам. Окно может иметь несколько областей. Для перемещения между областями используйте клавиши Tab или Shift+Tab, либо Window Next. Курсор в областях перемещается с помощью стандартных клавиш перемещения курсора.

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

команды Window Size/Move и клавиш стрелок, либо сразу нажмите

Shift и сдвигайте окно стрелками. Для быстрого увеличения или

уменьшения окна выберите Window Zoom (F5) или щелкните "мышью" на

кнопке минимизации/максимизации в верхнем правом углу окна.

Если вы по ошибке закрыли окно, вернуться в последнее окно

можно с помощью команды Window Undo Close (Alt+F6). Когда программа затирает своим выводом экран операционной среды (при выключенном переключении экрана), вы можете очистить его с помощью

System Repaint Desktop. Для возврата к используемой по умолчанию

схемы окон Turbo Debugger выберите System Restore Standard.

Каждое окно Turbo Debugger имеет специальное оперативное меню SpeedMenu, содержащее команды, относящиеся к данному окну. Области окон также могут иметь свои меню. Для доступа к SpeedMenu

активного окна или области вы можете нажать в окне правую кнопку

"мыши", либо нажать клавиши Alt+F10, либо нажать Ctrl и подсвеченную букву команды SpeedMenu (для этого должно быть разрешено

действие команд-сокращений).



Окно Breakpoints


Используется для установки, модификации или удаления точек

останова. Точка останова определяет то место в программе, где отладчик приостанавливает выполнение программы. Это окно имеет две

области. Справа перечислены условия и действия точек останова,

слева - все точки останова.



Окно Breakpoints


Создать окно точек останова Breakpoints можно с помощью команды View Breakpoints основного меню. Это дает вам способ выбора

и установки условий, при которых срабатывает точка останова. Это

окно можно использовать для добавления новых точек останова, отмены (удаления) точек останова и изменения существующих точек останова.

[*] Breakpoints 3 [^][v]

TCDEMO.220 Breakpoint

TCDEMO.225 Always

TCDEMO.226 Enabled

< >

В левой области этого окна показан список всех адресов, где

установлены точки останова. В правой области показаны подробные

данные по текущим (подсвеченным в левой области) точкам останова.

Локальное меню SpeedMenu окна Breakpoints можно получить по

нажатию клавиш Alt+F10. Команды данного меню позволяют вам добавлять новые точки останова, отменять существующие или изменять характер поведения имеющихся точек останова.



Окно Clipboard


Буфер Clipboard отладчика используется для для вырезания и

вставки элементов из одного окна отладчика в другое. Оно показывает вырезанные элементы и их типы. Скопированные в буфер элементы динамически обновляются.



Окно CPU


Выводит текущее состояние процессора. Окно имеет 6 областей,

где выводятся дизассемблированные инструкции, селекторы Windows

(только в TDW), шестнадцатиричные данные, стек в шестнадцатиричном виде, регистры ЦП и флаги процессора. Это окно полезно использовать при отладке программ на ассемблере или просмотре точно последовательности инструкций.



Окно CPU


Это окно открывается командой View CPU строки меню и использует различные области для описания состояния вашей программы на

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

просмотра машинного кода и дизассемблированных инструкций

программы;

проверки и модификации байт структур данных программы;

тестирования исправления ошибок с помощью встроенного ассемблера в области кода.

область регистров

область кода область стека

[*] CPU 80486 3 [^][ ]

TCDEMO.120: Inc(NumLines); ^ ax 0004 c=0

cs:04C4:4F36063000 inc word ptr [TPDEMO bx 3EEE z=0

TCDEMO.121 i := 1; cx 0000 s=0

cs:04C8 C:43FE0100 word ptr [bp+02].000 dx 5920 o=0

TCDEMO.122: while i <= Length(S) do si 3CEC p=0

cs:04C0 C47ED4 les di,[bp+04] bp 3EF4 a=0

cs:0400 288A05 mov al,es:[di] sp 3EF4 i=1

cs:0403 3D84 xor ah,ah ds 5920 d=0

cs:0405 3B48FE cmp ax,[bp+02] es 5920

cs:0408 7D03 jnl TPDEMO.125 (04DD) ss 595A

cs:040A 898A00 jmp TPDEMO.148 cs 548A

TCDEMO.125 while (i <= Length(S)) and notv ip 04C8

< >

ds:0008 5A 5D 5A 5D 5A 5D 00 00 Э^$< < ss:3EF2 548A

ds:0010 00 00 00 00 00 00 5A 5D 6D vЖ ss:3EF0>04C1

ds:0018 00 00 5A 5D 00 00 00 90 7 ss:3EEE 0246

область дампа область стека

Область кода показывает машинный код и дизассемблированные

машинные инструкции вашей программы. Здесь могут также выводиться

строки исходного кода. В области регистров выводится содержимое

регистров ЦП. В области флагов показывается состояние 8 флагов

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

Для адресных ссылок вне текущего сегмента в окне CPU выводятся знаки вопроса. Клавиша Ctrl в сочетании со стрелками позволяет сдвигать вывод на 1 байт. При выполнении кода Windows, модуля без отладочной информации, остановке программы на инструкции

внутри строки исходного кода или при трассировке инструкций с помощью Alt+F7 окно CPU выводится автоматически.



Окно Dump


Выводит в шестнадцатиричном виде содержимое любой области

памяти (аналогично области окна CPU). Команды SpeeMenu этого окна

позволяют вам модифицировать данные и работать с блоками памяти.



Окно Dump


В этом окне выводится в непосредственном виде дамп любой области памяти. Оно работает так же, как область данных окна CPU.

[*] Dump 3 [^][v]

ds:0000 CD 20 00 A0 00 9A F0 FE = & U** ^

ds:0008 1B 02 B2 01 22 31 7C 01 <.^% .`

ds:0010 22 31 88 02 52 2B E2 1D * X 4-#

ds:0018 01 01 01 00 03 FF FF FF v

< >

С помощью команды View Another Dump вы можете одновременно

открыть несколько окон Dump.



Окно Execution History


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

выполнения.



Окно File


Выводит содержимое любого файла на диске. В нем можно просматривать шестнадцатиричные байты или текст ASCII и искать нужные

байтовые последовательности.



Окно Hierarchy


Выводит на экран дерево иерархии всех используемых текущим

модулем классов. Имеет область списка классов и дерева иерархии.

Это окно показывает взаимосвязь используемых в модуле классов.



Окно Hierarchy


Окно Hierarchy (открываемое командой View Hierarchy) служит

для проверки иерархии объектов или классов, которая выводится в

графическом виде.

Область классов Область иерархии

[*] Class Hierarchy 3 [^][v]

Devi e Point

GlowGauge Rectangle

HorzArrow Device

HorzBar TextWindow

LinearGauge Range

Point Device

Range GlowGauge

Rectangle

Screen Parents of Device

TextWindow Range

VertArrow Rectangle

VertBar Point

Screen

< >



Окно Log


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

об использовании памяти, модулях и оконных сообщения приложения

Windows.



Окно Log


Это окно отслеживает события, происходящие во время сеанса

отладки. Открывается оно по команде View Log и по умолчанию содержит до 50 строк текста (вы можете изменить это с помощью программы инсталляции).

[*] Log 3 [^][v]

At MCINPUT.124 ^

Breakpoint at TCDEMO.220

Breakpoint at TCDEMO.220

Breakpoint at TCDEMO.220

We are now entering procedure Params...

Breakpoint at TCDEMO.180 v

< >

В это окно записываются:

адрес программы при ее приостановке;

комментарий (при использовании команды Add Comment данного

окна);

значение выражения, определенного для активизированной

точки останова;

содержимое области или окна при выборе команды Edit Dump

to Log.

информация о локальной и глобальной динамической распределяемой памяти или список программных модулей (при выборе

команды Display Windows Info локального меню данного окна);

при установке в Yes параметра Send to Log Window окна Windows Messages в окно Log передаются все посылаемые данному

окну сообщения.

Команды SpeedMenu окна Log позволяют вам записывать журнал в

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

Open Log File

Эта команда записывает на дик все записи, регистрируемые в

окне Log. Вам выводится подсказка для ввода имени файла на диске.

По умолчанию он имеет расширение .LOG, а его имя соответствует

имени программы. При открытии файла в него записываются все уже

зарегистрированные записи. Если это нежелательно, выберите сначала команду Erase Log.

Close Log File

Закрывает файл, открытый с помощью команды Open Log File.
Logging

Разрешает/запрещает запись событий в окно Log. Используется

для управления регистрацией событий.

Add Comment

Позволяет включить в окно Log комментарии. Открывает диалоговое окно с подсказкой для ввода комментария.
Erase Log

Очищает окно Log. Файл журнала на диске не изменяется.
Display Windows Info

Доступна только для TDW и выводит на экран окно Windows Information. Позволяет вывести информацию о динамически распределяемой памяти и список модуля приложения.



Окно Module


Одно из важнейших окон Turbo Debugger, показывающее исходный

код отлаживаемого программного модуля (включая DLL). Модуль должен компилироваться с отладочной информацией.



Окно Numeric Processor


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

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

См. файл TD_ASM.TXT.



Окно Registers


Показывает содержимое регистров (в области регистров) и флагов ЦП (в области флагов). С помощью команд SpeedMenu вы можете

изменить их значения.



Окно Registers


В окне Registers выводится содержимое регистров и флагов

центрального процессора. оно работает, как сочетание областей регистров и флагов в окне CPU и имеет те же команды.

Назад | Содержание | Вперед



Окно сообщений


При компиляции программ в окне сообщений выводятся ошибки и

предупреждения. С помощью команды Preferences в диалоговом окне

Enviroment Options вы можете настроить некоторые функциональные

возможности окон сообщений Message.

При выборе сообщения в окне Message редактор помещает курсор

в ту точку исходного кода, где произошла ошибка или предупреждение. Если файл с ошибкой не загружен в окне редактора, для его

загрузки нажмите пробел (можно воспользоваться и SpeedMenu). Окно

сообщений остается выбранным, так что вы можете перемещаться от

сообщения к сообщению. С помощью команды Remove all messages оперативного меню вы можете очистить окно сообщения. Клавиши Alt+F7

выводят следующее сообщение об ошибке, а Alt+F8 - предыдущее.



Окно Stack


Показывает текущее состояние программного стека. Первая вызванная функция показывается в нижней части окна, а выше ее - каждая последующая. Подсвечивая эти функции и нажимая Ctrl+I вы можете проверять исходный код. Кроме того, можно открыть окно Variables и вывести все локальные переменные и аргументы функции (Ctrl+L).



Окно Stack


Это окно позволяет проанализировать стек вызова и вывести в

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

функций. Первой в списке указывается последняя вызванная процедуры, за которой следует вызвавшая ее процедура и предыдущая процедура, и так до самой первой функции программы (функция main в

Си). Это окно выводит также имена функций-элементов, перед которой указывается имя класса. При рекурсивном вызове окно Stack содержит несколько экземпляров функции.

[*] Stack 3 [^][v]

TCDEMO.PROCESSLINE.ISLETTER('A')

TCDEMO.PROCESSLINE('ABCDEF')

< >

SpeedMenu окна Stack содержит две команды: Ispect и Locals.

Команда Inspect открывает окно Module и позиционирует курсор на

активную строку подсвеченной функции. Если подсвеченная функция

находится в вершине стека вызова (последняя вызванная функция),

то в окне Module показывается положение счетчика команд. В противном случае курсор позиционируется на строку после вызова соответствующей функции. Вызвать эту команду можно также нажатием Enter после подстветки нужной функции. Команда Locals открывает окно Variables с идентификаторами, локальными для текущего модуля и

подсвеченной функции.



Окно Variables


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

- локальные. Это полезно использовать для поиска функции или

идентификатора, имени которых вы точно не помните.



Окно Variables


В этом окне, которое открывается по команде View Variable,

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

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

[*] Variables 3 [^][v]

TCDEMO.SHORESULTS @7129:01fA

TCDEMO.INIT @7129:0402

TCDEMO.PROCESSLINE @7129:04B5

TCDEMO.PARMSONHEAP @7129:0651

TCDEMO.NUMLINES 1 ($1)

TCDEMO.NUMWORDS 0 ($0)

< >

CH 'A'

ISLETTER True

S 'ABC DEF'

I 1 ($1)

WORDLEN 28969

Окно имеет две области. Область глобальных переменных (вверху), показывает все глобальные идентификаторы программы. Область

статических/локальных переменных (внизу) показывает все статические переменные (идентификаторы) текущего модуля. В обеих областях

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

то он выводит четыре вопросительных знака (????).

Меню окна Variables

Каждая область окна Variables имеет собственное SpeemMenu.

Оба меню содержат команды Inspect, Change и Wathes, а команда

Show имеется только в области локальных идентификаторов.

Inspect

Открывает окно Inspector, где выводится содержимое подсвеченного идентификатора. В отличие от обычных окон Inspector, если

вы проверяете глобальную переменную, имя которой совпадает с именем локальной переменной, то Turbo Debugger выводит значение глобальной переменной. При проверке имени функции активизируется окно Module, а курсор перемещается на имя этой функции в исходном

коде (при его отсутствии выводится окно CPU).

Change

Открывает диалоговое окно Change, в котором можно изменит

значение подсвеченного идентификатора.

Watch

Открывает окно Watches и добавляет в него подсвеченный идентификатор. При этом не отслеживается, глобальная это переменная

или локальная. В блоке локальной переменной локальная переменная

имеет старшинство.

Show

Выводит диалоговое окно Local Display. Кнопки с зависимой

фиксацией этого окна позволяют разрешить или изменить область

действия переменной в области локальных переменных.

Show Показывать только статические переменные.
Auto Только переменные, локальные для текущего блока.
Both И статические, и локальные (по умолчанию).
Module Смена текущего модуля. Выводит диалоговое окно со

списком модулей программы.



Окно Watches


Показывает значения переменных и выражений. Введя в это окно

выражения, вы можете отслеживать их значения при выполнении программы. Окно добавляется с помощью клавиш Ctrl+W при установке курсора на переменной в окне Module.



Окно Watches


Это окно обеспечивает самый простой способ отслеживания элементов данных программы. В нем вы можете просматривать переменные

и выражения, значения которых нужно отслеживать.

[*] Watches 2 [^][v]

wordcount unsigned int 8 (Ox8) ^

wordcounts unsigned int [10] {1,2,4,6,1,1,2,0,0,0}

lettersinfo struct linfo [26] {(4,2),(1,1),(0,0),(1,1),(7,0),(.

nlines*nwords unsigned int 24 (Ox22)

totalcharacters unsigned long 88L (Ox42) v

< >

Это окно допускает просмотр значений как простых переменных,

так и составных объектов данных (например, массивов). Элементы

составных объектов выводятся в фигурных скобках ({}). Можно также

отслеживать выражения, не ссылающиеся непосредственно на память.

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

Чтобы задать отслеживаемые данные, выберите команду Data Add

Watch, либо команду Watch локального меню окна Module, Variable

или Watches. Turbo Debugger открывает диалоговое окно Enter Expression to Watch. Введите в нем имя переменной или выражение.

Если в окне Module курсор находится на переменной, то она

автоматические добавляется в окно Watch при выборе окна Wathes в

SpeedMenu. Это же относится к выражениям, выделенными с помощью

клавиш Ins и стрелок.

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

вводить аккуратно (Turbo Debugger не распознает ошибок).

При трассировке внутри функции-элемента можно использовать

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



Окно Windows Messages


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



Оконные объекты


Оконные объекты - это интерфейсные объекты высокого уровня,

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

оконных объектов:

Окна схемы.

Окна-рамки.

Декорированные окна-рамки.

Окна MDI.

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



Операции в команде


В дополнение к операциям переназначения <, > и >>, утилита

MAKE добавляет операции << и &&. Эти операции для создания подаваемых на вход команды данных создают в оперативном порядке файл.

Операция << создает временный файл и переназначает поток стандартного ввода команды таким образом, что он поступает из созданного файла. Если у вас имеется программа, которая допускает ввод

данных из потока stdin, то команда:

MYPROG <<!

Это лишь тест

!

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

\n", переопределяя ее как единственный поток входной информации

для программы myрrog. Восклицательный знак (!) представляет собой

в данном примере разделитель; в качестве разделителя для этого

файла можно использовать любой символ за исключением символов #

или \. Первая строка, начальным символом которой является символ

разделителя, завершает файл. Остальная часть строки, следующая за

символом разделителя (в данном примере, восклицательным знаком)

считается часть предшествующей команды.

Операция && аналогична операции <<. Он создает временный

файл, но вместо того, чтобы сделать этот файл стандартным потоком

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

приведенном ниже примере показывается, как создать "файл подсказки" для утилиты TLINK.

MYPROG.EXE: $(MYOBJS)

tlink /c @&&!

COS $(MYOBJS)

$*

$*

$(MYLIBS) EMU.LIB MATHS.LIB CS.LIB

Заметьте, что макрокоманда (которая обозначается с помощью

знака $) расширяется при создании файла. $* заменяется именем

создаваемого файла без расширения, а $(MYOBJS) и $(MYLIBS) заме-

няются значениями макрокоманд MYOBJS и MYLIBS. Таким образом, для

TLINK файл будет выглядеть следующим образом:

COS a.obj b.obj c.obj d.obj

MYPROG

MYPROG

w.lib x.lib y.lib z.lib EMU.LIB MATHS.LIB CS.LIB

Если не используется параметр командной строки -K, то все

временные файлы удаляются. Параметром -K следует пользоваться для

"отладки" временных файлов, если возникает впечатление, что эти

файлы работают неверно.



Операции ввода-вывода с плавающей точкой


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

Чтобы уменьшить размер выполняемого файла, форматы с плавающей

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

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

в результате ошибку ввода-вывода. Правильно оформить программу

можно, например, следующим образом:

/* Подготовка к выводу чисел с плавающей точкой */

#include <stdio.h>

#pragma extref _floatconvert

void main() {

printf(*d = %f\n", 1.3);

}



Оперативная помощь


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

сообщения об ошибке или подсказки. Для вывода справочного экрана

с информацией, относящийся к текущему контексту (окну или меню)

нажмите клавишу F1. При наличие "мыши" вы можете вывести справочный экран, выбрав F1 в строке состояния. Некоторые справочные экраны содержат подсвеченные слова, которые позволяют вам получить

дополнительную информацию по данной теме. Для перемещения к нужным ключевым словам используйте клавиши Tab или Shift+Tab и нажмите клавишу Enter. Для перемещения к первому или последнему слову на экране используйте клавиши Home и End. Доступ к оперативным

справочным средствам можно получить также с помощью команды Help

из строки меню (оперативные клавиши Alt+H).

Если вы хотите вернуться к предыдущему справочному экрану,

нажмите клавиши Alt+F1 или выберите команду Previous из меню

Help. В справочной системе для просмотра последних 20 экранов

можно пользоваться клавишей PgUp (клавиша PgDn работает, когда вы

находитесь в группе связанных экранов). Для доступа к индексному

указателю справочной системы нажмите Shift+F1 (или F1 в справочной системе) или выберите команду Index в меню Help. Для получения информации о самой справочной системе выберите в меню Help

команду Help Help. Для выхода из справочной системы нажмите клавишу Esc.

При работе в отладчике в нижней части экрана выводится краткая справочная строка. В этой строке состояния кратко описаны

клавиши или команды меню для текущего контекста.



Оператор CODE


Оператор CODE определяет стандартные атрибуты сегментов кода. Сегменты кода могут иметь любое имя, но должны принадлежать

классам сегментов, имена которых оканчиваются на CODE. Например,

корректными именами классов сегментов являются CODE и MYCODE.

Оператор имеет следующий синтаксис:

Для TLINK:

CODE [FIXED MOVEABLE]

[DISCARDABLE NONDISCARDABLE]

[PRELOAD LOADONCALL]

Для TLINK32:

[PRELOAD LOADONCALL]

[EXECUTEONLY EXECUDEREAD]

FIXED означает, что сегмент занимает фиксированное положение

в памяти; MOVEABLE означает, что сегмент может перемещаться.

DISCARDABLE означает, что сегмент может отбрасываться, если

он больше не нужен. DISCARDABLE подразумевает MOVEABLE.

NONDISCARDABLE означает, что сегмент не может отбрасываться.

PRELOAD означает, что сегмент загружается при первой загрузке модуля; LOADONCALL означает, что сегмент загружается, когда

вызывается код, находящийся в этом сегменте. Компилятор ресурсов

и загрузчик Windows устанавливают сегмент кода, содержащий начальную точку входа в программу, в значение PRELOAD независимо от

содержания файла определения модуля.

EXECUTEONLY означает, что сегмент кода может быть только выполняемым. EXECUTEREAD означает, что сегмент кода может считываться и выполняться.



Оператор DATA


Оператор DATA определяет стандартные атрибуты сегментов данных и имеет синтаксис:

DATA [NONE SINGLE MULTIPLE]

[READONLY LOADCALL]

[PRELOAD LOADONCALL]

[SHARED NONSHARED]

NONE означает отсутствие сегмента данных. Если задается

NONE, то другие параметры использовать нельзя. Этот параметр

используется только для библиотек.

READONLY означает, что сегмент данных может только считыватьcя. READWRITE означает чтение и запись в сегмент данных.

PRELOAD означает, что сегмент данных загружается при первой

загрузке модуля. LOADONCALL (по умолчанию) означает, что сегмент

данных загружается при первом обращении (для 32-разрядных приложений это игнорируется).

SHARED (по умолчанию для 16-разрядных приложений) означает,

что одна копия сегмента данных совместно используется всеми процессами. NONSHARED (по умолчанию для программ и 32-разрядных DLL)

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



Оператор DESCRIPTION


DESCRIPTION вставляет текст в модуль прикладной программы.

Оператор DESCRIPTION обычно используется для вставки автора, даты

или информации о копировании. Оно является необязательным параметром. Оператор имеет синтаксис:

DESCRIPTION 'текст'

где "текст" является строкой ASCII, разделенной одинарными кавычками.



Оператор EXETYPE


EXETYPE задает стандартный тип заголовка (Windows или OS/2)

выполняемого файла (.EXE) для 16-разрядных приложений. В 32-разрядных приложениях для обратной совместимости этот оператор можно

сохранить. В данной версии Borland C++ можно задавать только значение WINDOWS. Оператор имеет синтаксис:

EXETYPE WINDOWS