Caret Position & Line Numbers in Multiline Edit Controls

Last reviewed: November 2, 1995
Article ID: Q68572
The information in this article applies to:
  • Microsoft Windows Software Development Kit (SDK) versions 3.0 and 3.1
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT versions 3.5 and 3.51
        - Microsoft Windows 95 version 4.0
    

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:

  1. 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.

  2. 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:

  1. 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.

  2. 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.

  3. 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:

  1. Follow steps 1 and 2 of "Finding the Line Number of the Caret Position," presented above, and save the line number.

  2. 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.)

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. Repeat step 7 until the vertical coordinate of the caret is less than or equal to tmHeight.

  9. Call SelectObject to select hOldFont back into hDC. Then call ReleaseDC to return the display context to the system.

  10. The value remaining in the line number variable is the line number of the first visible line in the edit control.


Additional reference words: 3.00 3.10 3.50 4.00 95 caretpos
KBCategory: kbui
KBSubcategory: UsrCrt


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 2, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.