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.