What is F-IN-BOX Delphi Edition?

F-IN-BOX is a powerful Delphi / C++ Builder / VCL component that wraps the official Macromedia / Adobe Flash Player ActiveX (swflash.ocx / flash.ocx), allowing you to bypass its limitations while maintaining full compatibility. Unlike custom renderers, F-IN-BOX uses the real Flash engine but enables you to load SWF and FLV files directly from memory streams—without saving to disk or relying on temporary files.

It supports asynchronous streaming of large movies and external resources, frame capture, transparent Flash UI, audio control, and the External API for two-way communication between your app and the Flash content.

All Flash Player versions are supported, in both x86 and x64 architectures. No installation or registration of Flash Player is required—F-IN-BOX can even load it from resources.

Want to see F-IN-BOX in action?

Enter a valid email address to receive the demo version.

If you don't receive the email, please contact us.

Key Features

It's a known limitation that Flash Player ActiveX can only load movies from certain URLs. Typically, you need to extract the movie from your application's resources, save it to a temporary location, generate a valid path, pass it to the Flash Player ActiveX, and finally delete the temporary file. This process is not only inconvenient but also risky — it may fail due to insufficient permissions or lack of access to a temporary directory. Moreover, this method is unsuitable in security-sensitive environments, as the SWF file can be easily intercepted.

F-IN-BOX solves this problem. It wraps the official swflash.ocx/flash.ocx and provides an alternative way to load Flash movies: directly from a stream. This means no more temporary files! You can load movies from any TStream descendant such as TResourceStream, TMemoryStream, and others. This greatly simplifies deployment and enhances security, especially when used with your preferred software protection tools.

Using the component you can load any flash movie from any stream object. Just use the LoadMovieFromStream and PutMovieFromStream methods. No temporary files! Load any flash movie on-the-fly from any supported source. For example, you can put one or more flash movies in the resource section of your application and then load it from the exe! That's the portability and power of F-IN-BOX!

Using F-IN-BOX, you can load any Flash movie on-the-fly from a supported source. For example, you can embed SWF files into your application's resources and load them directly from the executable. That's the portability and power of F-IN-BOX.

If you need to play a large SWF or experience performance issues, take a look at the Streaming feature for better handling.

Here's an example of how to load a Flash movie from a resource:

{$RESOURCE 'res\\movie.res'}
 
type
TMainForm = class(TForm)
  FlashPlayerControl1: TFlashPlayerControl;
end;
 
procedure TMainForm.FormCreate(Sender: TObject);
var
ResourceStream: TResourceStream;
begin
ResourceStream := TResourceStream.Create(0, 'EmbeddedMovie', 'FLASH');
FlashPlayerControl1.PutMovieFromStream(ResourceStream);
ResourceStream.Free;
end;
#pragma resource "res\\movie.res"
 
class TMainForm : public TForm
{
__published:
  void __fastcall FormCreate(TObject *Sender);
};
 
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
TResourceStream* ResourceStream = new TResourceStream(0, "EmbeddedMovie", "FLASH");
FlashPlayerControl1->PutMovieFromStream(ResourceStream);
delete ResourceStream;
}

One of the biggest challenges when using Flash Player ActiveX is the requirement to register the component. The common workaround is saving the swflash.ocx/flash.ocx file to a temporary location and registering it, but this comes with its own problems—such as lacking permissions to write or register the file. With F-IN-BOX, you can forget about all that. It allows you to use swflash.ocx/flash.ocx from any source, such as embedding it directly into your application's resources. Importantly, F-IN-BOX doesn't rely on temporary files or registration—it loads the code directly. No more user permission issues, no more temp files, and no more component registration headaches. By default, F-IN-BOX uses the system-installed version of swflash.ocx/flash.ocx, but you're free to choose any version you prefer.

Traditionally, developers face several limitations when using Macromedia / Adobe Flash Player ActiveX in their applications:

  • The application requires swflash.ocx/flash.ocx to be installed on the system.
  • It must be compatible with whatever version is already installed.
  • There's no easy way to protect Flash movies from being accessed or copied.

F-IN-BOX solves all of these problems—and more!

By default, the component uses the installed version of swflash.ocx/flash.ocx, but you can also embed your own version directly into your application's executable. This ensures your app works even if Flash Player ActiveX isn't present on the target machine. With F-IN-BOX, dealing with Flash installation issues becomes a thing of the past—it's that simple.

Here's an example of how to load swflash.ocx/flash.ocx from a resource:

{$RESOURCE 'res\\flash.res'}
 
var
FlashCodeStream: TResourceStream;
 
initialization
FlashCodeStream := TResourceStream.Create(0, 'FlashOCXCode', 'BIN');
FlashPlayerControl.LoadFlashOCXCodeFromStream(FlashCodeStream);
FlashCodeStream.Free;
#pragma resource "res\\flash_ocx.res"
 
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
Application->Initialize();
TResourceStream* FlashCodeStream = new TResourceStream(0, "FlashOCXCode", "BIN");
Flashplayercontrol::LoadFlashOCXCodeFromStream(FlashCodeStream);
delete FlashCodeStream;
}

Here's an example of how to load swflash.ocx/flash.ocx from a file:

var
  FlashCodeStream: TFileStream;
 
initialization
  FlashCodeStream := TFileStream.Create('flash.ocx', fmOpenRead or fmShareDenyNone);
  FlashPlayerControl.LoadFlashOCXCodeFromStream(FlashCodeStream);
  FlashCodeStream.Free;
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
  Application->Initialize();
 
  TFileStream* FlashCodeStream =
    new TFileStream("flash.ocx", fmOpenRead | fmShareDenyNone);
  Flashplayercontrol::LoadFlashOCXCodeFromStream(FlashCodeStream);
  delete FlashCodeStream;
}

With FlashPlayerControl, you can build applications using transparent Flash movies, allowing for non-rectangular, translucent windows. Design modern user interfaces in Flash and implement business logic using Delphi or C++ Builder.

To enable transparency, use the TTransparentFlashPlayerControl component. Simply place it on a form and set the MakeParentTransparent property to True. That's all!

Using FlashPlayerControl, you can play Flash Video (FLV) from external files, a URL, or directly from a TStream. When TFlashPlayerControl loads a Flash Video, no temporary files are created—everything runs directly from memory. You can even encrypt your video and embed it into your application's resources—TFlashPlayerControl will load the FLV without ever writing it to disk.

If you're playing a large FLV file or experiencing performance issues, be sure to check out the Streaming feature.

To play Flash Video from a stream, you need to create a Flash movie that loads the video from a "private" URL (e.g., http://FLV/FlashVideo.flv). The Flash movie should include the following ActionScript code (typically placed under a button):

var netConn:NetConnection = new NetConnection();
 
netConn.connect(null);
 
var netStream:NetStream = new NetStream(netConn);
 
my_video.attachVideo(netStream);
 
netStream.setBufferTime(0);
 
netStream.play("http://FLV/FlashVideo.flv");

When Flash attempts to load the video from http://FLV/FlashVideo.flv, TFlashPlayerControl supplies the content of the FLV. Use the global procedure SetGlobalOnLoadExternalResourceHandler to handle external resource requests and provide the data to Flash. See the example below:

type
  TMainForm = class(TForm)
    procedure FormCreate(Sender: TObject);
 
  private
    procedure OnGlobalLoadExternalResource(const URL: String; Stream: TStream);
end;
 
procedure TMainForm.FormCreate(Sender: TObject);
begin
  SetGlobalOnLoadExternalResourceHandler(OnGlobalLoadExternalResource);
end;
 
procedure TMainForm.OnGlobalLoadExternalResource(const URL: String; Stream: TStream);
var
  ResourceStream: TResourceStream;
begin
  if URL = 'http://FLV/FlashVideo.flv' then
  begin
      ResourceStream := TResourceStream.Create(0, 'FlashVideo', 'FLV');
      ResourceStream.SaveToStream(Stream);
      ResourceStream.Free;
  end;
end;
class TMainForm : public TForm
{
__published:
  void __fastcall FormCreate(TObject *Sender);
 
private:
  void __fastcall OnGlobalLoadExternalResource(const AnsiString URL, Classes::TStream* Stream);
}
 
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
  SetGlobalOnLoadExternalResourceHandler(OnGlobalLoadExternalResource);
}
 
void __fastcall TMainForm::OnGlobalLoadExternalResource(const AnsiString URL, Classes::TStream* Stream)
{
  if (URL == "http://FLV/FlashVideo.flv")
  {
    TResourceStream* ResourceStream = new TResourceStream(0, "FlashVideo", "FLV");
    ResourceStream->SaveToStream(Stream);                                         
    delete ResourceStream;
  }
}

Using the component, you can enable or disable all sounds in all loaded Flash movies.

To control the audio, use the global procedure SetAudioEnabled to turn sound on or off. To check the current audio status, call GetAudioEnabled.

Please see the sample below:

procedure TMainForm.Mute;
begin
  if FlashPlayerControl.GetAudioEnabled then
    FlashPlayerControl.SetAudioEnabled(False);
