Link to home
Start Free TrialLog in
Avatar of oragon
oragon

asked on

Caret of CEdit doesn't appear

I have a CEdit in a modeless dialog. If the focus is on it,
and then switches to a tree control I have in my app, and
then I click the CEdit again, the caret does not appear,
so the user thinks he hasn't got the focus. Using OnSetFocus()
is no good because the edit box already has the focus.
What can I do to make the caret appear ?
(the problem occurs only when I click the edit box in the
process of in-label editting of the tree).
Avatar of V_Bapat
V_Bapat
Flag of India image

Try CWnd::ShowCaret().

Also look at the caret function of CWnd.

Vicky
Avatar of Vinayak Kumbar
Vinayak Kumbar

Hi,

Are U doing something on KillFocus of Ur Tree control?
Does the caret appear after 2nd or 3rd click in edit box?
Check it out.
Avatar of oragon

ASKER

OK, I went to the short length of deriving a class from CEdit and catching the LButtonUp messages. I catch the message and indeed call ShowCaret() but still nothing happens !!!
In answer to VinExpert - clicking again doesn't help. I am not handling the kill focus of the tree control.
Ho Oragon
This question is almost similar to your last question(Q.10193541 - Edit box doesn't get focus after in-label...).

Did you get any hint from there which you can pass on here? This could make things more clear.

Vicky
Avatar of oragon

ASKER

I was advised to check the style properties of the dialog and edit box.
Another expert advised me to use the following statements:
SetItemState(iItem, TRUE, LVIS_FOCUSED|LVIS_SELECTED);
SendMessage(WM_CHAR, ' ', 0); // select selected item
but I didn't even understand where I was supposed to use them.
I posted this question because after some research I indeed found out that I could catch events but even after I put:
SetFocus()
ShowCaret()
Invalidate()
The caret is not visible, and when you click the keyboard letters are added normally to the end of the current text (even if I clicked in the middle of the text).
I've spent about two days already just on this rather simple-looking bug and I've pretty much run out of new ideas.
Did you try CreateGrayCaret()?

Call GetCaretPos() to verify whether the caret is present or not. If you get it call SetCaret() to set the caret or call CreateGrayCaret() to create one.

Hope this works.

Vicky
The CreateGrayCaret() function automatically destroys the previous caret shape, if any, regardless of which window owns the caret. Once created, the caret is initially hidden. To show the caret, the ShowCaret() function must be called.
Add a EN_SETFOCUS notification handler to your class derived from CEdit and try these things:

1. Show the caret when the edit control recevies the focus.
 ShowCaret();

2. Get the caret position, set it again and show it.
 SetCaretPos(GetCaretPos());
 ShowCaret();

3. Create a new caret and show it.
 CreateGrayCaret(0, 0);
 ShowCaret();

Let us know if any one of these works.

Vicky
Avatar of oragon

ASKER

I'm not sure waiting for focus is any good, but I'll try that in a moment. Meamwhile, just showing the caret does nothing. Actually creating it does work, but with some problems:
It is not created in the shape of the normal caret that a CEdit has.
Shouldn't there be a simpler solution ? Shouldn't MFC have taken care of this situation.
You have to get the width and height from GetSystemMetrics(). Read the help on CreateGrayCaret(). Try this:

CreateGrayCaret(GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
ShowCaret();

Vicky
Avatar of oragon

ASKER

For some reason it doesn't get EN_SETFOCUS messages. It seems that if the edit was in focus, then I edit the label in the tree, and then I click on the edit box, it does not get a set focus message. This makes me hard to implement your solutions.
ASKER CERTIFIED SOLUTION
Avatar of V_Bapat
V_Bapat
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Check if u'r mouse is captured anywhere.. just call releasecapture and try giving focus to the edit.. just a thought..
Avatar of oragon

ASKER

The only problem with creating a caret is that it doesn't get created with the same shape as the original one. I found a bit of an ugly solution to the whole situation by doing the following:
capturing message of mouse down, and then doing the following: setting focus to parent, setting focus back to me, and then using the point where the mouse clicked to create a selection that sets the caret exactly where it should be. So as not to mess up too much the inner workings of CEdit, I do this only the first time I get a mouse click message after the edit control had lost its focus. For this reason I keep an inner data member of my derived class, and set it to false when a WM_KILLFOCUS message is processed. The code looks something like this:

pParent->SetFocus();
SetFocus();
itsbInFocus = true;
int cIndex = CharFromPos(point);
SetSel(cIndex,cIndex);

<itsbInFocus> is my data member.

This is a bit ugly but actually works fine, and keeps the caret in its original shape.