Select text backwards - so that the current cursor is at the beginning of the selected text.

Posted on 2003-10-30
Last Modified: 2010-05-01
-- VB6 --
I have the need to select text in a ComboBox so that after selecting the text, the current cursor location is at the front of the selection as opposed to the end of the selection.

The ComboBox has the SelStart and SelLength properties.  The SelLength must be 0 or greater (therefore I cannot select a negative length to make the selection go backwards).

I tried sending the CB_SETEDITSEL message to the ComboBox but it would always select the 19th character to the end of line no matter what I passed as a W and L Param.  I did put the start and end in the LParam.

I tried getting the handle of the Edit Control associated with the ComboBox and sending the EM_SETSEL message to it.  I had a little more success in that I could get it to select the range but it would always put the cursor at the end of the selection.  I tried sending a start char of 3 and end char of 7 - and it acted correct.  I tried sending a start char of 7 and end char of 3 - and it acted the same as 3 and 7 in that it hilited the correct text but still put the cursor at the end of the selection.
Question by:markh524
  • 5
  • 4

Expert Comment

ID: 9652368
Try this little test and see if it solves your problem

Private Sub Command1_Click()
   Dim mFind As String
   Dim mResult As String
   mFind = InputBox("Find What?")
   mResult = InStr(Combo1.Text, mFind)
   If mResult Then
      Combo1.SelStart = mResult - 1
      Combo1.SelLength = 1
   End If
End Sub

Private Sub Form_Load()
   Combo1.Text = "Test for finding selection in combo box"
End Sub

Author Comment

ID: 9652492
Your suggestion tells me that I should rephrase my question another way.

I want a multi-character selection but I want the caret (flashing cursor) to be at the front of the selection instead of at the end of the selection.

When at tried jgarth's suggestion, it just selected the first character.

Accepted Solution

JCinDE earned 500 total points
ID: 9652787
This is an interesting request and the subroutine below should help out. The only problem with it is it has to set focus to the text box to do it because of the reliance on SendKeys. It's possible to emulate keyboard events directly to the control without having it in focus, using an API call.

Can I ask why it's necessary to have the cursor at the beginning of the selection? I cannot think of a scenario in which it would matter...

Private Sub ReverseSelect(txtBox As TextBox, SelStart As Long, SelLength As Long)

    Dim Iter As Long
    txtBox.SelStart = SelStart
    For Iter = 1 To SelLength
        SendKeys "+{LEFT}"

End Sub
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.


Expert Comment

ID: 9653004
Ignore my last. Here's some API code that does it easier:


    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

    Private Const EM_SETSEL = &HB1

Event Code:

Private Sub Command1_Click()
    Dim SelStart As Long
    Dim SelEnd As Long

    SelStart = 20
    SelEnd = 5

    PostMessage Text1.hwnd, EM_SETSEL, SelStart, SelEnd
End Sub

Notice that the SelStart and SelEnd are actual character positions. The code above selects 15 characters starting from character position 20 going backward to character position 5.

Author Comment

ID: 9653312
JCinDE - The SendKeys solution worked for what I requested.

I had tried the EM_SETSEL solution before (and retried your solution) but it still put the caret at the end of the selection.

What I discovered was that I posted the wrong question -so- I will repost a more accurate (separate thread) question for additional points (has to do with wanting to horizontally scroll what is visible in the Combo text area so that the first part is always visible - I thought moving the cursor to the front would do that for me).

Expert Comment

ID: 9653375
If the SelStart is greater than the SelEnd when calling the API I described then the blinking cursor will be at the left end of the selection. If the SelStart is smaller than the SelEnd then the cursor will be at the right end of the selection.


Author Comment

ID: 9653497
That's what the API says but I still can't get it to work.
I started over with a new project and it still puts the flashing caret at the end (right side) of the selection.
I even added:
   Text1.SetFocus that I could see the selection without having to tab to the control to see it.

I compiled and ran the .exe (with and without the SetFocus) incase it was something goofy while running interactively.

FYI - This is VB6 running on Win2K.

Author Comment

ID: 9653509
Accompanying question referred to in my 2:56PM post is entitled, "Horizontally Scroll Text in ComboBox - leaving the currently selected text alone." - Q_20783500.html

Expert Comment

ID: 9653513
Doh! Sorry. I just found this on MSDN's site:

    Edit controls: The control displays a flashing caret at the end position regardless of the relative values of start and end.

So that means the EM_SETSEL doesn't work afterall.

Anyway, for your actual question, try this API:

    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Const EM_SCROLLCARET = &HB7

Private Sub cmdTest_Click()

    Dim SelStart As Long
    Dim SelLength As Long
    SelStart = Val(txtStart.Text)
    SelLength = Val(txtLength.Text)
    ReverseSelect txtSingle, SelStart, SelLength
    PostMessage txtSingle.hwnd, EM_SCROLLCARET, 0, 0
    ReverseSelect txtMulti, SelStart, SelLength
    PostMessage txtMulti.hwnd, EM_SCROLLCARET, 0, 0
End Sub

This should scroll the textbox so the caret comes into view.

Author Comment

ID: 9655251
Ahhh, but I discovered that if you change an Edit control's style to ES_MULTILINE that it the EM_SETSEL will work.
I tried to change a ComboBox's associated Editbox's style to ES_MULTILINE but then no controls on the form responded.
I'll stick with the accepted answer.

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

786 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question