end;
void __fastcall TMainForm::Mute()
{
if (Flashplayercontrol::GetAudioEnabled())
  Flashplayercontrol::SetAudioEnabled(false);
}

You can control the sound volume using the global procedure FlashPlayerControl.SetAudioVolume, passing a value between 0 and 100. To retrieve the current audio volume, use FlashPlayerControl.GetAudioVolume:

FlashPlayerControl.SetAudioVolume(TrackBarSoundVolume.Position);
Flashplayercontrol::SetAudioVolume(TrackBarSoundVolume->Position);

You can capture a bitmap image from the current frame of a Flash movie. This allows you to create applications that convert Flash movies into a series of bitmaps, JPEGs, or other image formats. You can also use the generated images to create an AVI video, for example. See the sample code below:

procedure TMainForm.ButtonSaveAsBitmapClick(Sender: TObject);
var
Bitmap: TBitmap;
Picture: TPicture;
begin
Picture := TPicture.Create;
Bitmap := FlashPlayerControl1.CreateFrameBitmap;
Picture.Bitmap := Bitmap;
 
Picture.SaveToFile('Frame.bmp');
 
Bitmap.Free;
Picture.Free;
end;
void __fastcall TMainForm::ButtonSaveAsBitmapClick(TObject *Sender)
{
TPicture* Picture = new TPicture;
Graphics::TBitmap* Bitmap = FlashPlayerControl1->CreateFrameBitmap();
Picture->Bitmap = Bitmap;
 
Picture->SaveToFile("Frame.bmp");
 
delete Bitmap;
delete Picture;
}

One of the challenges with Macromedia / Adobe Flash Player ActiveX programming is managing compatibility with different versions. For example, the "Stacking" property exists only in Flash Player ActiveX 5 and was removed in later versions.

F-IN-BOX automatically detects the version of Flash Player ActiveX being used and prevents failures when accessing non-existent properties or methods. Applications built with F-IN-BOX are not only compatible with any version of Flash Player ActiveX but also intelligently adapt to the version in use.

This makes your application more robust and can significantly reduce technical support issues.

FlashPlayerControl supports the External API, enabling two-way communication between your application and the Flash movie. Unlike fscommand, this communication is synchronous.

You can:

  • Call ActionScript functions from your application
  • Call application functions directly from the Flash script

Calling an ActionScript Function from Your Application

Register your function using ExternalInterface.addCallback:

import flash.external.*;
 
ExternalInterface.addCallback("CallMeFromApplication", this, InternalFunction);
 
function InternalFunction(str: String): String {
  TextArea1.text = str;
  return "The function was called successfully";
}

Then call the function using CallFunction:

var
  Response: WideString;
begin
  Response :=
    FlashPlayerControl1.CallFunction(
      '<invoke name="CallMeFromApplication" returntype="xml">' +
      '<arguments>' +
      '<string>Some text for TFlashPlayerControl</string>' +
      '</arguments>' +
      '</invoke>');
 
  ShowMessage(Format('The function returned: %s', [ Response ]));
end;
WideString Response =
  FlashPlayerControl1->CallFunction(
    "<invoke name=\"CallMeFromApplication\" returntype=\"xml\">" 
    "<arguments><string>Some text for F-IN-BOX</string></arguments>"
    "</invoke>");
 
  ShowMessage("The function returned: " + Response);

Calling an Application Function from Flash Script

Use flash.external.ExternalInterface.call in your ActionScript code:

on (click) {
  _root.TextArea1.text = flash.external.ExternalInterface.call("SomeFunction");
}

Then handle the call using the OnFlashCall event:

procedure TMainForm.FlashPlayerControl1FlashCall(ASender: TObject; const request: WideString);
begin
  FlashPlayerControl1.SetReturnValue('<string>Current time is: ' +
    TimeToStr(Time) +
      '</string>');
end;
void __fastcall TMainForm::FlashPlayerControl1FlashCall(TObject *ASender, const WideString request)
{
  FlashPlayerControl1->SetReturnValue("<string>Current time is: " +
    TimeToStr(Time()) +
    "</string>");
}

Streaming refers to the ability to load content asynchronously. When you use LoadMovieFromStream, the movie is loaded directly from the stream. If the movie is large, this may take some time. For example, if you've encoded an SWF or FLV file and want to load it into the player, using LoadMovieFromStream means the player will begin playback only after all the data has been decoded. This is why the ability to stream content asynchronously is so important.

Important notes:

To load a movie or other resource (e.g., .flv, .jpg, .mp3, .xml, etc.), use a stream (AStream). Provide content by writing to the stream using AStream.Write.

