Project JEDI - Issue Tracker
Mantis Bugtracker

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0006671 [JEDI VCL] 00 JVCL Components crash always 2019-04-15 14:57 2019-04-17 16:40
Reporter mh View Status public  
Assigned To AHUser
Priority normal Resolution fixed  
Status resolved   Product Version 3.48
Summary 0006671: Changing TJvDialButton Frequency, Min or Max at runtime leads to exception
Description Trying to set frequency, min or max property of a TJvDialButton, which had been created at runtime in code, crashes with access violation. The crash is in Unit Vcl.Graphics in the if of this function:

function TBitmap.GetCanvas: TCanvas;
  if FCanvas = nil then

The crash happens after the parent of the TJvDialButton instance had been set. It does not crash if the new value is the default value or if the assignment of the value is before setting the parent.

Additional Information
Tags No tags attached.
Attached Files zip file icon [^] (53,631 bytes) 2019-04-15 15:12

- Relationships

-  Notes
mh (reporter)
2019-04-15 22:22

While I have the question why the Rio Debugger doesn't properly let me debug JVCL (\run directory is in the search path, optimization is off), I land in CPU view and breakpoints inside JvDialButton unit are not honored I managed to find out, that the TBitmap.GetCanvas call which fails fails, because the TBitMap object is nil and the call is in this method:

procedure TJvCustomDialButton.SetTick(Value: Integer; Length: TJvTickLength);
  Lengths: array [TJvTickLength] of Byte =
    (tlShortLen, tlMiddleLen, tlLongLen);
  P: PTick;
  I: Integer;
  if (Value < FMin) or (Value > FMax) then
    raise EInvalidOperation.CreateResFmt(@SOutOfRange, [FMin, FMax]);
  for I := 0 to FTicks.Count - 1 do
    P := FTicks.Items[I];
    if P^.Value = Value then
      if P^.Length <> Lengths[Length] then
        P^.Length := Lengths[Length];
        P^.Changed := True;
  P^.Value := Value;
  P^.Length := Lengths[Length];
  P^.Changed := True;
  P^.Color := clBtnText;
  if HandleAllocated then
    DrawTick(FBitmap.Canvas, P^);
    DrawTick(Canvas, P^);

I suspect it is the DrawTick(FBitmap.Canvas, P^); call.
mh (reporter)
2019-04-15 22:54

Further investigation result: FBitmap is being created in the BitmapNeeded method, which is called in two places:

- Paint method
- DrawBorder method.

Ok, FBitmap is not created if we create the component at runtime in code and set Max before it had any chance to get itsself painted.

=> BitmapNeeded method must be called "earlier", but that one contains calls to DrawButton and DrawTicks.
mh (reporter)
2019-04-15 23:00

I tried to place a call to BitmapNeeded as first call in SetMax method to test what happens, but it looks like it never got called.

I created a public method in TJvDialButton which simply calls Bitmap needed, but the compiler says he cannot find this method. But I did save the JVCL unit, did a clean of the demo (the one in the zip of this issue) and checked if I altered the right copy of JvDialButton.pas. What did I do wrong?
mh (reporter)
2019-04-15 23:01

Did another test, altered the Unit1.pas of the attached zip file like this and found out by this, that it works then:

unit Unit1;


  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ExtCtrls, Vcl.ToolWin,
  Vcl.StdCtrls, JvDialButton;

  TMyDialButton = class(TJvDialButton)
    procedure DoBitmapNeeded;

  TForm1 = class(TForm)
    FlowPanel1: TFlowPanel;
    CrashButton: TButton;
    procedure CrashButtonClick(Sender: TObject);
// TestDialButton : TJvDialButton;
    TestDialButton : TMyDialButton;
    procedure CreateJvDialogButton;
    { Public-Deklarationen }

  Form1: TForm1;


{$R *.dfm}

{ TForm1 }

procedure TForm1.CrashButtonClick(Sender: TObject);

procedure TForm1.CreateJvDialogButton;
// TestDialButton := TJvDialButton.Create(FlowPanel1);
  TestDialButton := TMyDialButton.Create(FlowPanel1);
  TestDialButton.Parent := FlowPanel1;
  TestDialButton.Max := 200;

{ TMyDialButton }

procedure TMyDialButton.DoBitmapNeeded;

Talkbaze (reporter)
2019-04-16 17:35 [^]
mh (reporter)
2019-04-16 19:25

Proposed a fix via pull request: [^]
AHUser (developer)
2019-04-17 16:40

Fixed in master branch.

- Issue History
Date Modified Username Field Change
2019-04-15 14:57 mh New Issue
2019-04-15 15:12 mh File Added:
2019-04-15 22:22 mh Note Added: 0021703
2019-04-15 22:54 mh Note Added: 0021704
2019-04-15 23:00 mh Note Added: 0021705
2019-04-15 23:01 mh Note Added: 0021706
2019-04-16 17:35 Talkbaze Note Added: 0021707
2019-04-16 19:25 mh Note Added: 0021708
2019-04-17 16:40 AHUser Note Added: 0021716
2019-04-17 16:40 AHUser Status new => resolved
2019-04-17 16:40 AHUser Fixed in Version => Daily / GIT
2019-04-17 16:40 AHUser Resolution open => fixed
2019-04-17 16:40 AHUser Assigned To => AHUser

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker