Написание переносимого кода 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 позволяет:
возвращаемого значения;
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.
В IDE используйте команду
Options Compiler Messages Display All. В BCC32 укажите
параметр -w.
STRICT с помощью #define или использовать в командной
строке параметр -DSTRICT.
Перечислим некоторые рекомендации, которые могут оказаться
полезными при преобразовании вашего программного кода в соответствии со STRICT:
хотите получить 16-битовое значение на 32-разрядной платформе).
с помощью подходящего типа функции, а не с помощью
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);
ядра, осуществляющие управление модулями, обычно используют HINSTANCE, но некоторые API возвращают или воспринимают
только HMODULE.
WINDOWS.H, они могут быть изменены, и ваши описания могут
оказаться устаревшими. Удалите локальные описания.
приводиться к LOCALHANDLE или GLOBALHADLE.
SendDlgItemMsg или любых других функций, которые возвращают LRESULT или LONG к какому-либо описателю вы должны сначала привести результат к UINT:
HBRUSH hbr;
hbr = (HBRUSH)(UINR)
SendMessage(hwnd WM_CTLCOLOR, ..., ...);
идентификатора. В этом случае вы должны привести тип к
HMENU:
HWND hwmd;
int id;
hwnd = CreateWindow("Button", "Ok", BS_PUSBUTTON,
x, y, cx, cy, hwndParent,
(HMENU)id, // здесь требуется приведение типа
hinst, NULL);
FAR*) следует возможно скорее присваивать переменным. Избегайте использовать их в своих программах, когда тип значения известен. Это минимизирует число потенциально небезопасных и непереносимых в 32-разрядный режим преобразований типов. Макрокоманды API и механизмы обработки сообщений, предусмотренные в windowsx.h, будут выполнять практически всю упаковку и распаковку этих типов данных способом, обеспечивающим переносимость в 32-разрядный режим.
компилятора, которые вы можете обнаружить при переходе к
STRICT.