I have some TRadioButton
s on Form2
and call Form2
from Form1
with this code:
procedure TForm1.btnCallForm2Click(Sender:TObject);
begin
Form2.RadioButton2.Checked:= true;
Form2.ShowModal;
end;
If user clicked btnCallForm2
, Form2
will be displayed, then user clicks RadioButton3
and closes the form, and then reopen it by clicking btnCallForm2
again.
Now Form2
displayed again but RadioButton3
is checked instead of RadioButton2
.
Q: What is this behavior, is it a bug? How to set checked my desired RadioButton
instead of what is selected by the user in previous turn?
This is not a bug. The reason that you have this "strange" behavior is that if the Form2 is not destroyed, then next time it becomes visible (e.g. ShowModal
) it remembers which control had the focus.
In your case the last control in focus is the RadioButton3 (because you clicked on it to change the "checked" state). So even if you are changing the "checked" state back to RadioButton2, the focus will be restored to RadioButton3 when the form is next activated. To restore the focus, the control is sent a WM_SETFOCUS
. Read the rest from documentation for default message processing for button controls:
WM_SETFOCUS Draws a focus rectangle on the button getting the focus. For radio buttons and automatic radio buttons, the parent window is sent a BN_CLICKED notification code.
This BN_CLICK
notification (WM_COMMAND
message) sets the state of the radio button to checked.
The rationale behind this behavior can be found while navigating the radio buttons with the keyboard. When you press up/down arrow while on one of the radio buttons, the next radio button that receives the focus becomes checked.
This behavior only applies to radio buttons, e.g., try the same with another control (e.g. check box), that its state is not altered when it has focus. You will see that everything is working as expected
As kobik was suggesting, a fast and easy solution would be to set the ActiveControl to nil before showing the Form2
Form2.ActiveControl := nil;
or in the light of the documentation:
Form2.ActiveControl := Form2.RadioButton2;
or you could destoy and recreate the form as following:
Remove the Form2 from the AutoCreated Forms in Project->Options->Forms and create it manually in the ButtonClick event
procedure TForm1.btnCallForm2Click(Sender:TObject)
begin
Form2 := TForm2.Create(nil);
try
Form2.RadioButton2.Checked:= true;
Form2.ShowModal;
finally
FreeAndNil(Form2);
end;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With