КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"
[Главная страница] [Delphi] [Контакты]
В секции определения переменных главной формы (перед началом раздела implementation) объявите переменные hMFile и pMFile и константу mFileName:
var Form1: TForm1; hMFile : THandle; pMFile : pointer; const mFileName = 'FileMappingDemo'; //имя объекта отображения
Сохраните приложение под именем FMapping.dpr. Перейдите к головному модулю проекта .dpr и внесите в него изменения так, как предложено в следующем листинге:
program FMapping; uses Forms, Windows, SysUtils, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; {Для того чтобы процессы смогли разделить объект файлового отображения, они должны передавать одинаковые параметры в методы CreateFileMapping() и MapViewOfFile()} hMFile := CreateFileMapping($FFFFFFFF, nil, Page_ReadWrite, 0, 256, mFileName); {размер объекта отображения – всего-навсего 256 байт, он доступен для чтения и записи} if hmFile > 0 then begin pMFile := MapViewOfFile(hmFile,File_Map_All_Access,0,0,0); Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.MainForm.Caption := Format('Handle = $%x',[Application.Handle]); Application.Run; end else Halt; //мы не смогли создать объект отображения end.
Сразу после инициализации приложения мы пытаемся создать объект отображения. Если эта операция завершилась неудачно, прекращаем работу программы, вызвав метод Halt(). Если же дескриптор объекта отображения получен, то проецируем его в виртуальное адресное пространство нашего процесса. Для этого вызываем функцию CreateFileMapping() и получаем указатель на начальную область памяти pMFile. Затем создаем главную форму и запускаем приложение на выполнение.
Опишем событие закрытия главной формы:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin UnMapViewOfFile(pMFile); //отмена представления файла в адресном пространстве CloseHandle(hMFile); //освобождаем дескриптор объекта отображения end;
Научившись создавать и уничтожать объекты отображения, займемся самым интересным. Разместите на главной форме проекта два элемента управления: группу переключателей TRadioGroup и таймер TTimer. Чтобы заполнить группу переключателей некоторым набором элементов, перепишите событие создания формы:
procedure TForm1.FormCreate(Sender: TObject); var Ch : byte; begin RadioGroup1.Align := alClient; for Ch:=Byte('A') to Byte('Z') do RadioGroup1.Items.Add(Char(Ch)); RadioGroup1.Columns := 3; end;
Компонент RadioGroup1 заполняется тремя колонками символов латинского алфавита. Опишем щелчок по компоненту:
procedure TForm1.RadioGroup1Click(Sender: TObject); var ind : string; begin ind := IntToStr(RadioGroup1.ItemIndex); //индекс выбранной кнопки StrCopy(pMFile,PChar(ind)); //передаем индекс в файл end;
В момент щелчка по группе переключателей выясняется индекс отмеченного переключателя, и он передается в объект отображения. Для этого применяется метод StrCopy(). Для считывания данных из объекта отображения предназначен таймер:
procedure TForm1.Timer1Timer(Sender: TObject); var ind: string; begin if not (Application.Active) then begin ind := PChar(pMFile); RadioGroup1.ItemIndex := StrToIntDef(ind, 0); end; end;
В момент возникновения события OnTimer() производится считывание данных из объекта отображения. Полученное значение соответствует индексу переключателя, выбранного в другом приложении.
Проект завершен. Запустите несколько экземпляров нашего приложения и проверьте работоспособность кода.
При одновременном обращении нескольких процессов к объекту отображения возможно возникновение ошибки совместного использования ресурса. В таких случаях для защиты разделяемого ресурса целесообразно воспользоваться объектами синхронизации, например критической секцией.
Исходный код проекта (Delphi XE)
Используемая литература: Delphi. Профессиональное программирование. Д. Осипов.