Table of Contents

Converting files

Once Service and APIKey are set, TTMSFNCCloudFileConversion creates a conversion job from a local file, a URL, or Base64 content, and tracks it until it finishes — without you needing to poll for status yourself. This chapter covers starting a conversion, how the component detects completion internally, and the callback alternative to component-level events.

Starting a conversion

ConvertFile uploads a local file and converts it to AOutputFormat; ConvertFileFromURL and ConvertFileFromBase64 create the same kind of job from a remote URL or from Base64-encoded content instead. Each call returns immediately with the job still in progress.

procedure TForm1.ConvertReportToPDF;
begin
  TMSFNCCloudFileConversion1.OnConvertJobFinished := FileConversionJobFinished;
  TMSFNCCloudFileConversion1.ConvertFile('C:\local\report.docx', fcfPdf);
end;

procedure TForm1.FileConversionJobFinished(Sender: TObject;
  const ARequestResult: TTMSFNCCloudBaseRequestResult;
  AJob: TTMSFNCCloudFileConversionJob; AStatus: TTMSFNCCloudFileConversionJobStatus);
begin
  if AStatus = fcjsSuccessful then
    Memo1.Lines.Add('Converted, ' + IntToStr(AJob.OutputFiles.Count) + ' file(s) ready')
  else
    Memo1.Lines.Add('Conversion did not succeed: ' + TTMSFNCCloudFileConversion.GetStatusText(AStatus));
end;

Automatic completion detection

Creating a job starts an internal timer (RetrieveDetailsInterval, 1000 ms by default) that periodically checks every job still in the fcjsWaiting or fcjsProcessing status, and stops itself once none remain — you never call GetConvertJobDetails in a loop yourself. The moment a job's status settles (successful, failed, or cancelled), OnConvertJobFinished fires once with the final TTMSFNCCloudFileConversionJobStatus.

procedure TForm1.FileConversionJobFinished(Sender: TObject;
  const ARequestResult: TTMSFNCCloudBaseRequestResult;
  AJob: TTMSFNCCloudFileConversionJob; AStatus: TTMSFNCCloudFileConversionJobStatus);
begin
  // Fires once per job, whatever the outcome - never for a job still
  // fcjsWaiting or fcjsProcessing, since the internal timer keeps polling
  // until the status settles.
  case AStatus of
    fcjsSuccessful:
      Memo1.Lines.Add(AJob.Name + ': ' + IntToStr(AJob.OutputFiles.Count) + ' output file(s) ready');
    fcjsError:
      Memo1.Lines.Add(AJob.Name + ': conversion failed');
    fcjsCancelled:
      Memo1.Lines.Add(AJob.Name + ': conversion was cancelled');
  end;
end;

Using callbacks for job creation

Every conversion and job method also accepts an optional callback, invoked when that specific call completes its own step — for ConvertFile and its siblings, that means the job was created (or failed to be created), not that the conversion itself finished. This is convenient when you start several conversions at once and want to confirm each one's job ID inline rather than through a shared OnConvertJobCreated event; you still need OnConvertJobFinished (above) to know when the conversion itself completes.

procedure TForm1.ConvertMultipleFilesIndependently;
begin
  TMSFNCCloudFileConversion1.ConvertFile('C:\local\invoice.docx', fcfPdf,
    procedure(AJob: TTMSFNCCloudFileConversionJob; AErrorMessage: string)
    begin
      if AErrorMessage = '' then
        Memo1.Lines.Add('Invoice job created: ' + AJob.Id)
      else
        Memo1.Lines.Add('Invoice job failed to start: ' + AErrorMessage);
    end);

  TMSFNCCloudFileConversion1.ConvertFile('C:\local\summary.docx', fcfPdf,
    procedure(AJob: TTMSFNCCloudFileConversionJob; AErrorMessage: string)
    begin
      if AErrorMessage = '' then
        Memo1.Lines.Add('Summary job created: ' + AJob.Id)
      else
        Memo1.Lines.Add('Summary job failed to start: ' + AErrorMessage);
    end);
end;

Combining a URL conversion with cancellation

CancelConvertJob stops a job that is still waiting or processing. This starts a conversion from a URL, then cancels it if it has not produced a result within a time limit tracked separately from the component's own polling:

// Assumes private fields: FPendingJob: TTMSFNCCloudFileConversionJob;
//                         FConversionDeadline: TDateTime;
procedure TForm1.ConvertFromURLWithTimeout(const AUrl: string);
begin
  FConversionDeadline := Now + (5 / 24 / 60); // 5 minutes from now
  TMSFNCCloudFileConversion1.OnConvertJobFinished := FileConversionURLJobFinished;
  TMSFNCCloudFileConversion1.ConvertFileFromURL(AUrl, fcfPdf, '',
    procedure(AJob: TTMSFNCCloudFileConversionJob; AErrorMessage: string)
    begin
      FPendingJob := AJob;
    end);
end;

// Call this periodically, for example from a UI timer, while the job is pending.
procedure TForm1.CheckConversionDeadline;
begin
  if Assigned(FPendingJob) and (Now > FConversionDeadline) then
  begin
    TMSFNCCloudFileConversion1.CancelConvertJob(FPendingJob);
    FPendingJob := nil;
  end;
end;

procedure TForm1.FileConversionURLJobFinished(Sender: TObject;
  const ARequestResult: TTMSFNCCloudBaseRequestResult;
  AJob: TTMSFNCCloudFileConversionJob; AStatus: TTMSFNCCloudFileConversionJobStatus);
begin
  FPendingJob := nil;
  Memo1.Lines.Add(AJob.Name + ': ' + TTMSFNCCloudFileConversion.GetStatusText(AStatus));
end;

Common mistakes

  • Polling for status manually. The component already polls internally; reading Job.Status from a timer of your own duplicates that work — wait for OnConvertJobFinished (or a callback) instead.
  • Assuming OnConvertJobFinished means success. It fires for every terminal status, including fcjsError and fcjsCancelled — check AStatus before treating the job as successful.
  • Reading OutputFiles before the job finishes. It is only populated once the job completes successfully and its details have been retrieved.

See also