Sign in to follow this  
Followers 0
AmbiguousJoe

Finding the caret position

4 posts in this topic

So I'm building a data entry screen and I want the caret (aka: insertion point or cursor) to automatically jump to the next field when the character limit is reached. However, it needs to be a bit smarter than that. I have two extra scenarios that I need to handle.

Scenario 1:

Lets say I reach my character limit for the first field (12) and continue typing, but then I notice I mistyped something in the first field. I delete the typo, and then begin to correct it. This new word happens to be longer than the previous word, so I hit the character limit while in the center of the field. At this point, the caret stops typing in the middle of the first field and jumps to the next field. The extra letters wind up overwriting the second field, and now all the information is a mess (both fields are incorrect). You can see this by running the code below and typing "Typing across multiple fields." In the first field, highlight the the word "Typing" and start typing "Testing across multiple fields."

-Instead of automatically jumping, I would prefer one of two things to happen: either nothing happens when you continue typing, or the rest of the text in the same field starts being overwritten.

Scenario 2:

I type something that happens to be the exact length of the character limit (12) ie: "it's strange". I change fields to enter information elsewhere in the form. Later I decide to come back to add more to the first field. I click on the first field, and start typing ", nothing types". Because the caret is already at the character limit, nothing triggers and nothing gets typed. I would like the the caret to automatically jump to the next field and start typing in that field if this occurs.

In either situation, it seems I need to know the caret position in order to code for these possibilities. At the least, I need to test if it's at the end of the field's character limit. The overwrite code would be a bit more tricky, but may still need to get the caret's position, so it can start replacing text. I tried using WinGetCaretPos(), but that gives the X & Y coordinates of the caret, which will change based on the length of the characters being typed. There are several other functions which use the caret positions, but don't provide a way to find it.

The code I'm using was posted by Siao in thread:

#include

Global $input_limit = 12

$gui = GUICreate("InputBox autofocus demo", 350, 100)
$in1 = GUICtrlCreateInput("", 40, 20, 80, 20)
GUICtrlSetLimit(-1, $input_limit)
$in2 = GUICtrlCreateInput("", 140, 20, 80, 20)
GUICtrlSetLimit(-1, $input_limit)
$in3 = GUICtrlCreateInput("", 240, 20, 80, 20)
GUICtrlSetLimit(-1, $input_limit)
$btn = GUICtrlCreateButton("OK", 100, 60, 50, 25)

GUIRegisterMsg(0x0111, "On_WM_COMMAND")
GUISetState()
While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
         Case $btn
             $str = GUICtrlRead($in1) & " " & GUICtrlRead($in2) & " " & GUICtrlRead($in3)
             MsgBox(0, "You have entered", $str)
     EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
     $nNotifyCode = BitShift($wParam, 16)
     $nID = BitAnd($wParam, 0x0000FFFF)
     Switch $nNotifyCode
         Case 0x400 ;$EN_UPDATE
             If StringLen(GUICtrlRead($nID)) = $input_limit Then GUICtrlSetState($nID+1, $GUI_FOCUS)
     EndSwitch
EndFunc

Share this post


Link to post
Share on other sites



Create variable switches for each field. For example, set 3 switches ($switch[3] = [0,0,0]). When field 1 reaches it's limit toggle $switch[0] = 1. When you check for the character limit in your On_WM_COMMAND(), if the switch is on, don't perform the GUICtrlSetState().


Spoiler

“Hello, ladies, look at your man, now back to me, now back at your man, now back to me. Sadly, he isn’t me, but if he stopped using ladies scented body wash and switched to Old Spice, he could smell like he’s me. Look down, back up, where are you? You’re on a boat with the man your man could smell like. What’s in your hand, back at me. I have it, it’s an oyster with two tickets to that thing you love. Look again, the tickets are now diamonds. Anything is possible when your man smells like Old Spice and not a lady. I’m on a horse.”

 

Share this post


Link to post
Share on other sites

Create variable switches for each field. For example, set 3 switches ($switch[3] = [0,0,0]). When field 1 reaches it's limit toggle $switch[0] = 1. When you check for the character limit in your On_WM_COMMAND(), if the switch is on, don't perform the GUICtrlSetState().

Hmm, that would solve scenario 1, but not scenario 2 (unless I'm thinking of it in the wrong way). I like the thinking behind that solution though, and may use it elsewhere in my script.

-Preventing SetState from occuring if the field switch is set to 1-

Scenario 1: The switch for field 1 triggers the first time the user hits the character limit, preventing future auto-jumps while editing information in the first field.

Scenario 2: The user types something in the field that is the same character limit (or copies & pastes into the field). The user clicks the end of the field and attempts to type, but nothing happens since the field is already at the limit. The user would prefer auto-jump in this case, since they're already at the end of the field.

I'm trying to mimic a system that coworkers in my department are already used to. With the software they use, if they hit the character limit, and their caret is in the middle of a field, it prevents auto-jumping to the next field. However, if they click at the end of a field that's already reached the character limit, attempting to type something will automatically jump to the next field. It's one of the few things they like about their current software.

Being able to obtain the caret position would also allow me to jump-back a field if they press backspace on the first character position of a field.

Share this post


Link to post
Share on other sites

Try this on for size:

#include <GUIConstants.au3>

Global $input_limit = 12

$gui = GUICreate("InputBox autofocus demo", 350, 100)
$in1 = GUICtrlCreateInput("", 40, 20, 80, 20)
GUICtrlSetLimit(-1, $input_limit)
$in2 = GUICtrlCreateInput("", 140, 20, 80, 20)
GUICtrlSetLimit(-1, $input_limit)
$in3 = GUICtrlCreateInput("", 240, 20, 80, 20)
GUICtrlSetLimit(-1, $input_limit)
$btn = GUICtrlCreateButton("OK", 100, 60, 50, 25)

GUIRegisterMsg(0x0111, "On_WM_COMMAND")

GUISetState()

While 1
     Switch GUIGetMsg()
         Case $GUI_EVENT_CLOSE
             Exit
         Case $btn
             $str = GUICtrlRead($in1) & " " & GUICtrlRead($in2) & " " & GUICtrlRead($in3)
             MsgBox(0, "You have entered", $str)
     EndSwitch
WEnd

Func On_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    $nID = BitAnd($wParam, 0x0000FFFF)
    If StringLen(GUICtrlRead($nID)) = $input_limit And ControlCommand($hWnd, "", $nID, "GetCurrentCol") = 13  Then GUICtrlSetState($nID+1, $GUI_FOCUS)
EndFunc

Forget about looking for the field to update... just look for an input and read the necessary data. ControlCommand() with "GetCurrentCol" is like reading the caret position for a single-line field. You could use the GuiCtrlEdit set of functions to search for a true index position, but using ControlCommand() keeps it native and works for what is necessary.


Spoiler

“Hello, ladies, look at your man, now back to me, now back at your man, now back to me. Sadly, he isn’t me, but if he stopped using ladies scented body wash and switched to Old Spice, he could smell like he’s me. Look down, back up, where are you? You’re on a boat with the man your man could smell like. What’s in your hand, back at me. I have it, it’s an oyster with two tickets to that thing you love. Look again, the tickets are now diamonds. Anything is possible when your man smells like Old Spice and not a lady. I’m on a horse.”

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0