If you write data from a separate thread, make sure to call AStream.Write within a Synchronize block.

If AStream.Write returns 0, it means the loading process has been canceled (for example, if another movie is being loaded).

Always free the stream using AStream.Free when loading is complete—even if it was canceled.

There are several typical use cases:

Use LoadMovieUsingStream or PutMovieUsingStream to load a movie asynchronously.

Important notes:

Provide the movie content by writing to the movie stream. If you're writing data from a separate thread, use Synchronize when calling Write on the stream. If Write returns 0, it means loading was canceled (e.g., another movie started loading). Be sure to free the movie stream when loading is complete—even if it was canceled:

MovieStream: TStream;
begin
  FlashPlayerControl1.LoadMovieUsingStream(0, MovieStream);
  ContentProviderThread := TContentProviderThread.Create(MovieStream);
end;
...
 
TContentProviderThread = class(TThread)
private
  FMovieStream: TStream;
  FBuffer: TMemoryStream;
...
end;
...
procedure TContentProviderThread.DoWrite;
var
  nWrittenBytes: integer;
begin
  nWrittenBytes := FMovieStream.Write(FBuffer.Memory^, FBuffer.Size);
 
  if nWrittenBytes = 0 then
      // Write returns 0, if loading was cancelled by some reason
      FStop := true;
end;
...
procedure TContentProviderThread.Execute;
begin
  while not FStop do
  begin
      // preparing buffer
      PrepareBuffer;
 
      if FBuffer.Size > 0 then
        // always call DoWrite using Synchronize!
        Synchronize(DoWrite);
  end;
 
  // free the stream after providing all amount of data!
  FMovieStream.Free;
end;
TStream* MovieStream;
 
FlashPlayerControl1->LoadMovieUsingStream(0, MovieStream);
 
TContentProviderThread* ContentProviderThread = new TContentProviderThread(MovieStream);
...
class TContentProviderThread : public TThread
{
  private:
      TStream* FMovieStream;
      TMemoryStream* FBuffer;
...
};
 
...
 
void __fastcall TContentProviderThread::DoWrite()
{
  int nWrittenBytes = FMovieStream->Write(FBuffer->Memory, FBuffer->Size);
 
  if (0 == nWrittenBytes)
      FStop = true;
}
...
void __fastcall TContentProviderThread::Execute()
{
  while (!FStop)
  {
      // preparing buffer
      PrepareBuffer();
 
      if (FBuffer->Size > 0)
      Synchronize(DoWrite);
  }
 
  // free the stream after providing all amount of data!
  FMovieStream->Free();
}

To load external resources asynchronously (such as Flash videos, images, or audio files), use the global procedure FlashPlayerControl.SetGlobalOnLoadExternalResourceHandlerEx to set a resource handler.

For example, when a movie attempts to load http://FLV/FlashVideo.flv, the handler is triggered. Inside the handler, compare the passed URL with your expected value. If they match, set bHandled to true and use the provided stream to supply the content.

After supplying the data, free the stream—regardless of whether the load was completed or canceled.

Important notes:

  • The stream used in the handler represents the resource being requested.
  • If writing to the stream from a separate thread, use Synchronize.
  • If Write returns 0, loading was canceled (e.g., another movie started loading).
  • Always free the stream when finished.
var
  MovieStream: TStream;
begin
  // set global handler
  SetGlobalOnLoadExternalResourceHandlerEx(ContentProvider);
  FlashPlayerControl1.LoadMovieFromStream(0, MovieStream); // load movie
...
procedure TMainForm.ContentProvider(const URL: string;
        Stream: TStream;
        out bHandled: Boolean);
var
  ContentProviderThread: TContentProviderThread;
begin
  if URL = 'http://FLV/FlashVideo.flv' then
  begin
      ContentProviderThread := TContentProviderThread.Create(Stream);
 
      bHandled := true;
  end;
end;
...
TContentProviderThread = class(TThread)
private
  FResourceStream: TStream;
  FBuffer: TMemoryStream;
...
end;
...
procedure TContentProviderThread.DoWrite;
var
  nWrittenBytes: integer;
begin
  nWrittenBytes := FResourceStream.Write(FBuffer.Memory^, FBuffer.Size);
 
  if nWrittenBytes = 0 then
      // Write returns 0, if loading was cancelled by some reason
      FStop := true;
end;
...
procedure TContentProviderThread.Execute;
begin
  while not FStop do
  begin
      // preparing buffer
      PrepareBuffer;
 
  if FBuffer.Size > 0 then
      // always call DoWrite using Synchronize!
      Synchronize(DoWrite);
  end;
 
  // free the stream after providing all amount of data!
  FResourceStream.Free;
