View Issue Details

IDProjectCategoryView StatusLast Update
0025868LazarusLCLpublic2016-12-20 17:13
ReporterwpAssigned ToOndrej Pokorny 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformi86OSWinOS VersionWin7
Product Version1.3 (SVN)Product Build 
Target Version1.6.4Fixed in Version1.7 (SVN) 
Summary0025868: Groupbox hides contained Label when Groupbox.Caption is changed
DescriptionIf a groupbox contains a label and the caption of the group box is changed at runtime the label is suddenly not visible any more.

This seems to be related to Windows since the behavior is correct under Ubuntu. The behavior is correct also in Delphi 7.
Steps To ReproduceRun attached demo: the groupbox contains a TLabel, a TEdit and a TStaticText. Click on the button to change the caption of the groupbox. Afterwards the Label is no longer visible. The other controls are still visible.

Of course, a "GroupBox.Invalidate" or "Groupbox.Refresh" after changing the caption restores the label.
TagsNo tags attached.
Fixed in Revision53736
LazTarget-
WidgetsetWin32/Win64
Attached Files
  • groupbox.zip (4,345 bytes)
  • pic1.PNG (21,589 bytes)
    pic1.PNG (21,589 bytes)
  • pic2.PNG (20,283 bytes)
    pic2.PNG (20,283 bytes)
  • control.inc.patch (474 bytes)
    Index: lcl/include/control.inc
    ===================================================================
    --- lcl/include/control.inc	(revision 51109)
    +++ lcl/include/control.inc	(working copy)
    @@ -4790,6 +4790,7 @@
       //  debugln('TControl.SetText END ',DbgSName(Self),' FCaption="',FCaption,'"');
       if HostDockSite <> nil then
         HostDockSite.UpdateDockCaption(nil);
    +  Invalidate;
     end;
     
     {------------------------------------------------------------------------------
    
    control.inc.patch (474 bytes)
  • grp.diff (1,367 bytes)
    Index: lcl/include/customgroupbox.inc
    ===================================================================
    --- lcl/include/customgroupbox.inc	(revision 53724)
    +++ lcl/include/customgroupbox.inc	(working copy)
    @@ -8,6 +8,19 @@
      *****************************************************************************
     }
     
    +function TCustomGroupBox.GetCaption: TCaption;
    +begin
    +  Result := inherited Caption;
    +end;
    +
    +procedure TCustomGroupBox.SetCaption(const AValue: TCaption);
    +begin
    +  inherited Caption := AValue;
    +  {$ifdef windows}
    +  Invalidate; // Mantis #25868
    +  {$endif}
    +end;
    +
     class procedure TCustomGroupBox.WSRegisterClass;
     begin
       inherited WSRegisterClass;
    Index: lcl/stdctrls.pp
    ===================================================================
    --- lcl/stdctrls.pp	(revision 53724)
    +++ lcl/stdctrls.pp	(working copy)
    @@ -157,6 +157,9 @@
       { TCustomGroupBox }
     
       TCustomGroupBox = class(TWinControl)
    +  private
    +    function GetCaption: TCaption;
    +    procedure SetCaption(const AValue: TCaption);
       protected
         class procedure WSRegisterClass; override;
         class function GetControlClassDefaultSize: TSize; override;
    @@ -163,6 +166,7 @@
         procedure CreateParams(var Params: TCreateParams); override;
       public
         constructor Create(AOwner: TComponent); override;
    +    property Caption: TCaption read GetCaption write SetCaption;
       end;
     
     
    
    grp.diff (1,367 bytes)
  • grp2.diff (1,335 bytes)
    Index: lcl/include/customgroupbox.inc
    ===================================================================
    --- lcl/include/customgroupbox.inc	(revision 53724)
    +++ lcl/include/customgroupbox.inc	(working copy)
    @@ -8,6 +8,17 @@
      *****************************************************************************
     }
     
    +function TCustomGroupBox.GetCaption: TCaption;
    +begin
    +  Result := inherited Caption;
    +end;
    +
    +procedure TCustomGroupBox.SetCaption(const AValue: TCaption);
    +begin
    +  inherited Caption := AValue;
    +  Invalidate; // Mantis #25868
    +end;
    +
     class procedure TCustomGroupBox.WSRegisterClass;
     begin
       inherited WSRegisterClass;
    Index: lcl/stdctrls.pp
    ===================================================================
    --- lcl/stdctrls.pp	(revision 53724)
    +++ lcl/stdctrls.pp	(working copy)
    @@ -157,6 +157,9 @@
       { TCustomGroupBox }
     
       TCustomGroupBox = class(TWinControl)
    +  private
    +    function GetCaption: TCaption;
    +    procedure SetCaption(const AValue: TCaption);
       protected
         class procedure WSRegisterClass; override;
         class function GetControlClassDefaultSize: TSize; override;
    @@ -163,6 +166,7 @@
         procedure CreateParams(var Params: TCreateParams); override;
       public
         constructor Create(AOwner: TComponent); override;
    +    property Caption: TCaption read GetCaption write SetCaption;
       end;
     
     
    
    grp2.diff (1,335 bytes)

