Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Validate characters as you type in an Edit control


  • Please log in to reply
2 replies to this topic
jsherk
  • Members
  • 65 posts
  • Last active: Jul 02 2014 12:27 PM
  • Joined: 11 Jun 2011
Here is a simple script I use to validate characters as they are being typed in an Edit control. It uses the RegExReplace and removes any unwanted characters from the string then writes the string back to the Edit control.

; Validate charcters as you type
Gui, Add, Text, x5 y10 w75 h20 , Type text here:
Gui, Add, Edit, x85 y10 w250 h20 hwndhMyText vMyText gOnChangeMyText, ;Add HWNDH for use with SendMessage EM_SETSEL
Gui, Add, Text, x5 y40 w75 h20 , You typed:
Gui, Add, Text, x85 y40 w210 h20 vTypedText, nothing yet
Gui, Show
return

GuiClose:
    ExitApp
return

OnChangeMyText:
    Gui, Submit, NoHide ; Get the info entered in the GUI
    NewText := RegExReplace(MyText, "[^0-9a-zA-Z_' \-]", "") ;Allow digits letters underscore_ apostrophe' space dash-
    If NewText != %MyText% ; Check if any invalid characters were removed
    {
        ControlGet, cursorPos, CurrentCol,, %MyText%, A ; Get current cursor position
        GuiControl, Text, MyText, %NewText% ; Write text back to Edit control
        cursorPos := cursorPos - 2 
        SendMessage, 0xB1, cursorPos, cursorPos,, ahk_id %hMyText% ; EM_SETSEL ; Add hwndh to Edit control for this to work
    }
    GuiControl, Text, TypedText, %NewText% ; Write text back to the "You Typed:" Text control
return
EDIT: Corrected the code above to fix the issue of the cursor always returning to the end of the line. It should now go back to wherever you were.
EDIT: I changed it again, and the new version corrects both issues noted below... no more shift problem and the cursor moves to the correct spot.

jballi
  • Members
  • 1029 posts
  • Last active:
  • Joined: 01 Oct 2005
Very clever. I usually do the old-school method of checking the data after the user is done with everything but verifying/correcting in real-time definitely has it's advantages.

I found a couple of problems. I hope you don't mind if I point them out.

When I tried to enter some invalid characters that required the use of the Shift modifier (Ex: "!", "@", "#", etc.), the script might correctly stop entry of the first keystroke but on the 2nd and subsequent attempt, the unshifted version of key (Ex: "1", "2", "3") is echoed. No, I don't know why it does this.

Also, invalid characters are correctly blocked on paste and when characters are inserted in the middle of already-entered text, however, the caret is alway moved to end the line. This can be quite unsettling if the user wants to insert/paste several characters in the middle of text.

I made a version of your script that uses the Edit Library to manipulate the Edit control. I haven't done any hard-core testing but it appears to correct the problems I mentioned. I hope this is helpful. Please use or ignore at your convenience.

#NoEnv

; Validate charcters as you type
Gui, Add, Text,,Type text here (2nd Edit control uses the Edit Library):
Gui, Add, Edit,w250 vMyText gOnChangeMyText,  ;-- Original
Gui, Add, Edit,w250 hWndhEdit gOnEditChange,  ;-- New.  Uses Edit Library
Gui, Add, Text,,You typed:
Gui, Add, Text,w250 vTypedText, nothing yet
Gui, Show
return

GUIEscape:
GuiClose:
    ExitApp
return

OnChangeMyText:
    Gui, Submit, NoHide ; Get the info entered in the GUI
    NewText := RegExReplace(MyText, "[^0-9a-zA-Z_' \-]", "") ;Allow digits letters underscore_ apostrophe' space dash-
    If NewText != %MyText% ; Check if any invalid characters were removed
    {
        GuiControl, Text, MyText, %NewText% ; Write text back to Edit control
        Send {End} ; Move back to the end of the Edit control
    }
    GuiControl, Text, TypedText, %NewText% ; Write text back to the "You Typed:" Text control
return

OnEditChange:
Text:=Edit_GetText(hEdit)
NewText:= RegExReplace(Text,"[^0-9a-zA-Z_' \-]","") ;Allow digits letters underscore_ apostrophe' space dash-
if (NewText<>Text)
    {
    Edit_GetSel(hEdit,StartSelPos,EndSelPos)    ;-- Get caret position
    Edit_SetText(hEdit,NewText)                 ;-- Replace text
    NewSelPos:=EndSelPos-(StrLen(Text)-StrLen(NewText))
    Edit_SetSel(hEdit,NewSelPos,NewSelPos)      ;-- Reposition caret
    }

return

#include Edit.ahk
    ;-- http://www.autohotkey.com/forum/viewtopic.php?t=55062


jsherk
  • Members
  • 65 posts
  • Last active: Jul 02 2014 12:27 PM
  • Joined: 11 Jun 2011
@jballi - Definitely appreciate your input and will consider your solution using your Edit.ahk

I knew about the shift key issue before I posted the code, and I found the other issue after I posted the code. I am working on a fix for the second issue using ControlGet with CurrentCol which would essentially do the same as what your code does, but for some reason am having a hard time getting it to work properly! Once I figure out ControlGet I will repost fixed code!

Thanks

EDIT: Ok, I got it working and fixed my original code above in the first post. But jballi's code is less buggy and probably the way to go!
EDIT: I changed the cursor move from Send to SendMessage and this is less buggy way to move cursor and also solves the shift key problem that existed before.