unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls;

type
  TfMain = class(TForm)
    GroupBox1: TGroupBox;
    eName: TLabeledEdit;
    dtBirthday: TDateTimePicker;
    Label1: TLabel;
    ePhone: TLabeledEdit;
    eAddress: TLabeledEdit;
    eWeight: TLabeledEdit;
    eHeight: TLabeledEdit;
    btnSave: TButton;
    GroupBox2: TGroupBox;
    btnCreate: TButton;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnCreateClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  PPeopleInfo = ^TPeopleInfo;
  TPeopleInfo = record
    Name : string[100];
    Weight : real;
    Height : real;
    Birthday : TDate;
    Phone : string[50];
    Address : string[200];
  end;

var
  fMain: TfMain;
  PF : file of TPeopleInfo;
  MainDir : string;
  PIPtr : PPeopleInfo;
  PI : TPeopleInfo;

  FFileHandle : THandle;       // Ідентифікатор відкритого файлу
  FMapHandle  : THandle;       // Ідентифікатор об'єкта відображення файлу
  FFileSize   : Integer;       // Розмір файлу
  FData       : PByte;         // Вказівник на дані файла при відображенні

const PFName = 'PeopleData.pdata';

implementation

{$R *.dfm}

procedure TfMain.btnCreateClick(Sender: TObject);
begin
  if FileExists(MainDir + PFName) then begin
    MessageDlg('Файл вже існує!', mtInformation, [mbOK], 0);
    Exit;
  end;

  AssignFile(PF, MainDir + PFName);
  Rewrite(PF);
  with PI do begin
    Name := 'Петренко Василь Іванович';
    Birthday := Now - 25 * 365;
    Phone := '0678736474';
    Address := 'м. Київ, вул. Лучаковського, 178/ 37';
    Weight := 78.4;
    Height := 176;
  end;
  Write(PF, PI);
  CloseFile(PF);
end;

procedure TfMain.btnSaveClick(Sender: TObject);
begin
  // Запис нових даних у пам'ять (відображений файл)
  PIPtr := PPeopleInfo(FData);
  with PIPtr^ do begin
    Name := eName.Text;
    Birthday := dtBirthday.Date;
    Phone := ePhone.Text;
    Address := eAddress.Text;
    Weight := StrToFloat(eWeight.Text);
    Height := StrToFloat(eHeight.Text);
  end;
  FlushViewOfFile(FData, 0);
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
  MainDir := ExtractFilePath(Application.ExeName);
  if not FileExists(MainDir + PFName) then btnCreate.OnClick(nil);

  // Відкриваємо файл
  FFileHandle := CreateFile(PChar(MainDir + PFName), GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  // Можна також використовувати функцію Delphi FileOpen
  // FFileHandle := FileOpen(MainDir + PFName, fmOpenReadWrite);
  if FFileHandle = INVALID_HANDLE_VALUE then raise Exception.Create('Файл не відкрито');

  try
    FFileSize := GetFileSize(FFileHandle, nil);
    // Отримуємо ідентифікатор об'єкта відображення файлу
    FMapHandle := CreateFileMapping(FFileHandle, nil, PAGE_READWRITE, 0, 0, nil);
    if FMapHandle = 0 then raise Exception.Create('Не вдалось створити відображення файлу');
  finally
    // Вивільняємо ідентифікатор файлу
    CloseHandle(FFileHandle);
  end;

  try
    // Подаємо об'єкт відображення у вікні перегляду.
    // Ця функція поверне вказівник на дані файлу
    FData := MapViewOfFile(FMapHandle, FILE_MAP_ALL_ACCESS, 0, 0, FFileSize);
    if FData = nil then raise Exception.Create('Не вдалось відобразити вікно перегляду файла');
  finally
    // Вивільняємо ідентифікатор об'єкта відображення файлу
    CloseHandle(FMapHandle);
  end;
end;

procedure TfMain.FormDestroy(Sender: TObject);
begin
  // Вивільняємо відображення файлу
  UnMapViewOfFile(FData);
end;

end.
