How to select all text of a TEdit1 whenever user click on it or click to select some text of it
It can be quite dangerous to do anything beyond the default behaviour of the TEdit control. Your users know how the standard Windows controls behave and any deviation from this is likely to cause confusion.
By default the AutoSelect property is set to True.
Determines whether all the text in the edit control is automatically selected when the control gets focus.
Set AutoSelect to select all the text when the edit control gets focus. AutoSelect only applies to single-line edit controls.
Use AutoSelect when the user is more likely to replace the text in the edit control than to append to it.
When this property is True, the entire contents of the edit control are selected when it gets the focus by means of keyboard action. If the control gets the focus by a mouse click then the contents will not all be selected. In that case you simply press CTRL+A to select all. A double click will select the word underneath the mouse. This is all standard behaviour implemented by the underlying Windows control.
If you change the select in response to the OnClick event, as per the currently selected answer, then you will find that it is impossible to move the caret with a mouse click. This is exceedingly counter-intuitive behaviour.
This is a classic example of why you need to be very careful about changing the behaviour of a control from its default. It's simply very easy not to miss a particular use case when testing but when your users get hold of the program, they are sure to find all such wrinkles.
What you could safely do is to call SelectAll from OnDblClick. This would, I believe have no annoying side-effects.
Another option would be to call SelectAll when the focus switched to the edit control, but not every time you click in the control. This might feel a little odd to the user, but I personally think it would be reasonable to take this course of action. If you want to do this you need to handle the OnEnter event of your edit control:
procedure TForm1.Edit1Enter(Sender: TObject);
begin
PostMessage(Edit1.Handle, EM_SETSEL, 0, -1);
end;
How to select all text of a TEdit1 whenever user click on it
Select Edit1 in the VCL editor and double-click on the OnClick event:
procedure TForm13.Edit1Click(Sender: TObject);
begin
Edit1.SelectAll;
end;
You can also link this event to another control like a button.
Select the button, choose and click on the V arrow to select an event you want to link.
Now both Edit1.OnClick and Button1.OnClick link to the same event.
How to select some text of a TEdit1 whenever user click on it:
procedure TForm1.Edit1Click(Sender: TObject);
begin
Edit1.SelStart:= 1;
Edit1.SelLength:= 2;
end;
You must use OnMouseUp;
procedure cxMRUEdit1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then cxMRUEdit1.SelectAll;
end;
Related
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.
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.
I'm building an editor which uses a TImage to display a picture and has mouse events to be able to draw, move, and resize boxes on the image. All this works perfectly. Now I'm trying to implement the ability to use the arrows on the keyboard to move the selected box, but A) TImage does not get any focus, and B) TImage does not have any key events (because it cannot get focus). I guess I could cheat and switch on the form's KeyPreview property and catch them there, but there's many other controls on this form and I'd need to make sure the user is intending to work with the image. For example, if user has focus in the TEdit control, the arrow keys shall only affect this memo, and not modifying the image.
So is there any way to put or fake some kind of focus in the TImage to recognize key events?
Only controls that inherit from TWinControl can receive keyboard focus.
TImage descents from TGraphicControl and cannot receive keyboard events.
You can put the Image on top of a panel which sits on top of another control e.g. TEdit and give that focus if the Image is selected.
Then just use the OnKeyPress event of the non-visible edit.
Make sure to disallow the tab key if you don't want that to change the focus to another control.
procedure TForm8.Image1Click(Sender: TObject);
begin
Edit1.SetFocus;
end;
procedure TForm8.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = #9 then Key = #0; //disable tab key.
case key of
//do stuff here
end; {case}
end;
When TRadioButton has TabStop=True, it's acting very strange.
If you will try to switch focus between many radio buttons on a form using Tab key, you would do it only 1 time per app session. The tabulation is one-way, never returning back to the first radio button. Also when the focus is moving across radio buttons, they becoming "checked" automatically.
Can this behavior be fixed without creating my own component?
I want standard radio buttons to
switch focus cyclically
prevent radio button from checking when the focus comes into it (I want my users to check them using Space key)
I understand that you're working with existing code, which is a real world constraint that's too often dismissed in these forums.
Sounds to me like checkboxes would suit you better. You can enforce the exclusivity normally expected of RadioButtons in the OnChecked event. That should solve your tabbing/focus and selection/deselection issues.
Checkboxes won't be checked automatically upon receiving focus, and your users can check/uncheck them with the space key.
You can put code in the OnEnter event to prevent the checkbox from selecting.
You'll need to store the previously selected RadioButton somehow though.
var
SelectedRadioButton: TRadioButton;
//event shared by all radiobuttons
procedure TForm1.RadioButton1Enter(Sender: TObject);
begin
if Sender <> SelectedRadioButton then begin
SelectedRadioButton.Checked:= true;
end;
end;
procedure TFrameOrder.RadioButton1Click(Sender: TObject);
begin
SelectedRadioButton:= (Sender as TRadioButton);
end;
procedure TFrameOrder.RadioButton1KeyPress(Sender: TObject; var Key: Char);
var
MyRadioButton: TRadioButton;
begin
MyRadioButton:= (Sender as TRadioButton);
if Key in [#32,#13] then begin
MyRadioButton.Checked:= true;
RadioButton1Click(MyRadioButton);
end; {if}
end;
It probably clearer to create a new TMyRadioButton component though because this will clutter up your regular code.
I have found an interesting article of Craig Stuntz about this problem. As I can see, I'll need to create my own control to solve it.
By default only one RadioButon has property TabStop = True;
All Radiobuttons are treated as one controll.
When radiobutton has focus you can switch beetween radiobutons using arrow up and down.
Now when user choose one option they can press tab to switch to another controll (without changing radio options).
I have a TComboBox on a form. Its Style property is set to csDropDownList. If I open the dropdown and select an option with my mouse or keyboard and hit ENTER, the dropdown box closes and the ItemIndex property is changed before the KeyPress event handler is fired. If I hit TAB, the dropdown doesn't disappear until after the KeyPress event handler has fired and focus has moved off the control, and the ItemIndex doesn't get updated; it reverts back to whatever had been selected before I opened the list.
If I want TAB to update ItemIndex to whatever's currently selected in the dropdown list, how would I implement it?
Set the Form's KeyPreview property to True.
In the ComboBox OnKeyDown event:
procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = VK_TAB) then
begin
Key := VK_RETURN;
Perform(WM_NEXTDLGCTL,0,0);
end;
end;
This emulates the return key and then moves focus to the next control.
I believe this is the default behavior, and to change it you might need to subclass the control (or even a class helper), intercept the windows message for the keystroke, then if its a tab send a return to the control and handle the tab yourself.
You should try to trap TAB earlier in the KeyUp event or maybe even earlier in the KeyDown.
When you retrieve your index use this instead of the classical ComboBox->ItemIndex
ComboBox->Items->IndexOf(ComboBox->Text)