0

I'm creating a project in Embarcadero RAD Studio XE7, in which I created a custom TGraphic component, available in a package. I also created a demo project, in which I use this custom TGraphic to populate a TImage component.

All is running well as long as I compile and run my project in 32 bit. However I noticed a strange behavior when I compile and run it in 64 bit. Doing that, the TImage content is no longer visible until I refresh it. The only difference between the both versions is just that one is compiled in 32 bit, and the other is compiled in 64 bit.

I recreated a similar behavior in a separate project, for which I provide the source below.

Main.pas

unit Main;

interface

uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Winapi.GDIPAPI, Winapi.GDIPObj, Vcl.ExtCtrls, Vcl.StdCtrls;

type
    TMainForm = class(TForm)
        im1: TImage;
        bt1: TButton;

        procedure bt1Click(Sender: TObject);

    private
        pBitmap:TBitmap;

    public
        constructor Create(pOwner: TComponent); override;
        destructor Destroy; override;
        procedure DrawGradient; virtual;
    end;

var
    MainForm: TMainForm;

implementation

{$R *.dfm}

constructor TMainForm.Create(pOwner: TComponent);
begin
    inherited Create(pOwner);

    pBitmap:=TBitmap.Create;
    pBitmap.PixelFormat := pf24bit;
    pBitmap.SetSize(600, 600);
    DrawGradient;
    im1.Picture.Bitmap.Assign(pBitmap);
end;

destructor TMainForm.Destroy;
begin
    FreeAndNil(pBitmap);
    inherited Destroy;
end;

procedure TMainForm.bt1Click(Sender: TObject);
begin
    DrawGradient;
    im1.Picture.Bitmap.Assign(pBitmap);
    im1.Invalidate;
end;

procedure TMainForm.DrawGradient;
var
    startPoint: TGpPointF;
    endPoint: TGpPointF;
    startColor: TGpColor;
    endColor: TGpColor;
    rect: TGPRectF;
    pBrush: TGpLinearGradientBrush;
    pGraphics: TGpGraphics;
    pGraphicPath: TGpGraphicsPath;
    colors: array of TGpColor;
    offsets: array of Single;
    pMatrix: TGpMatrix;
begin
    pGraphics := TGpGraphics.Create(pBitmap.Canvas.Handle);

    startPoint.X := 360.499053955078;
    startPoint.Y := 598.405334472656;
    endPoint.X   := 354.387237548828;
    endPoint.Y   := 456.281829833984;

    startColor := 4289977853;
    endColor   := 4281558680;

    pBrush := TGpLinearGradientBrush.Create(startPoint, endPoint, startColor, endColor);
    pBrush.SetWrapMode(WrapModeClamp);

    SetLength(colors,  4);
    SetLength(offsets, 4);

    colors[0] := startColor;
    offsets[0] := 0.0;
    colors[1] := startColor;
    offsets[1] := 0.207910388708115;
    colors[2] := endColor;
    offsets[2] := 0.981223344802856;
    colors[3] := endColor;
    offsets[3] := 1.0;

    pBrush.SetInterpolationColors(PGpColor(colors), PSingle(offsets), 4);

    rect.X      := 292.332000732422;
    rect.Y      := 458.950439453125;
    rect.Width  := 93.1629943847656;
    rect.Height := 138.380004882813;

    pGraphicPath := TGpGraphicsPath.Create;
    pGraphicPath.AddRectangle(rect);

    pMatrix := TGpMatrix.Create;
    pMatrix.SetElements( 0.0,                   0.0,
                         0.0,                   0.835756719112396,
                        -3.23515876073745e-35, -363.817687988281);
    pGraphics.SetTransform(pMatrix);

    pGraphics.FillPath(pBrush, pGraphicPath);

    FreeAndNil(pMatrix);
    FreeAndNil(pGraphicPath);
    FreeAndNil(pBrush);
    FreeAndNil(pGraphics);
end;

end.

Main.dfm

object MainForm: TMainForm
    Left = 0
    Top = 0
    Caption = 'MainForm'
    ClientHeight = 430
    ClientWidth = 400
    Color = clBtnFace
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    OldCreateOrder = False
    PixelsPerInch = 96
    TextHeight = 13
    object im1: TImage
        Left = 0
        Top = 0
        Width = 400
        Height = 400
        Center = True
        Proportional = True
        Stretch = True
    end
    object bt1: TButton
        Left = 0
        Top = 405
        Width = 400
        Height = 25
        Align = alBottom
        Caption = 'bt1'
        TabOrder = 0
        OnClick = bt1Click
        ExplicitLeft = 22
        ExplicitTop = 183
        ExplicitWidth = 75
    end
end

The project was created with the default compiler options. When I compile the above project in 64 bit, nothing is shown in the TImage until I click on the button, whereas the TImage content is visible without problems as long as I compile and run it in 32 bit. Once again, the only difference between the both versions is just the first is compiled in 32 bit, and the other in 64 bit. Nothing else is modified, neither in project options nor in code. I'm working with XE7, but I also noticed the same behavior in all compiler versions between XE8 and 10.3 Rio.

Am I doing something wrong, or someone else notice the same behavior? If I'm wrong, what is my mistake? Or it is a compiler bug?

NOTE I'm aware that the above code is ugly, inefficient, and probably filled with design errors. The purpose here was to reproduce a bug I'm facing in another project, for which I cannot publish the source code. Please don't care about the code quality, it's really not the point here.

Jean-Milost Reymond
  • 1,833
  • 1
  • 15
  • 36

0 Answers0