View Issue Details

IDProjectCategoryView StatusLast Update
0031993LazarusLCLpublic2017-06-29 15:52
ReporterSoner Assigned Towp  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Product Version1.6.4 
Target Version1.8RC2 
Summary0031993: (Patch)RadioItems from TDBRadioGroup is changeable also by TDataSet.ReadOnly=true
DescriptionRadioItems from TDBRadioGroup is changeable also when associated TDataSet is ReadOnly.
The Datafield value does not changed only the Radioitems can be selected.
Steps To Reproduce1) Start the example
2) Click readonly-Button
3) Click on the DBRAdioGroup on the left.
4) Look in the grid, the value doesn't changed only
 the selected RadioButton is changed.
5) Apply my patch and start the example again.
Additional InformationThis is the Patch (only the last 4 lines):
procedure TDBRadioGroup.UpdateRadioButtonStates;
// .. dont change it shows only where to add the patch
  if (NewValue<>OldValue) and FDatalink.CanModify and not SettingValue then
// .. dont change it shows only where to add the patch
    //; Soner FOLLOWING IS PATCH ..........
  else if (not DataLink.CanModify) and (DataLink.Field.AsString<>NewValue) then begin
    fValue:=''; // because in procedure TDBRadioGroup.SetValue is
                // if FValue=AValue then exit;
    Value:= OldValue;
TagsNo tags attached.
Fixed in Revision55344
Attached Files


duplicate of 0021099 resolvedLuiz Americo Packages DBRadioGroup Behavior 
related to 0032077 resolvedwp Lazarus Access Violation in TDBRadioGroup.UpdateRadioButtonStates 



2017-06-09 21:33


Juha Manninen

2017-06-11 10:43

developer   ~0101018

Please create a proper patch.


2017-06-11 14:21

reporter   ~0101020

Last edited: 2017-06-11 14:33

View 2 revisions

Possible solution that works(note: "and DataLink.Active " ) :
Change the file: lcl\include\
Add the end of the procedure TDBRadioGroup.UpdateRadioButtonStates;
following lines:
  //; <- comment out ;
  else if (not DataLink.CanModify) and (DataLink.Active) and (DataLink.Field.AsString<>NewValue) then begin
   fValue:=''; // because in procedure TDBRadioGroup.SetValue is:
               // if FValue=AValue then exit;
   Value:= OldValue;


2017-06-11 14:30

reporter   ~0101021

@Juna Manninen
I can't send proper patch, because:
 - this isn't patch, it is possible solution.
 - I don't have svn-Version from Lazarus and I can't just download svn-Version, because I have only 56K internet connection (mobile Smart-phone connection).
I download new or fixed Versions from Lazarus in Office or by friends.

Sorry for misleading issue title, in future I will not call it patch, when it isn't patch.
Sorr again.

Juha Manninen

2017-06-11 20:51

developer   ~0101027

The initial loading of SVN version takes bandwidth.
After that only diffs for the latest changes are downloaded (eg. "svn up") and the bandwidth usage is minimal.
You use much more bandwidth when downloading the release versions with binaries and all included.


2017-06-13 00:24

developer   ~0101072

The patch works, but I am not sure if it fixes the right place. The patch just reverts a change of the radiogroup's ItemIndex if the dataset is readonly. I think the correct fix should not allow the radiogroup to change at all. Unfortunately, TCustomRadioGroup does not have a ReadOnly property, and according to 0021099, it probably will never have one. There is a method "CanModify" which could be overridden to return FDataLink.CanModify, but it does not seem to be fully implemented.


2017-06-13 11:48

reporter   ~0101080

I followed your idea and found possible solution, this works also with normal TRadioButtons.
To set the TRadioButtons ClicksDisabled property automatically, we can use TDataLink.SetReadOnly or similar. I set ClicksDisabled in example programm self.

Here is possible solution:
1)In lazarus\lcl\interfaces\win32\
//soner: Add this from here .....
// (remove this after moving TButtonControl.ClicksDisabled in public-area)
  TButtonControlHack = class(TButtonControl)
    property ClicksDisabled;
// ... to here.
//soner: change this
function TWindowProcHelper.DoWindowProc: LResult;
      if LParam <> SKIP_LMCHANGE then
        LMessage.Msg := LM_CHANGED;
      if lWinControl is TRadioButton then
      //Soner add this from here ...
        if (TButtonControlHack(lWinControl).ClicksDisabled) then begin //soner
          if Ord(TRadioButton(lWinControl).SavedState)<>SendMessage(lWinControl.Handle,BM_GETCHECK,0,0) then
            Windows.sendMessage(lWinControl.Handle, BM_SETCHECK,
              Windows.WParam(Ord(TRadioButton(lWinControl).SavedState){BST_UNCHECKED}), Windows.LParam(SKIP_LMCHANGE));
      // ... to here.
      //Uncheck siblings
      if WParam = BST_CHECKED then

// ****************************************************
2) In lazarus\lcl\stdctrls.pp
  TCustomCheckBox = class(TButtonControl)
    constructor Create(TheOwner: TComponent); override;
    function SavedState: TCheckBoxState; //soner add this (we need this because checked returns current(win32)state not the saved state)

// ****************************************************
3) In lazarus\lcl\include\
function TCustomCheckBox.SavedState: TCheckBoxState; //soner add this

// ****************************************************
4) In example programm

  TButtonControlHack = class(TButtonControl)
    property ClicksDisabled;
