The information in this article applies to:
SUMMARY
This article explains how to determine the position (row and column) of the
caret and the line number of the first visible line of text in a multiline
edit control.
MORE INFORMATION
Edit controls process several messages that return information relevant to
the position of the caret within the control. These messages help an
application determine the line number of the caret relative to the number
of lines of text in the control.
Once the line number is known, the application can compute the caret's
character position within that line and the line number of the first
visible line of text in the control.
An edit control must be subclassed in order to track the caret position
because the position changes with mouse clicks and keystrokes. The subclass
procedure must process the WM_KEYDOWN and WM_LBUTTONDOWN messages, and
compute the caret position upon receipt of each message.
The remainder of this article describes three procedures:
- Finding the line number of the caret position
- Finding the column number of the caret position
- Finding the line number of the first visible line
Note that you may replace any mention of the SendMessage API in this
article with the SendDlgItemMessage function. Also note that the term
return value refers to the value returned by the SendMessage or the
SendDlgItemMessage function.
Finding the Line Number of the Caret Position
Perform the following two steps:
- Send the EM_GETSEL message to the edit control. The high-order word
of the return value is the character position of the caret relative
to the first character in the control.
- Send the EM_LINEFROMCHAR message to the edit control and specify the
value returned from step 1 as wParam. Add 1 to the return value to
get the line number of the caret position because Windows numbers
the lines starting at zero.
Finding the Column Number of the Caret Position
Perform the following three steps:
- Send the EM_GETSEL message to the edit control. The high-order word
of the return value is the character position of the caret relative
to the first character in the control.
- Send the EM_LINEINDEX message with wParam set to -1. The value
returned is the count of characters that precede the first
character in the line containing the caret.
- Subtract the value returned in step 2 from the value in step 1 and
add 1 because Windows numbers the columns starting at zero. This
result is the column number of the caret position.
Finding the Line Number of the First Visible Line
Windows 3.1 and later define the EM_GETFIRSTVISIBLELINE message, which an
application can send to a single line or a multiline edit control. For
single line edit controls, this value returned for the message is the
offset of the first visible character. For multiline edit controls,
the value returned is the number of the first visible line.
Under Windows 95, it would be more efficient to use a combination of
GetCaretPos() and EM_CHARFROMPOS.
If an application must be compatible with Windows 3.0, it can perform
the following 10-step procedure:
- Follow steps 1 and 2 of "Finding the Line Number of the Caret
Position," presented above, and save the line number.
- Call the GetCaretPos function to fill a POINT structure with the
caret's coordinates relative to the client area of the edit
control. (The client area is inside the border.)
- Call the GetDC function using the handle to the edit control to
retrieve a handle to a device context for the edit control. Store
this handle in a variable named hDC.
- Send the WM_GETFONT message to the edit control. The return value
is a handle to the font used by the edit control. If the value
returned is NULL, proceed to step 6 because the control is using
the system default font.
- Call the SelectObject function to select the font used by the edit
control into hDC. Do not call the SelectObject function if
WM_GETFONT returned NULL in step 4. Save the value returned by
SelectObject in the hOldFont variable.
- Call the GetTextMetrics function with hDC to fill a TEXTMETRIC
data structure with information about the font used by the edit
control (the font which is selected into hDC). The field of
interest is tmHeight.
- While the vertical coordinate of the caret is greater than the
value of tmHeight, subtract tmHeight from the vertical coordinate
and subtract 1 from the line number of the caret from step 1.
- Repeat step 7 until the vertical coordinate of the caret is less
than or equal to tmHeight.
- Call SelectObject to select hOldFont back into hDC. Then call
ReleaseDC to return the display context to the system.
- The value remaining in the line number variable is the line number
of the first visible line in the edit control.