|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Text API Routines SendMessage: Text Selection Methods via API |
||
Posted: | Saturday July 18, 1998 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6 | |
Developed with: | VB5, Windows 95 | |
OS restrictions: | None | |
Author: | VBnet - Randy Birch | |
Related: |
SendMessage: Determine the Current Line in a Text Box SendMessage: Determine the Number of Lines in a Text Box SendMessage: Find Text Box Document Size via API SendMessage: Text Range Selection via API |
|
Prerequisites |
None. |
|
This
is a small collection of API methods to both simulate VB's 'SelStart/SelLength' methods and provide new word-processing style functionality.
All use SendMessage to affect the selections within a textbox, but some methods may also apply to the RichTextBox control as the Windows RichEdit and Edit classes share many messages. |
BAS Module Code |
None. |
|
Form Code |
Create a simple project like the illustration, with a Multiline textbox and six command buttons (Command1-Command6). Add the following to the form: |
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" _ (ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long Private Const EM_GETSEL = &HB0 Private Const EM_SETSEL = &HB1 Private Const EM_GETLINECOUNT = &HBA Private Const EM_LINEINDEX = &HBB Private Const EM_LINELENGTH = &HC1 Private Const EM_LINEFROMCHAR = &HC9 Private Sub Command1_Click() 'Typically this would be called from 'a menu item, for example 'Select To Top' Dim cursorPos As Long On Local Error Resume Next 'get the character position of the cursor Call SendMessage(Text1.hwnd, EM_GETSEL, 0&, cursorPos) 'select the text from position 0 to the cursor Text1.SetFocus Call SendMessage(Text1.hwnd, EM_SETSEL, 0, ByVal cursorPos) End Sub Private Sub Command2_Click() 'Typically this would be called from 'a menu item, for example 'Select To End' Dim cursorPos As Long Dim lineCount As Long Dim ChrsUpToLast As Long Dim lastLineLen As Long On Local Error Resume Next 'get the cursor position in the textbox Call SendMessage(Text1.hwnd, _ EM_GETSEL, 0, cursorPos) 'get the number of lines in the textbox lineCount = SendMessage(Text1.hwnd, _ EM_GETLINECOUNT, 0, ByVal 0&) 'the number of characters in the textbox, 'up to but not including the the last line '(0-based) ChrsUpToLast = SendMessage(Text1.hwnd, _ EM_LINEINDEX, _ lineCount - 1, ByVal 0&) 'the number of characters in the last line lastLineLen = SendMessage(Text1.hwnd, _ EM_LINELENGTH, _ lineCount, ByVal 0&) 'select the text from the cursor 'position to the last line Text1.SetFocus Call SendMessage(Text1.hwnd, _ EM_SETSEL, _ cursorPos, _ ByVal ChrsUpToLast + lastLineLen) End Sub Private Sub Command3_Click() 'Typically this would be called from 'a menu item, for example 'Select To Beginning of Line' Dim cursorPos As Long Dim currLine As Long Dim chrsToCurrent As Long On Local Error Resume Next 'get the cursor position in the textbox Call SendMessage(Text1.hwnd, _ EM_GETSEL, 0, cursorPos) 'get the current line index currLine = SendMessage(Text1.hwnd, _ EM_LINEFROMCHAR, _ cursorPos, _ ByVal 0&) ' + 1 'number of chrs up to the current line chrsToCurrent = SendMessage(Text1.hwnd, _ EM_LINEINDEX, _ currLine, ByVal 0&) 'select from the first chr on the 'cursor line up to the cursor Text1.SetFocus Call SendMessage(Text1.hwnd, _ EM_SETSEL, _ chrsToCurrent, _ ByVal cursorPos) End Sub Private Sub Command4_Click() 'Typically this would be called from 'a menu item, for example 'Select To End of Line' Dim cursorPos As Long Dim currLine As Long Dim chrsToCurrent As Long On Local Error Resume Next 'get the cursor position in the textbox Call SendMessage(Text1.hwnd, _ EM_GETSEL, 0, cursorPos) 'get the current line index currLine = SendMessage(Text1.hwnd, EM_LINEFROMCHAR, cursorPos, ByVal 0&) 'number of chrs up to the *next* line chrsToCurrent = SendMessage(Text1.hwnd, _ EM_LINEINDEX, _ currLine + 1, _ ByVal 0&) 'select from the cursor position 'to the the end of the line, subtracting '1 to keep the cursor on the selected line. Text1.SetFocus Call SendMessage(Text1.hwnd, _ EM_SETSEL, _ cursorPos, _ ByVal chrsToCurrent - 1) End Sub Private Sub Command5_Click() 'Typically this would be called from 'a menu item, for example 'Select Line' Dim cursorPos As Long Dim currLine As Long Dim chrsToStart As Long Dim chrsToEnd As Long On Local Error Resume Next 'get the cursor position in the textbox Call SendMessage(Text1.hwnd, _ EM_GETSEL, 0, cursorPos) 'get the current line index currLine = SendMessage(Text1.hwnd, _ EM_LINEFROMCHAR, _ cursorPos, ByVal 0&) 'number of chrs up to the current line chrsToStart = SendMessage(Text1.hwnd, _ EM_LINEINDEX, _ currLine, ByVal 0&) 'number of chrs up to the next line chrsToEnd = SendMessage(Text1.hwnd, _ EM_LINEINDEX, _ currLine + 1, ByVal 0&) 'select from the cursor position 'to the the end of the line. Subtracting '1 keeps the cursor on the selected line. Text1.SetFocus Call SendMessage(Text1.hwnd, _ EM_SETSEL, _ chrsToStart, _ ByVal chrsToEnd - 1) End Sub Private Sub Command6_Click() Unload Me End Sub |
Comments |
The textbox passed to the SendMessage API must have its
multiline property set to true at design time. The EM_GETLINECOUNT message does not pass additional parameters to the API in the wParam or lParam variables. These must be 0. With EM_LINEINDEX, the value of the wParam parameter specifies the zero-based line number. A value of -1 specifies the current line number (the line that contains the caret). lParam is not used an must be 0. With EM_LINELENGTH, the value of the wParam parameter specifies the character index of a character in the line whose length is to be retrieved. If this parameter is -1, the message returns the number of unselected characters on lines containing selected characters. lParam is not used and must be 0. This code is new and reflects the methods used with 32-bit applications. The messages for 16-bit apps was different, requiring data to be packed into a long for passing as a single parameter. The 32-bit code is far less involved. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |