|
|
![]() |
|
||
|
|
|||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||
| 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. |
![]() |