end;
TStream* MovieStream;
 
FlashPlayerControl1->LoadMovieUsingStream(0, MovieStream);
 
TContentProviderThread* ContentProviderThread = new TContentProviderThread(MovieStream);
...
class TContentProviderThread : public TThread
{
  private:
      TStream* FResourceStream;
      TMemoryStream* FBuffer;
...
};
...
void __fastcall TContentProviderThread::DoWrite()
{
  int nWrittenBytes = FResourceStream->Write(FBuffer->Memory, FBuffer->Size);
 
  if (0 == nWrittenBytes)
      FStop = true;
}
...
void __fastcall TContentProviderThread::Execute()
{
  while (!FStop)
  {
      // preparing buffer
      PrepareBuffer();
 
      if (FBuffer->Size > 0)
        Synchronize(DoWrite);
  }
 
  // free the stream after providing all amount of data!
  FResourceStream->Free();
}

When a movie is loaded using LoadMovieFromStream, PutMovieFromStream, LoadMovieUsingStream, or PutMovieUsingStream, it may attempt to load additional external resources (such as images, sounds, or other SWF files) using relative paths (e.g., "images/image1.jpg"). In this case, you should handle the OnLoadExternalResourceEx event to provide the required content asynchronously.

Important notes:

  • In the OnLoadExternalResourceEx event handler, you receive a stream associated with the requested resource. If you're ready to supply the content, set the bHandled flag (passed by reference) to true and use the provided stream to write the resource data.
  • If you're writing data from a background thread, make sure to call Write using Synchronize.
  • If Write returns 0, the loading has been cancelled (for instance, due to another movie being loaded). Always free the stream, even in this case.
  • Once all data has been written, free the stream to complete the operation.
  • For C++ Builder users: Sometimes the IDE incorrectly generates the OnLoadExternalResourceEx handler with bool bHandled instead of bool& bHandled. If this happens, manually correct the signature in both the header and source files.

Below is an example of how to provide image content from your application:

procedure TMainForm.FlashPlayerControl1LoadExternalResourceEx(
  ASender: TObject;
  const URL: String;
  Stream: TStream;
  var bHandled: Boolean);
var
  ContentProviderThread: TContentProviderThread;
begin
  if URL = 'images/embedded_image1.jpg' then
  begin
      ContentProviderThread := TContentProviderThread.Create(Stream);
 
      bHandled := true;
  end;
end;
...
TContentProviderThread = class(TThread)
private
  FResourceStream: TStream;
  FBuffer: TMemoryStream;
...
end;
...
procedure TContentProviderThread.DoWrite;
var
  nWrittenBytes: integer;
begin
  nWrittenBytes := FResourceStream.Write(FBuffer.Memory^, FBuffer.Size);
 
  if nWrittenBytes = 0 then
      // Write returns 0, if loading was cancelled by some reason
      FStop := true;
end;
...
procedure TContentProviderThread.Execute;
begin
  while not FStop do
  begin
      // preparing buffer
      PrepareBuffer;
 
      if FBuffer.Size > 0 then
        // always call DoWrite using Synchronize!
        Synchronize(DoWrite);
  end;
 
  // free the stream after providing all amount of data!
  FResourceStream.Free;
end;
// Sometimes Builder C++ creates event handler with bool bHandled
// instead of bool& bHandled. If it happened, change bool
// to bool& in a header file and in a source file
void __fastcall TMainForm::FlashPlayerControl1LoadExternalResourceEx(
      TObject *ASender,
      const AnsiString URL,
      TStream *Stream,
      bool& bHandled)
{
  if (URL == "images/embedded_image1.jpg")
  {
      TContentProviderThread* ContentProviderThread = new TContentProviderThread(Stream);
 
      bHandled = true;
  }
}
...
class TContentProviderThread : public TThread
{
  private:
      TStream* FResourceStream;
      TMemoryStream* FBuffer;
...
};
...
void __fastcall TContentProviderThread::DoWrite()
{
  int nWrittenBytes = FResourceStream->Write(FBuffer->Memory, FBuffer->Size);
 
  if (0 == nWrittenBytes)
      FStop = true;
}
...
void __fastcall TContentProviderThread::Execute()
{
  while (!FStop)
  {
      // preparing buffer
      PrepareBuffer();
 
      if (FBuffer->Size > 0)
        Synchronize(DoWrite);
  }
 
  // free the stream after providing all amount of data!
  FResourceStream->Free();
}