从VCL到FMX的Delphi端口代码

从VCL到FMX的Delphi端口代码,delphi,firemonkey,Delphi,Firemonkey,我有一个位图解码器模块 function DecryptBmp(FHandle:pointer; FBitmap,FData:pointer; DataSize:integer):boolean;cdecl; external 'BmpDecrypter.dll'; 我将其与VCL一起使用的方式如下: procedure TBmpDecrypter.Decrypt(ASourceData: pointer; ASourceSize: integer); var isDecrypted:b

我有一个位图解码器模块

function  DecryptBmp(FHandle:pointer; FBitmap,FData:pointer; DataSize:integer):boolean;cdecl; external 'BmpDecrypter.dll';
我将其与VCL一起使用的方式如下:

procedure TBmpDecrypter.Decrypt(ASourceData: pointer; ASourceSize: integer);
var
  isDecrypted:boolean;
begin

    if FHandle = nil then Exit;

      isDecrypted:= DecryptBmp(FHandle, FDestBmp.ScanLine[FDestBmp.Height-1],ASourceData, ASourceSize);
      if isDecrypted then 
       ShowMessage('Bmp decrypted with success')
       else
       ShowMessage('Bmp can''t be decrypted !')

end;
那么,我如何将其导入FMX,仅此部分:

DecryptBmp(FHandle, FDestBmp.ScanLine[FDestBmp.Height-1]{Can we use the TBitmapData here ?},ASourceData, ASourceSize);

非常感谢

您需要直接“解密”到TBitmapSurface对象,而不是TBitmap,如下所示:

procedure TBmpDecrypter.Decrypt(ASourceData: pointer; ASourceSize: integer);
var
  isDecrypted:boolean;
  Surface: TBitmapSurface;
begin
  if FHandle = nil then Exit;
  Surface := TBitmapSurface.Create;
  try
    Surface.SetSize(FDestBmp.Width, FDestBmp.Height); //!!! see note below
    isDecrypted := DecryptBmp(FHandle, Surface.ScanLine[Surface.Height - 1], ASourceData, ASourceSize);
    FDestBmp.Assign(Surface);
    if isDecrypted then 
      ShowMessage('Bmp decrypted with success')
    else
      ShowMessage('Bmp can''t be decrypted !')
  finally
    Surface.Free;
  end;
end;
这假定DLL函数的第二个参数仅用于输出。如果它也用于输入,则需要执行此操作,而不是设置大小行:

Surface.Assign(FDestBmp);
风格的另一个未连接点:您不应该在出现错误时直接调用ShowMessage,而是引发异常:

type
  EDecryptBmpError = class(Exception);

//...

implementation

procedure TBmpDecrypter.Decrypt(ASourceData: pointer; ASourceSize: integer);
var
  Surface: TBitmapSurface;
begin
  if FHandle = nil then Exit;
  Surface := TBitmapSurface.Create;
  try
    Surface.SetSize(FDestBmp.Width, FDestBmp.Height);
    if not DecryptBmp(FHandle, Surface.ScanLine[Surface.Height - 1], ASourceData, ASourceSize) then
      raise EDecryptBmpError.Create('Bitmap cannot be decrypted');
    FDestBmp.Assign(Surface);
  finally
    Surface.Free;
  end;
end;

如果调用者想要显示一条消息,提醒用户解密成功,那么调用者应该自己做这件事(我很感激您可能只是出于调试目的才包含这一行,但这很难判断)。

您需要首先了解现有代码的实际功能。参数是什么,等等。签名是不够的。你应该看看调用代码和库文档。@David,我正在努力解决
FDestBmp.ScanLine[FDestBmp.Height-1]
这个模块是我的,正在我的VCL版本中使用。为什么在我实际回答了这个问题(答案被接受)之后,这个问题会被“搁置”呢?如果你们中有人在FMX方面有任何具体的经验,我会感到惊讶,因为问题在其他方面已经足够清楚了(最初的FMX TBitmap实际上有一个扫描线属性)。