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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.


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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
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…

792 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