Activities

wp

2014-03-15 18:40

developer  

groupbox.zip (4,345 bytes)

Bart Broersma

2014-03-15 18:58

developer   ~0073732

Same here (Lazarus 1.3 r44418 FPC 2.6.4 i386-win32-win32/win64).

FTurtle

2015-12-31 16:16

reporter   ~0088473

The same is in Lazarus 1.6 RC1

FTurtle

2015-12-31 16:56

reporter   ~0088476

Last edited: 2016-01-01 20:04

View 2 revisions

> If a groupbox contains a label and the caption of the group box is changed at runtime the label is suddenly not visible any more.

1. In form designer occurs the same.
2. The same behavior also occurs with other descendants of TGraphicControl: TSpeedButton, TBevel, TShape and etc.

> Of course, a "GroupBox.Invalidate" or "Groupbox.Refresh" after changing the caption restores the label.

So, the bug may be fixed easily.

FTurtle

2016-01-01 22:30

reporter  

pic1.PNG (21,589 bytes)
pic1.PNG (21,589 bytes)

FTurtle

2016-01-01 22:31

reporter  

pic2.PNG (20,283 bytes)
pic2.PNG (20,283 bytes)

FTurtle

2016-01-01 22:32

reporter   ~0088512

In addition I found that:

1. All descendants of TCustomGroupBox (not only TGroupBox, but also TRadioGroup and TCheckGroup) in form designer can accept other controls. (I dont know is it bug or feature).
2. All descendants of TCustomGroupBox after changing their Caption dont redraw their children which are descendants of TGraphicControl.
3. Later all children redraw correctly. At runtime enough move mouse over parent. In form designer enough click on form.

See pic1.png, pic2.png

wp

2016-01-02 01:11

developer  

control.inc.patch (474 bytes)
Index: lcl/include/control.inc
===================================================================
--- lcl/include/control.inc	(revision 51109)
+++ lcl/include/control.inc	(working copy)
@@ -4790,6 +4790,7 @@
   //  debugln('TControl.SetText END ',DbgSName(Self),' FCaption="',FCaption,'"');
   if HostDockSite <> nil then
     HostDockSite.UpdateDockCaption(nil);
+  Invalidate;
 end;
 
 {------------------------------------------------------------------------------
control.inc.patch (474 bytes)

wp

2016-01-02 01:15

developer   ~0088516

Last edited: 2016-01-05 17:55

View 2 revisions

I attached a possible patch which just calls Invalidate at the end of TControl.SetText. Because SetText is not virtual the patch reaches deeply into the heart of the LCL... But can an unnecessary call of Invalidate be harmful to other controls?

Alexey Tor.

2016-12-20 02:45

reporter  

grp.diff (1,367 bytes)
Index: lcl/include/customgroupbox.inc
===================================================================
--- lcl/include/customgroupbox.inc	(revision 53724)
+++ lcl/include/customgroupbox.inc	(working copy)
@@ -8,6 +8,19 @@
  *****************************************************************************
 }
 
+function TCustomGroupBox.GetCaption: TCaption;
+begin
+  Result := inherited Caption;
+end;
+
+procedure TCustomGroupBox.SetCaption(const AValue: TCaption);
+begin
+  inherited Caption := AValue;
+  {$ifdef windows}
+  Invalidate; // Mantis #25868
+  {$endif}
+end;
+
 class procedure TCustomGroupBox.WSRegisterClass;
 begin
   inherited WSRegisterClass;
Index: lcl/stdctrls.pp
===================================================================
--- lcl/stdctrls.pp	(revision 53724)
+++ lcl/stdctrls.pp	(working copy)
@@ -157,6 +157,9 @@
   { TCustomGroupBox }
 
   TCustomGroupBox = class(TWinControl)
+  private
+    function GetCaption: TCaption;
+    procedure SetCaption(const AValue: TCaption);
   protected
     class procedure WSRegisterClass; override;
     class function GetControlClassDefaultSize: TSize; override;
@@ -163,6 +166,7 @@
     procedure CreateParams(var Params: TCreateParams); override;
   public
     constructor Create(AOwner: TComponent); override;
+    property Caption: TCaption read GetCaption write SetCaption;
   end;
 
 
grp.diff (1,367 bytes)

Alexey Tor.

2016-12-20 02:46

reporter   ~0096944

Last edited: 2016-12-20 02:47

View 2 revisions

Grp.diff== more correct fix; not touches TControl,
calls Invalidate inside {$ifdef}

