Поделиться через


Соглашения о написании кода Windows

Если вы не знакомы с программированием для Windows, это может быть смущает, когда вы впервые увидите программу Windows. Код заполняется странными определениями типов , такими как DWORD_PTR и LPRECT, а переменные имеют такие имена, как hWnd и pwsz (венгерская нотация). Стоит уделить некоторое время изучению некоторых соглашений о кодировании Windows.

Подавляющее большинство API Windows состоит из функций или интерфейсов COM. Очень немногие API Windows предоставляются в виде классов C++. (Заметным исключением является GDI+, один из интерфейсов API двухмерной графики.)

Определения типов

Заголовки Windows содержат много типов. Многие из них определены в файле заголовка WinDef.h. Вот некоторые из них, с которыми вы часто столкнетесь.

Целочисленные типы

Тип данных Размер Подписал?
BYTE 8 бит Без знака
DWORD 32 бита Без знака
INT32 32 бита Со знаком
INT64 64 бита Со знаком
LONG 32 бита Со знаком
LONGLONG 64 бита Со знаком
UINT32 32 бита Без знака
UINT64 64 бита Без знака
ULONG 32 бита Без знака
ULONGLONG 64 бита Без знака
WORD 16 бит Без знака

Как видите, в этих типах имеется определенная избыточность. Некоторые из этих перекрытий просто связаны с историей API Windows. Перечисленные здесь типы имеют фиксированный размер, а размеры одинаковы как в 32-разрядных, так и в 64-разрядных приложениях. Например, тип DWORD всегда имеет ширину 32 бита.

Логический тип

BOOL — это псевдоним типа для int, отличный от bool C++, а также от других типов, представляющих логическое значение. Файл заголовка WinDef.h также определяет два значения для использования с BOOL.

#define FALSE    0 
#define TRUE     1

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

// Right way.
if (SomeFunctionThatReturnsBoolean()) 
{ 
    ...
}

// or

if (SomeFunctionThatReturnsBoolean() != FALSE)
{ 
    ...
}

а не это:

if (result == TRUE) // Wrong!
{
    ... 
}

BOOL — это целочисленный тип, который не является взаимозаменяемым с логическим значением C++.

Типы указателей

Windows определяет множество типов данных формы, указывающих на X. Обычно они имеют префикс P- или LP- в имени. Например, LPRECT — это указатель на RECT, где RECT — это структура, описывающая прямоугольник. Следующие объявления переменных эквивалентны.

RECT*  rect;  // Pointer to a RECT structure.
LPRECT rect;  // The same
PRECT  rect;  // Also the same.

В 16-разрядных архитектурах (16-разрядная версия Windows) существует 2 типа указателей: P — "указатель", а LP — "длинный указатель". Длинные указатели (также называемые дальними указателями) были необходимы для обращения к диапазонам памяти за пределами текущего сегмента. Префикс LP был сохранен, чтобы упростить перенос 16-разрядного кода в 32-разрядную версию Windows. Сегодня различий нет, и все эти типы указателей эквивалентны. Избегайте использования этих префиксов; или, если вы должны использовать один, используйте P.

Типы точности указателя

Следующие типы данных всегда имеют размер указателя, то есть 32 бита в ширину в 32-разрядных приложениях и 64 бита в ширину в 64-разрядных приложениях. Размер определяется во время компиляции. Если 32-разрядное приложение работает в 64-разрядной версии Windows, эти типы данных по-прежнему имеют ширину 4 байта. (64-разрядное приложение не может работать в 32-разрядной версии Windows, поэтому обратная ситуация не возникает.)

  • DWORD_PTR
  • INT_PTR
  • LONG_PTR
  • ULONG_PTR
  • UINT_PTR

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

Венгерская нотация

Венгерская нотация — это практика добавления префиксов к именам переменных для получения дополнительных сведений о переменной. (Изобретатель нотации, Чарльз Simonyi, был венгерским, отсюда и ее название).

В первоначальном виде венгерская нотация предоставляет семантическую информацию о переменной, сообщая о предполагаемом использовании. Например, i означает индекс, cb означает размер в байтах ("количество байтов"), а rw и col — средние номера строк и столбцов. Эти префиксы предназначены для предотвращения случайного использования переменной в неправильном контексте. Например, если бы вы увидели выражение rwPosition + cbTable, вы бы знали, что номер строки добавляется к размеру, что почти наверняка является ошибкой в коде.

Более распространенная форма венгерской нотации использует префиксы для предоставления сведений о типе , например dw для DWORD и w для WORD.

Примечание

Основные рекомендации C++ не рекомендуют нотацию префикса (например, венгерскую нотацию). См . раздел NL.5. Избегайте сведений о типе кодирования в именах. На внутреннем сервере команда Windows больше не использует его. Но его использование остается в примерах и документации.

Следующая

Работа со строками