Sign in to follow this  
Followers 0
jvanegmond

Capture {ENTER} key in an Input or Edit Control

7 posts in this topic

I have seen this been asked so many times, but I've not found any solutions except _IsPressed and Hotkeys. Both are bad ways to do this. Here is how I have solved this problem. (Capturing this in an Input control is not recommended, I suggest using a Edit Control with height 21)

; Both includes are required
#include <GUIConstants.au3>
#include <Misc.au3>

Dim $PreviousStringLenght

; Set up a basic test GUI
GUICreate("Test", 200,100)
$InputControl = GUICtrlCreateEdit("",5,5,190,21*3, BitOR($ES_WANTRETURN,$ES_AUTOVSCROLL))

GUISetState()

; Start the main loop
While 1
    $ControlRead = GUICtrlRead($InputControl) ;Read data from the control
    
    If StringRight($ControlRead,2) = @CRLF Then ; if the last characters are {ENTER} then do things
    
        If _IsPressed(10) Then ;Checks if {SHIFT} is pressed so you can still use multiple enters
            
            $PreviousStringLenght = StringLen($ControlRead) ;Capture the lenght of the string, to see when something has changed
            
        ElseIf $PreviousStringLenght <> StringLen($ControlRead) Then ;on next occasion, where {SHIFT} is not pressed, check if the String lenght has changed. If so, then do this
            
            $ControlRead = StringTrimRight($ControlRead,2) ; Delete the {ENTER} from the end
            GUICtrlSetData($InputControl,$ControlRead) ; This is optional data, but I've done this so that the user will not see that the enter is not really captured
            MsgBox(0, "Test data", $ControlRead) ; Do something with the data, in this case display it in the MsgBox
            
        EndIf
        
    EndIf
    
    If GUIGetMsg() = -3 Then Exit ; Checks to see wether the GUI's close button has been pressed
WEnd

Share this post


Link to post
Share on other sites



This is good and commented well. It's a good way to capture enter without a button.


My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop.

Share this post


Link to post
Share on other sites

I understand. This method is only useful in Edit controls where you still want to be able to send an {ENTER} by pressing +{ENTER}. Such methods are often used in Instant Chats, which I have often seen using HotKey("{ENTER}", ... or _IsPressed.

Share this post


Link to post
Share on other sites

The recommened way to trap keys in an input box is to subclass the control and get the WM_CHAR message.

// First subclass the edit control
     // hEdit is a handle to the edit control
     WNDPROC oldProc;
     oldProc = (WNDPROC)SetWindowLong(hEdit, GWL_WNDPROC, (LONG)EditProc);
     
     ...
     
     // Handle the messages to that subclassed edit control
     LRESULT CALLBACK EditProc(HWND hEdit, UINT msg, WPARAM wParam, LPARAM lParam)
     {
     switch(msg)
     {
     case WM_KEYDOWN:
     case WM_CHAR:
     if(/*The pressed key is not permitted*/)
     return 0;
     break;
     
     case WM_DESTROY:
     // Reset the message handler to the original one
     SetWindowLong(hEdit, GWL_WNDPROC, (LONG)oldProc);
     return 0;
     }
     
     // Process the message using the default edit control handler
     return CallWindowProc(oldProc, hEdit, msg, wParam, lParam);
     }

I don't know of a way to do that with controls in AutoIt like we can do for GUI's with GuiRegisterMsg because we need a callback func. It would be nice to have a GUICtrlRegisterMessage that would let use do that. Until never, here's another workaround example for trapping the {ENTER} key in a simulated input box using an edit control, No HotKeys, No _IsPressed :

;;Author - eltorro
;;Trap enter key on an edit box.
#include <GuiConstants.au3>
Global Const $EN_CHANGE = 0x0300
Global Const $EN_UPDATE = 0x400
Global Const $WM_COMMAND = 0x0111

Opt("GUIOnEventMode", 1)
$gui = GUICreate("gui")
GUISetOnEvent($GUI_EVENT_CLOSE, "ExitFunc")
$input = GUICtrlCreateEdit("adfadfjhdd", 5, 5, 190, 17, BitOR($ES_WANTRETURN, $ES_AUTOVSCROLL));has to have $ES_AUTOVSCROLL
$button = GUICtrlCreateButton("Exit", 25, 25)
GUICtrlSetOnEvent(-1, "ExitFunc")
GUISetState()

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    Sleep(100)
WEnd
Exit

Func ExitFunc()
    Exit
EndFunc   ;==>ExitFunc

Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $nID = BitAND($wParam, 0x0000FFFF)
    If $nID = $input Then  ;the input control
        If $nNotifyCode = $EN_UPDATE Then
            If StringRight(GUICtrlRead($input),2) = @CRLF Then
                ;delete the return (also prevents the edit box from scrolling)
                Send("{BS}")
                ;Do something like move to the next control in zorder.
                Send("{TAB}")
            EndIf
        EndIf
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

How is this practical in a input-control when it can be triggered by simply checking GUIGetMsg

Most of the time not. The only downside I see is that the input-control has to have some kind of change happen in order for the Enter key to generate the message. Clicking on an empty control, the Enter key does nothing. Click on an empty control and press Space for example, Enter works. Just an observation.

Regards,

eltorro

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

one problem with GUIRegisterMsg($WM_COMMAND, "WM_COMMAND"), is that well from what i've tried is that autoit ignores any other functions that make use of GUIRegisterMsg($WM_COMMAND, ''), so the first function listed gets registered and others are ignored..

or i could be wrong.. :)

Edited by mrRevoked

Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


Link to post
Share on other sites

one problem with GUIRegisterMsg($WM_COMMAND, "WM_COMMAND"), is that well from what i've tried is that autoit ignores any other functions that make use of GUIRegisterMsg($WM_COMMAND, ''), so the first function listed gets registered and others are ignored..

or i could be wrong.. :)

What do you mean? Can you provide an example?

eltorro.

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