type
  TStreamOpenEvent = function(Sender: TObject; const AFilename: string; var ASeekable: Integer): Boolean of object;
{$IF Defined(VER140) or Defined(BCB)} // Delphi 6.0 or BCB
  {$IF Defined(BCB)}
  TStreamReadEvent = function(Sender: TObject; Buffer: Pointer; Count: Longint): Longint of object;
  TStreamWriteEvent = function(Sender: TObject; Buffer: Pointer; Count: Longint): Longint of object;
  {$ELSE}
  TStreamReadEvent = function(Sender: TObject; Buffer: PByte; Count: Longint): Longint of object;
  TStreamWriteEvent = function(Sender: TObject; Buffer: PByte; Count: Longint): Longint of object;
  {$IFEND}
{$ELSE}
  TStreamReadEvent = function(Sender: TObject; var Buffer; Count: Longint): Longint of object;
  TStreamWriteEvent = function(Sender: TObject; const Buffer; Count: Longint): Longint of object;
{$IFEND}
  TStreamSeekEvent = function(Sender: TObject; const Offset: Int64; Origin: TSeekOrigin): Int64 of object;

  TCustomEventStream = class(TStream)
  protected
    function Open(const AFilename: string; var ASeekable: Integer): Boolean;
    procedure Close;
  public
    constructor Create;
    destructor Destroy; override;

    function Read(var Buffer; Count: LongInt): LongInt; override;
    function Write(const Buffer; Count: LongInt): LongInt; override;
    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;

    property Opened: Boolean read FOpened;
    property Filename: string read FFilename;
    property TriggerEventInMainThread: Boolean read FTriggerEventInMainThread write FTriggerEventInMainThread;
    property OnOpen: TStreamOpenEvent read FOnOpen write FOnOpen;
    property OnClose: TNotifyEvent read FOnClose write FOnClose;
    property OnRead: TStreamReadEvent read FOnRead write FOnRead;
    property OnWrite: TStreamWriteEvent read FOnWrite write FOnWrite;
    property OnSeek: TStreamSeekEvent read FOnSeek write FOnSeek;
  end;

  TEventStream = class(TCustomEventStream);
