Разработчики Delphi не стали полностью копировать этот механизм, видимо, этому помешала существующая в Delphi раздельная компиляция модулей, из-за которой невозможно определением одного символа заставить все модули перекомпилироваться (тем более что часть из них может не иметь исходных кодов). Поэтому в Delphi нет типа, аналогичного TCHAR
.
Рассмотрим, как та же функция RegisterWindowMessage
импортируется модулем Windows (листинг 1.19).
RegisterWindowMessage
interface
…
function RegisterWindowMessage(lpString: PChar): UINT; stdcall;
function RegisterWindowMessageA(lpString: PAnsiChar): UINT;
stdcall; function RegisterWindowMessageW(lpString: PWideChar): UINT; stdcall;
…
implementation
…
function RegisterWindowMessage;
external user32 name 'RegisterWindowMessageA';
function RegisterWindowMessageA;
external user32 name 'RegisterWindowMessageA';
function RegisterWindowMessageW;
external user32 name 'RegisterWindowMessageW';
Видно, что функция RegisterWindowMessageA
импортируется дважды: один раз под своим настоящим именем, а второй раз — под именем RegisterWindowMessage
. Любое из этих имен подходит для вызова ANSI-варианта этой функции (напоминаю, что типы PChar
и PAnsiChar
эквивалентны). Чтобы вызвать Unicode-вариант функции, потребуется функция RegisterWindowMessageW
.
Структуры, содержащие строковые данные, также имеют ANSI- и Unicode-вариант. Например, структура WNDCLASS
в модуле Windows представлена типами TWndClassA
(с синонимами WNDCLASSA
и tagWNDCLASSA
) и TWndClassW
(с синонимами WNDCLASSW
и tagWHDCLASSW
). Тип TWndClass
(и его синонимы WNDCLASS
и tagWNDCLASS
) эквивалентен типу TWndClassA
. Соответственно, при вызове функций RegisterClassA
и RegisterClassExA
используется тип TWndClassA
, при вызове RegisterClassW
и RegisterClassExW
— тип TWndClassW
.
1.1.13. Строки в Windows API
Unicode в Delphi встречается редко, т. к. программы, использующие эту кодировку, не работают в Windows 9x/МЕ. Библиотека VCL также игнорирует возможность работы с Unicode, ограничиваясь ANSI. Поэтому далее мы будем говорить только об ANSI. С кодировкой Unicode можно работать аналогично, заменив PChar
на PWideChar
и string
на WideString
.
Для работы со строками в Delphi наиболее распространен тип AnsiString
, обычно называемый просто string
(более детально отношения между этими типами рассмотрены вstring
является указателем на строку, хранящуюся в динамической памяти. Этот указатель указывает на первый символ строки. По отрицательному смещению хранится число символов в строке и счетчик ссылок, который позволяет избежать ненужных копирований строки, реализуя так называемоеLength
он игнорируется). Но если присвоить строковой переменной пустую строку, то эта переменная станет нулевым указателем (nil
), память для хранения одного символа #0 выделена не будет. При выходе строковой переменной из области видимости (т. е., например, при завершении процедуры, в которой она является локальной переменной, или при уничтожении объекта, полем которого она является) она автоматически финализируется, т. е. счетчик ссылок уменьшается на единицу и, если он оказывается равен нулю, память, выделенная для строки, освобождается. (О внутреннем устройстве AnsiString
см. также