I have a Checkbox1 that I would like to customize that when user clicks on Caption (text) of checkbox it doesn't change it's state (checked/unchecked), but only it does when clicked on the actual checkbox square.
Here is current code with 2 global variables, one that says when to Skip changing state and one that remembers current state and makes sure it stay the same after OnClick - because the state is already changed when flow is in OnClick:
var
gSkipClick:boolean = false;
gPrevState:boolean;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
// Make sure previous state is assigned when Skip
if gSkipClick then
Checkbox1.Checked := gPrevState;
end;
procedure TForm1.CheckBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (x > 12) then
begin
// Click outside checkbox square
gSkipClick := True; // skip Click
gPrevState := CheckBox1.Checked; // save current state
end
else
gSkipClick := False; // enable Click
end;
Now I wanted to do this with 2 new properties in TCheckBox that would replace global variables:
TCheckBox = class(Vcl.StdCtrls.TCustomCheckBox)
private
FSkipStateChange:Boolean;
FPrevState:Boolean;
protected
published
property SkipStateChange:Boolean read FSkipStateChange write FSkipStateChange;
property PrevState:Boolean read FPrevState write FPrevState;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
// Click outside checkbox square
If TCheckBox(Checkbox1).SkipStateChange Then
Checkbox1.Checked := TCheckBox(Checkbox1).PrevState;
end;
procedure TForm1.CheckBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (x > 12) then
begin
// Click outside checkbox square
TCheckBox(Checkbox1).SkipStateChange := True;
TCheckBox(Checkbox1).PrevState := Checkbox1.Checked;
end
else
TCheckBox(Checkbox1).SkipStateChange := False;
end;
And it works, but if I click on Caption and then close form, this error occurs:
Project Project1.exe raised exception class $C0000005 with message 'access violation at 0x004080c5: read of address 0x0000000d'.
The error occurs in procedure TMonitor.Destroy;
in System unit:
procedure TMonitor.Destroy;
begin
if (MonitorSupport <> nil) and (FLockEvent <> nil) then { <-- ERROR ON THIS LINE}
MonitorSupport.FreeSyncObject(FLockEvent);
FreeMem(@Self);
end;
What am I doing wrong, why does error occur?