Ну, вот с базисом мы покончили и пора приступить к более полезным и практическим примерам. В качестве примера выберем поиск папок и файлов. Пример был разработан для FAQ конференции fido7.ru.delphi, в дальнейшем был немного модернизирован по замечаниям от Юрия Зотова. Полный пример и остальные статьи из FAQ доступны для загрузки с моего .
procedure ScanDir(StartDir: string; Mask:string; List:TStrings); var SearchRec : TSearchRec; begin if Mask = '' then Mask := '*.*'; if StartDir[Length(StartDir)] <> '\' then StartDir := StartDir + '\'; if FindFirst(StartDir + Mask, faAnyFile, SearchRec) = 0 then begin repeat Application.ProcessMessages; if (SearchRec.Attr and faDirectory) <> faDirectory then List.Add(StartDir + SearchRec.Name) else if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin List.Add(StartDir + SearchRec.Name + '\'); ScanDir(StartDir + SearchRec.Name + '\', Mask, List); end; until FindNext(SearchRec) <> 0; FindClose(SearchRec); end; end; Рассмотрим ключевые моменты, относящиеся к данной статье. if FindFirst(StartDir + Mask, faAnyFile, SearchRec) = 0 then
Здесь является битовой маской, описанной в модуле SysUtils, ее значение равно $3F, она предназначена для включения в поиск специальных файлов и одновременно для изоляции лишних бит из структуры TsearchRec, отдельные биты данной маски описаны как именованные константы.
Наименование
Значение
Описание
FaReadOnly
$00000001
Read-only files
Файлы с защитой от записи
faHidden
$00000002
Hidden files
Невидимые файлы
faSysFile
$00000004
System files
Системные файлы
faVolumeID
$00000008
Volume ID files
Метка тома
faDirectory
$00000010
Directory files
Папки
faArchive
$00000020
Archive files
Архивные файлы (для системы архивации)
faAnyFile
$0000003F
Any file
Все файлы - комбинация выше указанных флагов
if (SearchRec.Attr and faDirectory) <> faDirectory
здесь мы видим проверку флага faDirectory, работает это следующим образом, сначала изолируются не нужные биты, затем проводится проверка на неравенство нулю, поскольку все остальные биты изолированы, то возможны только два значения, ноль, если флаг не установлен и не ноль установлен, в зависимости от результата выполняется, или часть THEN, или часть ELSE. Других вещей касаемо нашей статьи в примере нет и поэтому рассматривать больше нечего. Прочие логические операции работают с булевыми, а не с битовыми значения.
В заключение статьи можно еще привести примеры использования масок для изоляции битов и выполнения операций над оставшимися битами, возьмем для примера какую ни будь абстрактную комбинацию бит и выполним, что ни будь с ними.
Например, у нас есть такая структура некоторого устройства, и при поступлении данных происходит прерывание, обработка которого поступает в наш обработчик и в другие вместе с кодом состояния, если мы обработали сообщение, то мы должны возвратить значение TRUE, если то FALSE и тогда управление будет передано следующему в цепочке обработчику. Бит TxReady проверять не надо, управление будет поступать, только тогда когда он установлен.
abcccddd - где
a - бит готовности
b - бит разрешения прерывания
ccc - тип операции
ddd - счетчик
function MyHandler(Code: byte): Boolean; const TxReady = $80; IntBit = $40; TypeMask = $38; CounterMask = $07; var I: Integer; TypeBits: Byte; begin if (Code and Intbit) = Intbit then begin // изоллируем биты типа и смещаем вправо для дальнейшей обработки TypeBits := (Code and TypeMask) shr 3; Case TypeBits of 0: begin for I := 1 to (Code and CounterMask) do begin считываем N данных, количесво указано в битах CounterMask, которые мы изолировали и использовали в качестве значения для окончания цикла. end; Result := TRUE; // обрабатали, пусть больше никто не трогает end; 1: begin команда 1, что то делаем Result := TRUE; // обрабатали, пусть больше никто не трогает end; 2: begin команда 2, что то делаем Result := TRUE; // обрабатали, пусть больше никто не трогает end; else Result := FALSE; // другие команды не наше дело end; end else begin Result := FALSE; // пусть другой обрабатывает end; end;