3

This is with Delphi Berlin 10.1 Update 2

The following works (I get a line drawn):

brush := TStrokeBrush.Create(TBrushKind.Solid, TAlphaColors.Lightgray);
brush.Thickness := 2;
with Canvas do
begin
    BeginUpdate;
    DrawLine(PointF(10, 10), PointF(100, 10), 1, brush);
    EndUpdate;
end;

The following does not work:

with Canvas do
begin
    BeginUpdate;
    Stroke.Color := TAlphaColors.Black;
    Stroke.Thickness := 2.0;
    DrawLine(PointF(10, 10), PointF(100, 10), 1);
    EndUpdate;
end;

Why can't I use the 2nd one? How can I get it to work, or should I stick to creating a stroke brush as in the first example?

I've included a minimal application:

main.pas

unit main;

interface

uses
    System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects;

type
    TMainForm = class(TForm)
        PaintBox: TPaintBox;
        procedure OnPaint(Sender: TObject; Canvas: TCanvas);
    private
        { Private declarations }
    public
        { Public declarations }
    end;

var
    MainForm: TMainForm;

implementation

{$R *.fmx}

procedure TMainForm.OnPaint(Sender: TObject; Canvas: TCanvas);
begin
    with Canvas do
    begin
        BeginUpdate;
        Stroke.Color := TAlphaColors.Black;
        Stroke.Thickness := 2.0;
        DrawLine(PointF(10, 10), PointF(100, 10), 1);
        EndUpdate;
    end;
end;

end.

main.fmx:

object MainForm: TMainForm
    Left = 0
    Top = 0
    Caption = 'Form1'
    ClientHeight = 480
    ClientWidth = 640
    FormFactor.Width = 320
    FormFactor.Height = 480
    FormFactor.Devices = [Desktop]
    DesignerMasterStyle = 0
    object PaintBox: TPaintBox
        Position.X = 16.000000000000000000
        Position.Y = 16.000000000000000000
        Size.Width = 609.000000000000000000
        Size.Height = 449.000000000000000000
        Size.PlatformDefault = False
        OnPaint = OnPaint
    end
end

test.dpr:

program test;

uses
   System.StartUpCopy,
   FMX.Forms,
   main in 'main.pas' {MainForm};

{$R *.res}

begin
    Application.Initialize;
    Application.CreateForm(TMainForm, MainForm);
    Application.Run;
end.
imekon
  • 1,501
  • 4
  • 22
  • 39
  • The code in your second example is fine. Please show a [mcve]. Are you perhaps trying to draw outside the `Paint` method or `OnPaint` handlers? – J... Nov 18 '16 at 13:07
  • 2
    `Stroke.Kind := TBrushKind.bkSolid;` may be needed on Android, since it is `bkNone` by default. On Windows the default value is `bkSolid`. – LU RD Nov 18 '16 at 13:31
  • I've added the minimal files needed to show the issue – imekon Nov 18 '16 at 14:15
  • @imekon Then certainly your code works fine for me (10.1 Seattle, windows) - are you compiling for android? ios? mac? – J... Nov 18 '16 at 14:30
  • Windows 32 bit debug or Mac OS X – imekon Nov 18 '16 at 14:34
  • @LURD `Stroke.Kind` seems to be `None` in D 10.1 Berlin as default. Adding as you suggested worked in my test. Maybe you should put it up as an answer. – Tom Brunberg Nov 18 '16 at 18:09
  • @J... Also to confirm your observation, it works without setting `Stroke.Kind` in D 10 Seattle, but in 10.1 Berlin it needs to be set – Tom Brunberg Nov 18 '16 at 18:18
  • 4
    You really need to stop using with – David Heffernan Nov 19 '16 at 07:12
  • I was just beating my head over this same problem, except I already was assigning `Stroke.Kind` yet still nothing. Turned out I was dumb and used `TColorRec.Red` instead of `TAlphaColors.Red`. It still compiles and runs, but has the wrong value. – Jerry Dodge Mar 12 '19 at 00:30

2 Answers2

6

Earlier versions of Delphi had different default values for Stroke.Kind depending on platform.

Since Delphi 10.1 Berlin, the default value seems to be Nonefor all platforms. (Thanks @TomBrunberg)

To make the line appear, set Stroke.Kind := TBrushKind.Solid;

Note: Tested on Windows 8.1


I created a new Metropolis FMX application as well, where the drawing worked without setting the Stroke.Kind. Can't explain that though.


A similar report was filed at QP, RSP-16313 The Canvas.DrawLine doesn't work at Windows XP (32 bit) forms. Here the problem manifests on Windows-XP but not on Windows-7.

LU RD
  • 34,438
  • 5
  • 88
  • 296
  • Bingo! Adding Stroke.Kind := TBrushKind.Solid was the answer. But why was such an odd default added? – imekon Nov 20 '16 at 20:45
  • I don't know. Perhaps the value is not persistant at all, but varies depending on context. Anyway, always setting it to solid before writing, works in all circumstances. – LU RD Nov 20 '16 at 20:59
1

it's very strange that first case is work.

You should use stroke brush.

And you Should use BeginScene and EndScene instead of BeginUpdate and EndUpdate. This fragment works perfect:

  Brush := TStrokeBrush.Create(TBrushKind.Solid, TAlphaColors.Black);
  Brush.Thickness := 2;
  with Canvas do
  begin
    BeginScene();
    DrawLine(PointF(10, 10), PointF(100, 10), 1, Brush);
    EndScene;
  end;
Dimsa
  • 272
  • 4
  • 13
  • The question states that using a separate Brush works and asks why using DrawLine without such a Brush does not work. Using BeginScene/EndScene in an OnPaint event is not needed. – LU RD Nov 20 '16 at 18:32
  • This doesn't work - even if I use BeginScene/EndScene: with Canvas do begin BeginScene; Stroke.Color := TAlphaColors.Black; Stroke.Thickness := 2.0; DrawLine(PointF(10, 10), PointF(100, 10), 1); EndScene; end; – imekon Nov 20 '16 at 20:42