Delphi. Трюки и эффекты - страница 46

Шрифт
Интервал

стр.

4.3. Файлы

В завершение главы рассмотрим три несложных примера работы с файлами: копирование файла (с отображением хода копирования в ProgressBar), определение значков, ассоциированных с файлами, и извлечение значков из ЕХЕ– и DLL-файлов.

Красивое копирование файла

Казалось бы, что особенного в организации копирования большого файла с отображением процесса: читай файл порциями, записывай прочитанные данные в файл назначения, попутно показывая в ProgressBar или где-то еще отношение объема переписанной информации к размеру файла. Однако зачем такие сложности? Ведь у API-функции CopyFi 1е, осуществляющей простое копирование файла, есть расширенный вариант – функция CopyFileEx, в которую встроена поддержка отображения процесса копирования (и не только это). Вот прототип функции CopyFileEx:

...

function CopyFileEx(lpExistingFileName, lpNewFileName: PChar;

lpProgressRoutine: TFNProgressRoutine; lpData: Pointer;

pbCancel: PBool; dwCopyFlags: DWORD): BOOL; stdcall;

Итак, кроме пути исходного и конечного файлов, а также флагов (последний параметр), функция принимает ряд дополнительных параметров: адрес функции обратного вызова (IpProgressRoutine), указатель на данные, передаваемые в функцию обратного вызова (lpData), а также адрес переменной типа BOOL (pbCancel), при установке значения которой в True копирование прерывается.

Пример использования функции CopyFileEx в программе приведен в листинге 4.32. Здесь подразумевается, что кнопка cmbCopy используется как для запуска, так и для остановки процесса копирования. Также на форме присутствуют следующие элементы управления:

• индикатор pbCopyProgress, диапазон значений которого от 0 до 100;

• текстовое поле txtFrom с именем копируемого файла;

• текстовое поле txtTo с именем файла назначения.

...

Листинг 4.32.

Использование функции CopyFileEx

procedure TForm1.cmbCopyClick(Sender: TObject);

begin

if cmbCopy.Caption = \'Копировать\' then

begin

//Запускаем копирование

progress := pbCopyProgress; //Настроен от 0 до 100 %

bCancelCopy := False;

cmbCopy.Caption := \'Отмена\

if CopyFileEx(PAnsiChar(txtFrom.Text), PAnsiChar(txtTo.Text),

Addr(CopyProgressFunc), nil, Addr(bCancelCopy),

COPY_FILE_FAIL_IF_EXISTS) = False

then

MessageBox(Handle, \'Не удается скопировать файл\',

\'Копирование\', MB_ICONEXCLAMATION);

end

else

begin

//Останавливаем процесс копирования

bCancelCopy := True;

cmbCopy.Caption := \'Копировать\

end;

end;

Из листинга 4.32 можно увидеть, что в качестве значения последнего параметра функции CopyFileEx можно передавать константу COPY_FILE_FAIL_IF_EXISTS (функция вернет False, если файл назначения уже существует, и не будет осуществлять копирование).

На самом деле значение параметра dwCopyFlags функции CopyFileEx может быть комбинацией значений COPY_FILE_FAIL_IF_EXISTS И COPY_FILE_RES TARTABLE, то есть представляет собой битовый флаг. Последнее значение используется для того, чтобы в случае прерывания копирование файла можно было возобновить. Функция CopyFileEx в этом случае сохраняет в файле назначения информацию, достаточную для возобновления процесса копирования.

В листинге 4.32 изменяется переменная progress – глобальная переменная-ссылка на TProgressBar, которая используется в функции обратного вызова. Переменная bCancelCopy, адрес которой передается в функцию CopyFileEx, также объявлена глобальной (в пределах модуля).

Теперь, наконец, рассмотрим функцию обратного вызова, осуществляющую в нашем случае отображение хода копирования на индикаторе (листинг 4.33).

...

Листинг 4.33.

Функция, показывающая ход копирования файла

function CopyProgressFunc( TotalFileSize: Int64;

TotalBytesTransferred: Int64;

StreamSize: Int64;

StreamBytesTransferred: Int64;

dwStreamNumber: DWORD;

dwCallbackReason: DWORD;

hSourceFile: THandle;

hDestinationFile: THandle;

lpData: Pointer): DWORD; stdcall;

begin

progress.Position := 100 * TotalBytesTransferred div

TotalFileSize;

Application.ProcessMessages; //Чтобы не «зависал»

//интерфейс приложения

CopyProgressFunc := PROGRESS_CONTINUE;

end;

Пусть вас не смущает большое количество параметров функцииСоруРгодгеззЕипс. Применять их все далеко не обязательно (но они должны быть объявлены), хотя ничего сложного здесь нет. В листинге 4.33 использование параметров реализовано наиболее простым (на наш взгляд) и очевидным образом: значения параметров TotalBytesTransferred и TotalFileSize применяются для определения доли скопированной информации.


стр.

Похожие книги