Which radio button is selected in a TRadioGroup? - delphi

As you can see in my question history, I'm developing a eBook manager, that will be open-source and I will release it in about 10 days, but I have a TRadioGroup, as you can see:
TRadioGroup Used On My Form http://img85.imageshack.us/img85/1830/radiogroup.png
And I want to store somethings in a variable(that needs to be a Integer) that will be "linked" with this TRadioGroup.
I need to do a if function like this:
Caption Of The TRadioButton -> Number that will need to be stored in the variable
Fit 2xWidth - Default -> 0
Fit 2xHeight -> 1
Fit Width -> 2
Fit Height -> 3
But I just used a TRadioGroup and a TRadioButton one time, different than in C# that I've used more than 20 times. Then I want to know what I need to put on the if function, because what it will do I already know how to do:
var
num: Integer;
begin
if(TRadioButton1 checked?)
begin
num := 0;
end;
end.
What I need to put inside the brackets of the if function?
PS: I'm going to put the credits on the program for the people that helped me in this little project.

A TRadioButton has the Checked property. But A TRadioGroup has the ItemIndex property.
The items in a TRadioGroup are stored using a TStrings. So you can associate an object to each option and you can cast an integer to a TObject to be stored.
Example:
// fill the radiogroup
radiogroup.Items.AddObject('Fit 2xWidth', TObject(0));
radiogroup.Items.AddObject('Fit 2xHeight', TObject(1));
radiogroup.Items.AddObject('Fit Width', TObject(2));
radiogroup.Items.AddObject('Fit Height', TObject(3));
radiogroup.ItemIndex := 0;
To read the current setting:
value := radiogroup.ItemIndex;
Or to get the associated integer:
index := radiogroup.ItemIndex;
Assert(index>=0); // Sanity check
value := Integer(radiogroup.Items.Objects[index]);
In your case, the values are 0 to 3 so you can use the ItemIndex.
As a note, if is not a function. A function is a piece of code that returns a value based on the input parameters. If is a statement, which is a command that can be executed. The if statement is special because it enables you to execute a different statement based on the if condition.

Just a little TIP: Setting .ItemIndex does not send keyboard focus to the radio item, i know how to fix it, read ahead.
Instead of selecting by code a Radio in a RadioGroup by setting .ItemIndex it is much better to do it by sending focus to the radio item; just to be very clear: i mean sending focus just to the radio item, not the whole radio group.
Instead of: radiogroup.itemindex:=TheIndex;
Do it as this: TRadioButton(radiogroup.Controls[TheIndex]).SetFocus;
It will make the radio item to be selected and send the keyboard focus to it, so it will display the dotted rectangle arroud it, just as if the user had clicked on it.
Note1: To see it in action use keyboard cursor keys and compare behavor of just setting .ItemIndex and sending focus to radio item.
Note2: If you use TRadioButton(radiogroup.Controls[TheIndex]).SetFocus; then there is no no need to set .ItemIndex at all, it will also be done.
Hope that helps someone having the same problem as me, when need to set it by code, for example to avoid circular keyboard behavor, for example for making it to stay on last radio item when last radio item is selected and keyboard right cursor is pressed, same for first.

Related

When typing at the end of the editmask, it will pass the number to the left side until it reaches the last one

Good afternoon,
I'm doing a project in delphi that uses editmask. I'm using the phone mask.
When clicking on edit to write the phone number, it goes to the last field on the right, so it is necessary to go back with the backspace to the beginning of the edit on the left.
i would like to find a way that when the user typed the number in the last field on the right, it was passed to the left. So on until you complete the phone field. It would be possible?
Using an example of what it would look like:
I couldn't think of a way to do it
The component is called TMaskEdit.
Just like anything that bases on TEdit putting the focus onto the control will by default put the text cursor at the end of its content
via keyboard, should .AutoSelect be FALSE and
via mouse if clicking behind any text (by default the text is aligned to the left).
You should have experienced this with the other components already. If you want the text cursor to always be at a certain position upon focusing the control, then do that in such an event handler:
for keyboard use OnEnter:
procedure TForm1.MaskEdit1Enter(Sender: TObject);
begin
(Sender as TMaskEdit).SelStart:= 1; // Second position
end;
and for mouse use OnClick with the same code.
It even works unbound to how the property .AutoSelect is set.
Using Backspace is the worst choice input wise, as it always deletes potential content and needs to be pressed several times to go to the first position. Why not using the Home key instead?

Uncheck all checkboxes in a TCheckListBox

I want the user to be able to press a button to reset a TCheckListBox to it's initial state (having no boxes checked).
See images below of an example of what I want to happen after clicking the button:
Changed to:
How would I go about doing this? I know there would probably be a loop involved, but I'm unsure where to start. Thanks for the help in advance.
There is nice method - look at official help.
If we open TCheckListBox help page, choose Methods and filter off "inherited" ones, we'll see CheckAll method
CheckListBox1.CheckAll(cbUnchecked);
For individual checkboxes (missed this is a TCheckListBox).
Something along these lines,
Let's assume the checkboxes are on a panel called panel1.
var n: Integer;
begin
for n := 0 to panel1.ComponentCount - 1 do
if panel1.Components[n] is TCheckbox then
Tcheckbox(panel1.components[n]).checked := False;
end;
Note: if there is an event associated with the checkbox, you need to set the event to nil before modifying it, and returning the event after - else, the event will trigger as if you clicked the box.