procedure TForm1.BtnReadOnlyClick(Sender: TObject);
var i: integer;
  if BufDataset1.ReadOnly then Caption:='ReadOnly'
  else Caption:='Not ReadOnly';

  for i:=0 to DBRadioGroup1.ControlCount-1 do
   //test for the normal radiobuttons



2017-06-13 12:06

reporter   ~0101081

I would prefer first solution because it is crossplatform and the changed solution needs changes in lcl and it is only for win32-widgetset.


2017-06-13 12:17

developer   ~0101083

Last edited: 2017-06-13 12:33

View 2 revisions

Thank you.

I did not yet try to bring your code snippets into current code because I see two main problems:

(1) You are referring to win32 interface units. This implies that your code will be working only for Windows. But we need it cross-platform! My preference would be not to touch widgetset code at all because it will become an endless story. (NOTE: When writing this I did not see your previous message # 101081)

(2) The name "ClicksDisabled" implies (maybe I am wrong) that the code works only for mouse clicks. But the radiobutton/radiogroup can also be changed by means of the keyboard: Press the accelerator key assigned to the button, or navigate to the requested button by means of the arrow keys and press Space.


2017-06-13 12:38

reporter   ~0101085

The first solution( is crossplatform. I am using this for my lazarus.

Only the second solution( is for win32-interface. But the message part (in TWindowProcHelper.DoWindowProc) can be implemented for other widgetsets.

I am happy with first solution and it solves one problem that very rarely apppers.


2017-06-13 13:50

developer   ~0101089

A non-perfect patch is better than no patch --> applied (r55344). Left a comment in the source that it's only a workaround. Please test and close if ok.

This issue will come back, though, because TDBCheckbox suffers from the same problem...


2017-06-13 16:51

reporter   ~0101096

I would make this (the first way) also for TDBCheckbox.

This could be third solution to avoid onchanged event (Not tested):
1) Using TButtonControl.ClicksDisabled.
I think it is for this Kind of usage:

2)Changing in procedure TCustomRadioGroup.CheckItemIndexChanged;
if FLastClickedItemIndex=FItemIndex then exit;

to this:

if clicksdisabled and (FLastClickedItemIndex<>FItemIndex) then begin
  SetItemIndexWithoutEvents(FLastClickedItemIndex); // = SetState-Function
if FLastClickedItemIndex=FItemIndex then exit;


Now, I close this because this because your patch is okay.


2017-06-13 17:06

developer   ~0101097

SetItemIndexWithoutEvents - I was searching for something like this, but it does not exist.


2017-06-13 17:31

reporter   ~0101098

Sorry I should write more clearly.
It is the SetState-Function from TCustomCheckBox you must move it to protected or public area.(RadioButton is derived from CheckBox).

It is exactly the this function from procedure TCustomCheckBox.ApplyChanges:
TWSCustomCheckBoxClass(WidgetSetClass).SetState(Self, FState);

But you can use SetState from checkbox.

I will look all the Radio- and CheckBox related bugs closer today, when i am back at home.


2017-06-15 14:36

reporter   ~0101150

I closed this issue but now it looks like not closed.
Close this as solved.
Third way is not needed, because:
1.In FCL/LCL is some changes for TDataLink.SetReadOnly needed (for setting TButtonControl.ClicksDisabled).
2. No one shuld use TDBRadioGroup.OnChanged, because TDataset.AfterScroll, TField.OnChange or TField.OnSettext is for database more suitable.

Issue History

Date Modified Username Field Change
2017-06-09 21:33 Soner New Issue
2017-06-09 21:33 Soner File Added: DbRgReadOnlyError-public.7z
2017-06-11 10:43 Juha Manninen Note Added: 0101018
2017-06-11 14:21 Soner Note Added: 0101020
2017-06-11 14:30 Soner Note Added: 0101021
2017-06-11 14:33 Soner Note Edited: 0101020 View Revisions
2017-06-11 20:51 Juha Manninen Note Added: 0101027
2017-06-13 00:17 wp Relationship added duplicate of 0021099
2017-06-13 00:24 wp LazTarget => -
2017-06-13 00:24 wp Note Added: 0101072
2017-06-13 00:24 wp Assigned To => wp
2017-06-13 00:24 wp Status new => acknowledged
2017-06-13 11:48 Soner Note Added: 0101080
2017-06-13 12:06 Soner Note Added: 0101081
2017-06-13 12:17 wp Note Added: 0101083
2017-06-13 12:33 wp Note Edited: 0101083 View Revisions
2017-06-13 12:38 Soner Note Added: 0101085
2017-06-13 13:50 wp Fixed in Revision => 55344
2017-06-13 13:50 wp LazTarget - => 1.8
2017-06-13 13:50 wp Note Added: 0101089
2017-06-13 13:50 wp Status acknowledged => resolved
2017-06-13 13:50 wp Resolution open => fixed
2017-06-13 13:50 wp Target Version => 1.8RC2
2017-06-13 16:51 Soner Note Added: 0101096
2017-06-13 16:51 Soner Status resolved => closed
2017-06-13 17:05 wp Status closed => assigned
2017-06-13 17:05 wp Resolution fixed => reopened
2017-06-13 17:06 wp Note Added: 0101097
2017-06-13 17:06 wp Status assigned => feedback
2017-06-13 17:31 Soner Note Added: 0101098
2017-06-13 17:31 Soner Status feedback => assigned
2017-06-15 14:36 Soner Note Added: 0101150
2017-06-15 20:49 wp Status assigned => resolved
2017-06-15 20:49 wp Resolution reopened => fixed
2017-06-18 00:49 Soner Status resolved => closed
2017-06-29 15:52 wp Relationship added related to 0032077