Delphi端口代码从VCL到FMX

时间:2015-12-05 10:26:57

标签: delphi firemonkey

我是这个BitmapDecoder模块

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);
非常感谢

1 个答案:

答案 0 :(得分:2)

你需要解密'直接到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函数的第二个参数仅用于输出。如果它也是输入,那么你需要这样做而不是SetSize行:

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;

如果调用者想要显示一条警告用户成功解密的消息,那么调用者应该自己这样做(我感谢您可能只是为了调试目的而包含该行 - 这很难说)。