Here's the setting (I'm using Delphi 7, not sure if this will happen in later/earlier versions):
Create a new project with two forms.
Put a TMemo
, a TRichEdit
and a TButton
on the first form.
Set the Lines
properties of both the TMemo
and the TRichEdit
to 123456
.
In the TButton
's OnClick
event handler put Form2.Show;
Run the application, click the button and the empty Form2
will show and get focus.
Now click in the middle of the text "123456" of the TMemo
in Form1
- the focus will change back to Form1
and the cursor (caret) will be in the middle of the text "123456" where you clicked as expected.
Click on Form2
again to give it focus again.
Now click in the middle of the text "123456" of the TRichEdit
in Form1
- the focus will change back to Form1
, but the cursor (caret) won't be in the middle of the text "123456" where you clicked, but on the second empty line of the RichEdit
(or wherever it was previously).
If you click a second time in the same place in the middle of the text "123456" of the TRichEdit
, the cursor (caret) will now be moved there as expected.
So the TRichEdit
control gets focus, but the cursor (caret) isn't moved as expected.
Note: This only happens when changing the focus from one form to another. Changing the focus from one control to a TRichEdit control in the same form doesn't exhibit this problematic behavior.
My question: How to avoid the need for this second click inside a TRichEdit
and have the control behave like the TMemo
in this regard.
Thanks in advance!
You can derive a new control, or subclass the richedit in any way you like, to intervene with the activation mechanism. Below sample interposer class sets the focus to the control before the mouse down message is posted when it is about to be activated by the left button of the mouse if the control is not already focused:
type
TRichEdit = class(comctrls.TRichEdit)
protected
procedure WMMouseActivate(var Message: TWMMouseActivate);
message WM_MOUSEACTIVATE;
end;
procedure TRichEdit.WMMouseActivate(var Message: TWMMouseActivate);
begin
if (GetFocus <> Handle) and (Message.MouseMsg = WM_LBUTTONDOWN) then
SetFocus;
inherited;
end;