Fix still needed for Win10

Ondrej Pokorny

2016-12-20 08:20

reporter   ~0096946

Please don't use IFDEF in LCLBase (if not absolutely necessary). Platform-dependent code goes into WS-level.

Zeljan Rikalo

2016-12-20 09:51

developer   ~0096947

And please in any case do not use IFDEF MSWINDOWS in LCLBase, but IFDEF LCLWin32 if it's a must, since Qt works under windows too and does not need win32 fixes.

Alexey Tor.

2016-12-20 14:26

reporter  

grp2.diff (1,335 bytes)
Index: lcl/include/customgroupbox.inc
===================================================================
--- lcl/include/customgroupbox.inc	(revision 53724)
+++ lcl/include/customgroupbox.inc	(working copy)
@@ -8,6 +8,17 @@
  *****************************************************************************
 }
 
+function TCustomGroupBox.GetCaption: TCaption;
+begin
+  Result := inherited Caption;
+end;
+
+procedure TCustomGroupBox.SetCaption(const AValue: TCaption);
+begin
+  inherited Caption := AValue;
+  Invalidate; // Mantis #25868
+end;
+
 class procedure TCustomGroupBox.WSRegisterClass;
 begin
   inherited WSRegisterClass;
Index: lcl/stdctrls.pp
===================================================================
--- lcl/stdctrls.pp	(revision 53724)
+++ lcl/stdctrls.pp	(working copy)
@@ -157,6 +157,9 @@
   { TCustomGroupBox }
 
   TCustomGroupBox = class(TWinControl)
+  private
+    function GetCaption: TCaption;
+    procedure SetCaption(const AValue: TCaption);
   protected
     class procedure WSRegisterClass; override;
     class function GetControlClassDefaultSize: TSize; override;
@@ -163,6 +166,7 @@
     procedure CreateParams(var Params: TCreateParams); override;
   public
     constructor Create(AOwner: TComponent); override;
+    property Caption: TCaption read GetCaption write SetCaption;
   end;
 
 
grp2.diff (1,335 bytes)

Alexey Tor.

2016-12-20 14:26

reporter   ~0096949

Added new grp2.diff

Ondrej Pokorny

2016-12-20 15:08

reporter   ~0096950

Overloading a property is a no-go.

Fixed on WS-level.

wp

2016-12-20 17:13

developer   ~0096955

Thanks for fixing. In the uploaded demo, there seems to be some slight flicker of the label, though, - but this is considerably less evident than the missing groupbox caption title.

Issue History

Date Modified Username Field Change
2014-03-15 18:40 wp New Issue
2014-03-15 18:40 wp File Added: groupbox.zip
2014-03-15 18:58 Bart Broersma LazTarget => -
2014-03-15 18:58 Bart Broersma Note Added: 0073732
2014-03-15 18:58 Bart Broersma Status new => confirmed
2015-12-31 16:16 FTurtle Note Added: 0088473
2015-12-31 16:56 FTurtle Note Added: 0088476
2016-01-01 20:04 FTurtle Note Edited: 0088476 View Revisions
2016-01-01 22:30 FTurtle File Added: pic1.PNG
2016-01-01 22:31 FTurtle File Added: pic2.PNG
2016-01-01 22:32 FTurtle Note Added: 0088512
2016-01-02 01:11 wp File Added: control.inc.patch
2016-01-02 01:15 wp Note Added: 0088516
2016-01-05 17:55 wp Note Edited: 0088516 View Revisions
2016-12-20 02:45 Alexey Tor. File Added: grp.diff
2016-12-20 02:46 Alexey Tor. Note Added: 0096944
2016-12-20 02:47 Alexey Tor. Note Edited: 0096944 View Revisions
2016-12-20 08:20 Ondrej Pokorny Note Added: 0096946
2016-12-20 08:20 Ondrej Pokorny Assigned To => Ondrej Pokorny
2016-12-20 08:20 Ondrej Pokorny Status confirmed => assigned
2016-12-20 09:51 Zeljan Rikalo Note Added: 0096947
2016-12-20 14:26 Alexey Tor. File Added: grp2.diff
2016-12-20 14:26 Alexey Tor. Note Added: 0096949
2016-12-20 15:08 Ondrej Pokorny Fixed in Revision => 53736
2016-12-20 15:08 Ondrej Pokorny Note Added: 0096950
2016-12-20 15:08 Ondrej Pokorny Status assigned => resolved
2016-12-20 15:08 Ondrej Pokorny Resolution open => fixed
2016-12-20 15:11 Ondrej Pokorny Fixed in Version => 1.7 (SVN)
2016-12-20 15:11 Ondrej Pokorny Target Version => 1.6.4
2016-12-20 17:13 wp Note Added: 0096955
2016-12-20 17:13 wp Status resolved => closed