Silverfrost Forums

Welcome to our forums

Position/Sense the cursor in a %rs

4 Apr 2019 10:11 #23433

I was curious if there are function that set and return the current cursor position within a %rs control?

My issue is I'd like to intercept the user's typing and automatically select a choice from a list of possible choices, continuing to narrow the selections down with each key stroke.

For example if my choices are:

HAB HAC HAAD

And the user types HAA, then the control shows HAAD with the cursor between the second A and the D.

5 Apr 2019 6:18 #23436

%rs uses a Microsoft edit control so you could use %lc to get the HWND of the control and then send a EM_GETSEL message...

pos = SendMessage(hwnd, EM_GETSEL, 0, 0)

This would work if the user has not selected a number of characters together. Otherwise you might need to use the third and fourth arguments of SendMessage.

5 Apr 2019 1:13 #23441

Thanks, Paul. I'll give it a try.

5 Apr 2019 1:34 #23442

This works, with the value of the starting and ending character (in my simple test case, the same) returned in POS as 2 16-bit integers packed into the 32-bit return value.

To use the third and fourth parameters, they must be specified as loc(xx). This returns the start and end as 32-bit quantities (no unpacking needed)

I'll experiment with EM_SETSEL next.

Thanks again!

5 Apr 2019 1:55 #23443

For EM_SETSEL, the third and fourth parameters are the value to which the cursor position should be set.

It also has (in the MSDN documentation) some other characteristics that I'll have to experiment with to find the right combination.

That said, this looks like I'll be able to use it as I had intended.

Again, many thanks, Paul!

5 Apr 2019 3:35 #23444

If you prefer, you could avoid using LOC by defining an alternative interface for SendMessage in which VAL is replaced by REF for the 3rd and 4th arguments.

5 Apr 2019 3:48 #23445

Paul, good suggestion.

That said, it kind of 'fits' since the two arguments can be references or data values, depending on the message. Just requires some more care by the user to make sure the arguments are of the right type!

5 Apr 2019 5:24 #23446

Bill,

If there are a limited number of choices, then getting the user to select from a drop-down list is a good solution, as then you can populate the list with valid choices, and you don't need to check that the user has typed the selection correctly.

I struggled with a far less complex case than yours, namely a 1 or 2 character code. I solved that with a radio button pair that gave the choice of 1 or 2 characters. A simpler alternative if up to 4 character codes are possible is a drop-down list from which the user can select 1, 2, 3 or 4.

Hope this is of some help.

Eddie

5 Apr 2019 5:24 #23447

Bill,

If there are a limited number of choices, then getting the user to select from a drop-down list is a good solution, as then you can populate the list with valid choices, and you don't need to check that the user has typed the selection correctly.

I struggled with a far less complex case than yours, namely a 1 or 2 character code. I solved that with a radio button pair that gave the choice of 1 or 2 characters. A simpler alternative if up to 4 character codes are possible is a drop-down list from which the user can select 1, 2, 3 or 4.

Hope this is of some help.

Eddie

5 Apr 2019 6:58 #23449

Eddie,

Thanks for your solution. It helps to have another perspective.

I am exploring a number of options to assist selection of data/parameters. One of the limitations is the size of a %ls being 32678 characters. For this part of the selection, it could be the %ls might display over 1000 entries. Having a control that can display potential selections as the user is typing (kind of a peek ahead) can speed the process. For example, there may be 30 entries that start with 'H', but only 1 or a few that start with 'HA'. Changing from keyboard to mouse back to keyboard (what most people do because they are not aware of using keyboard focus shifting) takes time and some degree of concentration. I'm searching for a solution that minimizes both. The user knows what they want (usually).

So, I'm experimenting with things I've seen used in the past that seem to work well in their own application, just to see if I can duplicate the look/feel.

It's fun!

Bill

6 Apr 2019 8:22 #23455

I assume that you have a a need for something like my car GPS which has a system with a touch-screen on which a keyboard is displayed when 'Destination entry' has been selected. The letters and numerals can be disabled (greyed out). Only valid continuation characters are enabled.

So, if one had already typed HEAV, the only keys available are E, I and Y. If Y is pressed, the only available keys are 'space' and 'backspace'. and the word is displayed as HEAVY. If I is selected, the display is updated to 'HEAVISIDE', and again, only 'space' and 'backspace' are available. However, if 'E' is selected, letter keys D, N and S remain selectable.

Assuming this is the effect you are seeking, it seems to me that the entry shouldn't be directly into a %rs box, but instead, you need to use the %'rs option, and to sample the keypresses with ADD_KEYBOARD_MONITOR@, then if valid options are pressed, update the display with WINDOW_UPDATE@

Because you can't grey-out the keys on a physical keyboard, you can just ignore the inappropriate ones, or reward the user with a BEEP@ !

