QA: Why empty edit box with no border doesn't show caret?

Alexander Shargin (rudankort@softspb.com), July 22, 2003.

Question

I am using an edit box with no border. I noticed that it doesn't show caret when no text is entered to it. This also happens with comboboxes. Why does this happen? How can I fix this?

Answer

Background

Each edit box internally stores left and right margin sizes. You can change these sizes by sending EM_SETMARGINS to the edit box. EM_GETMARGINS is used to determine current margin sizes. By default, margins are calculated based on the font assigned to edit box (this mode is enabled by EC_USEFONTINFO flag used with EM_SETMARGINS message). But this mode has some problems on Pocket PC. In fact it works for some fonts (e. g. System) but fails with others (e. g. Tahoma) so the problem probably has to do with fonts, not with OS itself.

Solution

First obvious solution is to change font of your edit box (or of the entire dialog containing it). It can be done in resource editor (Font... button in dialog's properties) or in runtime using WM_SETFONT message or its MFC equivalent, CWnd::SetFont. Of course, this is not possible if you need to use a specific font. Second option is to use EM_SETMARGINS message to explicitly set edit box margins to, say, 1 pixel. In "pure" API it is done like this:

// hEdit is a handle of edit box. ::SendMessage(hEdit, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(1,1));

In MFC, CEdit::SetMargins method is used instead:

// wndEdit is an object of CEdit class. wndEdit.SetMargins(1, 1);

What about comboboxes?

Drop-down comboboxes internally use borderless edit boxes to edit text. So obviously, they suffer from the same problem and the same solutions apply here. If you want to use second solution, you need to obtain HWND of edit box embedded inside combobox first. Since edit box is a child window of combobox, this is done using GetWindow function:

// hCombo is a handle of combobox. HWND hEdit = ::GetWindow(hCombo, GW_CHILD); ::SendMessage(hEdit, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(1,1));