首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使使用TBitmap的函数为FireMonkey和VCL工作?

如何使使用TBitmap的函数为FireMonkey和VCL工作?
EN

Stack Overflow用户
提问于 2018-02-27 20:22:47
回答 5查看 1.1K关注 0票数 6

在火猴上,TBitmapFmx.graphics.TBitmap,而在VCL上是VCL.graphics.Tbitmap。它们的接口非常相似,我想创建(例如,这个函数)

代码语言:javascript
复制
function resizeBitmap(const aBitmap: Tbitmap; const w, h: integer);

由于resizeBitmap中的代码与Fmx.graphics.TBitmapVCL.graphics.Tbitmap的代码完全相同,所以我想让VCL应用程序和FMX应用程序都可以使用这个函数(而不重复它,因为这意味着我只需要通过代码复制并通过VCL.graphics.Tbitmap替换uses Fmx.graphics.TBitmap )。

他们是一种方式或条件的定义,可以帮助我在这份工作?

EN

回答 5

Stack Overflow用户

发布于 2018-02-27 21:10:13

不幸的是,在Delphi中没有预先定义的条件定义来区分FMX和VCL。幸运的是,你可以用很少的努力就能得到一个。在%APPDATA%\Embarcadero\BDS\19.0 (用于东京)中创建一个名为UserTools.proj的文件,并为其提供以下内容:

代码语言:javascript
复制
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
       <DCC_Define>FrameWork_$(FrameworkType);$(DCC_Define)</DCC_Define>
    </PropertyGroup>
</Project>

这样可以检查代码中的框架,如下所示:

代码语言:javascript
复制
{$IFDEF FrameWork_VCL}
{$IFDEF FrameWork_FMX}
{$IFDEF FrameWork_None}

缺点是该文件是特定于用户的。

票数 3
EN

Stack Overflow用户

发布于 2018-02-27 21:05:38

您可以将其包括:

文件bitmapcode.inc

代码语言:javascript
复制
// Here, TBitmap is either VCL or FMX, depending on where you include this. 
procedure ResizeBitmap(Bitmap: TBitmap; NewWidth, NewHeight: Integer);
begin
  Bitmap.Width := NewWidth;
  Bitmap.Height := NewHeight
end;

现在,使用以下内容创建一个名为VCL.BitmapTools.pas的单元:

代码语言:javascript
复制
unit VCL.BitmapTools;

interface

uses VCL.Graphics {and what else you need} ;

// Here, TBitmap is VCL.Graphics.TBitmap
procedure ResizeBitmap(Bitmap: TBitmap; NewWidth, NewHeight: Integer);

implementation

{$INCLUDE bitmapcode.inc}

end.

并对FMX做同样的操作:

代码语言:javascript
复制
unit FMX.BitmapTools;

interface

uses FMX.Graphics; // etc...

// Here, TBitmap is FMX.Graphics.TBitmap
procedure ResizeBitmap(Bitmap: TBitmap; NewWidth, NewHeight: Integer);

implementation

{$INCLUDE bitmapcode.inc}

end.

因此,您可以得到两个不同的单元,一个用于VCL,另一个用于FMX,但是(几乎)没有代码重复。

无泛型

注意,使用泛型是

  • 如果你这样做就没必要了
  • “泛型”位图不可能

因为在代码中

代码语言:javascript
复制
SomeClass<T>.ResizeBitmap(Bitmap: T; NewWidth, NewHeight: Integer); 

T根本没有任何属性或方法,当然也没有像WidthHeight这样的属性,所以任何使用它们的代码都不会编译。

条件编译

或者,您可以使用条件编译:

代码语言:javascript
复制
uses
{$IF declared(FireMonkeyVersion)}
  FMX.Graphics;
{$ELSE}
  VCL.Graphics;
{$IFEND}

但是,同样地,也不需要泛型:

代码语言:javascript
复制
procedure ResizeBitmap(Bitmap: TBitmap; NewWidth, NewHeight: Integer);
begin
  Bitmap.Width := NewWidth;
  Bitmap.Height := NewHeight;
end;

因为TBitmap将引用有条件编译的TBitmap。所以忘了仿制药吧。使用上述方法之一。

票数 1
EN

Stack Overflow用户

发布于 2018-02-28 10:58:38

另一种方法是定义一个具有两个TBitmap版本特征的接口:

代码语言:javascript
复制
type
  IBitmap = interface
  [GUID here]
    function GetWidth: Integer; // or Single
    procedure SetWidth(Value: Integer);
    // etc...
    property Width: Integer read GetWidth write SetWidth;
    // etc...
  end;

然后写两个包装器,每种位图一个:

代码语言:javascript
复制
type
  TVCLBitmapWrapper = class(TInterfacedObject, IBitmap)
  private
    FBitmap: VCL.Graphics.TBitmap;
  public
    constructor Create(From: VCL.Graphics.TBitmap);
    function GetWidth: Integer;
    // etc...
  end;

和FMX类似的版本。然后,您可以将这些传递给您的函数:

代码语言:javascript
复制
procedure SetBitmapSize(const Bitmap: IBitmap; H, W: Integer);

然后打电话给:

代码语言:javascript
复制
SetBitmapSize(TVCLBitmapWrapper.Create(MyVCLBitmap) as IBitmap, 33, 123);

代码语言:javascript
复制
SetBitmapSize(TFMXBitmapWrapper.Create(MyFMXBitmap) as IBitmap, 127, 99);

当然,如果必须将其传递给多个函数,首先创建包装器,将其传递给这些函数,然后,如果需要,则为零。

编写包装器对于一个简单的函数(如SetBitmapSize )来说是过分的,但是如果您有许多函数,这可能是有意义的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49017299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档