How to have text selected as I type

In a TextArea, I want to be able to have a section of just-typed text highlighted as a I type along. For instance, from the second character onwards. In the TextChange event, I’m doing this:

if (me.Text.len>1) then me.SelStart = 1 me.SelLength = me.Text.Len - 1 end if

But what happens is that I never get more than two characters in the TextArea, with the second highlighted and being replaced each time by a new character.

This is perhaps unsurprising since SelStart moved the insertion point as well as defining the start of the selected portion.

So, how do I select text without changing where the insertion point is? I only want the text highlighted for viewing purposes by the user, not (at this moment) with a view to changing it.

It’s not going to work like that. Selected text will get replaced at the next keydown event. I suggest creating a timer that gets reset at every keydown event and once the user stops typing it will then select all text.

However, if your user types really slow this won’t solve the issue. Maybe you should add your SelectAll code when the LostFocus event happens?

That’s the crux of the problem. Selection is more than just a visual so it’s a real fight to repurpose its behavior this way.

On mac I know of declares to set text background colors, I mean for individual letters/words. Maybe there’s something similar for Windows if you need that.

Or for something builtin you could use StyledText and highlight by changing the text color or underline.

[quote=283304:@Will Shank]On mac I know of declares to set text background colors, I mean for individual letters/words. Maybe there’s something similar for Windows if you need that.
[/quote]
What are the declares?

Hmmm, maybe it’s not so bad after all. I just verified how it operates in my existing code written in javascript that I am porting to Xojo. As the user types, event handler code checks whether what he’s typed so far matches an entry in a list. If so, I want to “complete” that for the user with highlighted text, but in fact the insertion point will need to be at the start of the highlighted text, so that’s OK.

For this particular aspect of my app, I’m at the “try something simple to see how it works in Xojo” stage, and that perhaps led me astray, because the “something simple” was not representative of what I actually need to do.

Still, chatting on here is helpful as it forces me to think, re-evaluate, check, …

You will probably find that a lot. Trying to force Xojo to do it way is almost always going to lead you down a dark, dismal, frustrating, and ultimately futile path.

What Xojo does very nicely is bolden and color text. From your description, maybe that would suffice to indicate the text has been found. Something like Bold Red could be just as effective. Or underlined.

Maybe do like Xojo and complete the word with dimmer text.

A TextArea is a NSScrollView. Get its documentView for the NSTextView and from that get textStorage. NSTextStorage is a subclass of NSMutableAttributedString which has the methods for adding attributes, like background color.

This code goes in a Module, only tested for 32bit, no error checking. Should be easy to update for 64bit. I used Xcode to get the attribute constant name.

[code]Sub setTextBGColor(extends ta As TextArea, start As integer, length As integer, bgColor As Color)

declare function NSClassFromString lib “Cocoa” (aClassName as CFStringRef) as Ptr
declare function docView lib “Cocoa” selector “documentView” (id As Ptr) as Ptr
declare function textStore lib “Cocoa” selector “textStorage” (id As Ptr) as Ptr
declare function colRGBA lib “Cocoa” selector “colorWithCalibratedRed:green:blue:alpha:” _
(cls As Ptr, r As single, g As single, b As single, a As single) as Ptr
declare sub addAttrib lib “Cocoa” selector “addAttribute:value:range:” _
(id As Ptr, name As CFStringRef, value As Ptr, aRange As NSRange32)
declare sub release lib “Cocoa” selector “release” (id As Ptr)

dim ts As Ptr = textStore(docView(Ptr(ta.Handle)))

dim range As NSRange32
range.location = start
range.length = length

dim colorCls As Ptr = NSClassFromString(“NSColor”)
dim col As Ptr = colRGBA(colorCls, _
bgColor.Red/255, bgColor.Green/255, bgColor.Blue/255, 1-bgColor.Alpha/255)

addAttrib(ts, “NSBackgroundColor”, col, range)

release(col)

End Sub

Structure NSRange32
location As UInt32
length As UInt32[/code]

demo…

TextArea1.Text = "abcdefg" TextArea1.setTextBGColor(2, 2, &c00FF00) //highlights "cd" in green

references…

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSScrollView_Class/
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextView_Class/
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextStorage_Class/
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSMutableAttributedString_Class/
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/index.html#//apple_ref/doc/constant_group/Character_Attributes

https://forum.xojo.com/32826-set-backcolor-for-specific-words-in-a-textarea/4
https://forum.xojo.com/27294-background-color-for-part-of-text-area/0

I just had a look to see how some other software handles this, and from what I’ve seen in search engine entry fields and similar things, it doesn’t highlight the text that’s already been typed, it only highlights the suggested text that is appended to the right of what has already been typed. This shouldn’t be hard to do.

TextArea and what you want to do - IMHO - is a wrong idea.

On the other hand, if you just need to type a single word a TextField may be used, this may be resolve your problem:

TextField with Autocomplete .

Of course, I may be wrong.