Excel. Трюки и эффекты
Шрифт:
function MapViewOfFile(hFileMappingObject: THandle;
dwDesiredAccess: DWORD;
dwFileOffsetHigh, dwFileOffsetLow,
dwNumberOfBytesToMap: DWORD ): Pointer;
Функция имеет следующие параметры.
• hFileMappingOb j ect – описатель созданного объекта файлового отображения.
• dwDesiredAccess – параметр доступа к полученным данным, в случае чтения и записи принимает значение FILE_MAP_WRITE.
• dwFileOf f setHigh, dwFileOf fsetLow – 64-битное смещение от начала файла.
• dwNumberOf BytesToMap –
В результате успешного выполнения функции MapViewOfFile будет получен указатель (тип Pointer) на начальный адрес данных объекта. Указатель будет использоваться в дальнейшем для записи или чтения файла.
Следующей функцией, противоположной по производимым действиям функции MapViewOfFile, является UnMapViewOf File. Она отключает проецируемый файл от текущего процесса:
function UnMapViewOfFile(lpBaseAddress: Pointer): Boolean;
Функция принимает указатель, возвращаемый MapViewOfFile, и использует его для отмены проекции файла на адресное пространство процесса. В случае успешной выгрузки функция возвращает True, в противном случае – False.
И последняя функция, которую необходимо рассмотреть, – это CloseHandle. Она используется для закрытия дескриптора (многих системных объектов, а не только проекции файла).
function CloseHandle(hFileMapObj: THandle):Boolean;
Как видно из синтаксиса функции, она принимает описатель объекта файлового отображения, полученный в результате выполнения функции CreateFileMapping и освобождает его. Для правильного завершения работы с объектом файлового отображения сначала следует применить функцию UnMapViewOf File, а затем CloseHandle.
Сама проекция файла будет удалена только после того, как будут закрыты все дескрипторы во всех использующих эту проекцию процессах.
Для демонстрации работы проецируемых в память файлов создадим приложение, которое будет записывать в такой файл строку и спустя некоторое время считывать ее оттуда. Для этого нам понадобится стандартный TextBox, кнопка, метка и таймер. Программа будет работать следующим образом: строка, записанная в поле редактора, после нажатия кнопки помещается в проецируемый файл. Далее, спустя некоторое время (задается таймером), содержимое файла считывается и задается в качестве заголовка метки (рис. 8.2).
Рис. 8.2. Вид приложения, использующего проецируемый файл
В секцию описания переменных программы помещаем следующие объявления:
var
FormMappingFile: TFormMappingFile;
//Глобальные переменные
//Описатель объекта проецируемого файла
hFileMapObj:THandle;
//Указатель на начальный адрес данных
lpBaseAddress:PChar;
Далее
Листинг 8.7.
Создание формы приложения
procedure TMappingFile.FormCreate(Sender: TObject);
begin
//Создаем проецируемый файл с именем FileMemory
//и передаем полученный в результате описатель
//в глобальную переменную hFileMapObj
hFileMapObj := CreateFileMapping(MAXDWORD,Nil,PAGE_READWRITE,
0,4,’FileMemory’);
If (hFileMapObj = 0) Then
ShowMessage(\'Не могу создать проецируемый файл!\')
Else
//Подключаем файл к адресному пространству
//и получаем начальный адрес данных
lpBaseAddress := MapViewOfFile(hFileMapObj,FILE_MAP_WRITE,
0,0,0);
If lpBaseAddress = Nil Then
ShowMessage(\'Не могу подключить проецируемый файл!\');
end;
После инициализации файла его можно использовать. Приведем листинг обработчика, копирующего данные в проецируемый файл (листинг 8.8).
Листинг 8.8. Копирование данных в проецируемый файл
procedure TMappingFile.bnOKClick(Sender: TObject);
begin
//Считываем данные в проецируемый файл
StrPCopy(lpBaseAddress,edVariable.Text);
end;
После того как будет нажата кнопка, данные помещаются в проецируемый файл. По истечении некоторого времени, заданного таймером, строка устанавливается в качестве текста метки (листинг 8.9).
Листинг 8.9.
Считывание данных из проекции файла
procedure TMappingFile.TimerMFTimer(Sender: TObject);
begin
lbVariable.Caption := PChar(lpBaseAddress);
end;
В момент завершения приложения необходимо отключить проецируемый файл от адресного пространства процесса и закрыть объект файла. Эти действия можно выполнять в момент уничтожения формы (листинг 8.10).
Листинг 8.10.
Уничтожение формы приложения
procedure TMappingFile.FormClose(Sender: TObject; var Action:
TCloseAction);
begin
//Отключим файл от адресного пространства
UnMapViewOfFile(lpBaseAddress);
//Освобождаем объект файла
CloseHandle(hFileMapObj);
//Закрываем форму
Action := caFree;
end;
Здесь рассмотрен простой пример работы с проекцией файла в рамках одного приложения. Более же интересный и реальный пример вы увидите в разд. 10.2 при рассмотрении программы «Оконный шпион»: там проекция файла в память используется для передачи данных из функции DLL, работающей в памяти другого процесса.