How do I assure that mouse pointer appears when mouse moves over form after commanding the drop down for a combobox to show?

I have a problem where:
I have a form with just a combobox.
The combobox has focus and mouse is not hovering over the form when item 3 happens.
I trigger the combobox's drop-down list to show on a key-press event.
When the drop-down list is visible and then I move my mouse pointer over the form, the pointer is either invisible, shows that it is busy, or shows the resizing icon but does not turn back to a normal pointer when over the form.
Is there something that can be done to assure that, when the drop-down of the combobox shows, that the mouse pointer is visible when I move the pointer over the form?
I have tried:
Applicaiton.ProcessMessages after showing the drop-down.
Changing focus to the form the combobox is on after showing the drop-down.
Adding Key := #0; after calling the drop-down to show.
procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
SendMessage(ComboBox1.Handle, CB_SHOWDROPDOWN, Integer(True), 0);
Key := #0;
end;
Tried using a timer to trigger the drop-down within the key-press event.
Tried using "SetCursor" after commanding the drop-down to appear.
Tried using ".DroppedDown", but did not see any difference in result from that of "SendMessage".
I would hope to be able to show the mouse pointer after the drop-down is displayed, but it is hidden instead. Thanks for any suggestions.
(NOTE: This problem I have run into is not exlusive to Delphi. I was able to duplicate the issue using Visual C# 2017. Either way, if there is a way to correct this, it would be good to know).
As already commented to the question, the issue is not Delphi related. You can observe the same behavior in dialog boxes which contains a similar combo that the OS presents. One example is the one on the "run" dialog.
Involving a single environment, re-setting the cursor in an OnDropDown event handler fixes the problem.
procedure TForm1.ComboBox1DropDown(Sender: TObject);
begin
winapi.windows.SetCursor(Screen.Cursors[Cursor]);
end;
Originally I tested the above because no one calls SetCursor after the drop down. Though it seems that no one calls it before either. So I have no idea about the cause or why the above fix works.

How can I add a caption/text to my csExDropDownList Combobox in Delphi?

I'm currently trying to create a combobox that has a "caption". By caption I mean the text that you see when you haven't clicked on it yet or if you are choosing an option.
Before I added the csExDropDownList it worked fine, but I wanted it to be ReadOnly. Now when I edit the Text property, it instantly gets deleted. I thought about using a TLabel in front of the combobox and making it dissapear the moment I chose a dropdown, but the TLabel is always in the background. I also tried with the TStaticText component, but that leaves a different colored background in front of the combobox which looks bad.
If I was unable to explain with words what I'm trying to edit/wanted to add a text to, this is what I mean:
I've found a workaround to my problem. I added a third dropdown with the index of 0. Now in properties I put the ItemIndex to 0 which means that it will be displayed similar to the Text property. When I interact with either QuickSort or InsertSort I delete Index 0.
My code looks like this:
procedure TSorterForm.AlgorithmCbxChange(Sender: TObject);
begin
if (AlgorithmCbx.Text <> 'Choose Algorithm...') and not IsAlgorithmSelected then begin
AlgorithmCbx.Items.Delete(0);
IsAlgorithmSelected:= true;
end;
end;
Obviously not perfect so it'd be great if you could tell me how to improve this.

Combo box - typing selection then clicking out of focus - doesn't select the typed item

I'm having an issue with the combo box. I have an event handler for OnClick which refreshes data based on what item was selected. The problem is when this scenario occurs:
Drop-down the combo box to list the various options
Type on the keyboard to find a matching item
Combo box changes this selection and calls the OnClick event
My screen refreshes due to this selection / event
Click somewhere outside of the combo box to take the focus away from it
Combo box goes back to the previous selection, even though OnClick was already called
Even though Combo box changed back to prior selection, OnClick isn't called again
After this, Combo Box shows different value than what my data actually represents
So when you open a combo box, and type a few letters on the keyboard to find the item in the drop-down list, OnClick is fired which refreshes my screen. But when you click somewhere outside the combo box (thus taking the focus away from it), the combo box changes back to whatever value was previously selected, instead of what I had typed. And at the same time, the OnClick event isn't fired, so the combo box shows the incorrect value compared to what I had loaded on the screen.
How do I make the combo box stay on the selected item in this scenario of typing the item on the keyboard?
In my code, I deal with this using the OnCloseUp event. Well, in fact I'm using a sub-classed combo for my drop-down lists and they override both the Change and CloseUp methods:
procedure TMyDropDownList.Change;
begin
RespondToChange;
inherited;
end;
procedure TMyDropDownList.CloseUp;
begin
RespondToChange;
inherited;
end;
The RespondToChange method reacts to the new ItemIndex value. If it is expensive to react to every single change whilst the combo is dropped down, then you might consider omitting the call to RespondToChange from the Change method.
You could use OnExit to make the entry with the keyboard jive with the Index on the ComboBox; where VarS is assigned OnChange and is the answer you would like to keep:
procedure TForm1.ComboBox1Exit(Sender: TObject);
begin
{ Windows keyboard select bug, force use of selected }
ComboBox1.ItemIndex := ComboBox1.Items.IndexOf(VarS);
end;
I would call this a bug in the ComboBox design.

Resources