As to how you manage the dictionary, I haven't got a clue, but it is probably some sort of tree structure*. I did a Google search, and there seem to be multiple options. One page suggested the cellphone autocomplete algorithm, but I always have autocomplete turned off, as once I get to SHI , the phone won't let me finish SHIN or SHIP or even SHILOH, but gives me an unacceptable choice!

It's also probably clumsy in Fortran, and if ever I had to re-invent that particular wheel, my solution would be brute force rather than elegant. I think that I would have to remember the actual acceptable keypresses so that a 'backspace' would have the capacity to remove more than one character if a group had been inserted, as in ISIDE with just I. Then, a backspace would revert to HEAV, not HEAVISID.

There is also the benefit that the whole computer's processing power is available while the user is interacting with it, and some elaborate work on the dictionary can be done seemingly without delay. So the computer could search the dictionary even if it was simply an alphabetical list to decide what characters were acceptable at any time.

Eddie

*The sort of thing that computer scientists love. It's in the lecture course after the point that most engineers have already left.

6 Apr 2019 9:51 #23456

Eddie, it may be of interest to you to read about 'perfect hashing', i.e., hashing without 'collisions'. See https://en.wikipedia.org/wiki/Perfect_hash_function .

Perfect hash algorithms are slower than plain hashing algorithms. However, if speed is not a factor to worry about, the use of perfect hashing relieves you from having to write code to resolve hash collisions.

6 Apr 2019 12:42 #23458

Eddie, thanks for your well considered reply.

Since I am investigating what I might do, I've been trying different possibilities. This was/is one of them. If I cannot work out the kinks or it becomes convoluted, then it gets abandoned. I don't like convoluted code. Makes it hard to maintain.

Again, thanks for the comments.

Bill

6 Apr 2019 12:52 #23459

Hi Mecej4,

I was hoping that you or jalih would respond, because programming such algorithms lies outside my usual range of activities. The point of the post, if it is discernable from the usual ramble, is that one is probably better using %'rs and ADD_KEYBOARD_MONITOR@ than delving into the realms of some undocumented (or needing to be developed) extension of the Clearwin+ code.

Bill's range may well extend to hash tables and tree structures, but mine does not. One has to accept one's limitations! However, with a dictionary of only around 1000 entries, it could be searched repeatedly for subsequent valid letters and still be done faster than anyone is likely to be able to type.

Eddie

7 Apr 2019 3:50 #23462

Just to clarify, my potential application is only a few thousand entries at most, and, yes, I can do a search faster than the user can type.

That said, I am open to all kinds of ideas.

I have also experimented with %el, but this control has a few idiosyncrasies that I haven't worked through. It might work, but.....

I might end up with a %rs to enter the string, while the %ls adjacent to it changes its contents(and limits) based on what was typed. I used something similar to this when writing a different section, where what the user types changes a %lv dynamically to limit choices.

The list from which the user chooses is a name of a quadrangle map. The user will typically abbreviate the actual quadrangle name (i.e. removing all the vowels). Thus, typing the consonants of the name quickly yields the result. perhaps even in a few keystrokes.

7 Apr 2019 9:14 #23465

Bill,

When entering text data into Excel sheets, it is interesting when excel chooses to complete the data input. Is this what you are attempting to replicate ? If so, is there any info in Excel to give some tips ?

John

7 Apr 2019 12:57 #23466

John,

Simply stated, yes, that's the intent.

In Excel, however, if you have two strings that match what has been typed, there is no 'suggestion' given. Which makes sense since there is an ambiguity. This has caused me some errors in the past - I don't touch type, so I don't see the 'fill-in' appear.

For some of my users, the quadrangle name, after a certain point, becomes unique. For example HANDSHOE and HANDISH become unique when the 5th character is typed.

For people like me who cannot touch type, it makes little difference since we won't see the 'fill-in' as we type. I'll type the whole name each time. But for others, it will/might.

I'll need to 'roll out' a new version for testing of this human interface change to see if the variants to entry actually make a difference to anyone, or if simpler is indeed always better.

BTW, once a name has been entered, it will remain throughout the remainder of the session until changed by the user. No matter where it is used. This saves the most time possible by not having to enter identifying information more than required.

Bill

8 Apr 2019 8:36 #23467

Bill,

Having idled away several hours toying with your problem, it occurred to me that I had never done anything of the sort. It dawned on me why this morning as I contemplated the tiles in the bathroom.

Rather than pick a square by name, I would draw the grid of squares on the screen in a %gr region, and invite the user to pick one with the mouse pointer. If there were too many squares to resolve individuals, I might either block-select a region (click-n-drag) or accept a click and select an appropriate number of squares around it, Then, I would display that subset, and invite a new pick.

You can get a zoom effect by redrawing the whole grid repeatedly, changing the scale factor each time - on my PC I have to use a timer otherwise I don't see the intermediate steps.

You did say you were open to new ideas.

Eddie

8 Apr 2019 12:53 #23468

Eddie, what a novel concept! I'll take a deeper look at this to see if it will work for one of the larger data sets (won't fit in a %ls).

Thanks, Bill

Please login to reply.