RedSyphon Posted November 12, 2009 Share Posted November 12, 2009 Hi All, Hope this is the right location for my question.... I have the following section in my code that tries to detect a code (konami code) and display a text message after it's been entered: expandcollapse popup;Show the splash screen SplashImageOn(<splash code here, it works so not including>) Dim $dll = DllOpen("user32.dll");Open the dll for input Dim $code = "" ;Holds the users entered code if any Dim $i = 0 ;Main loop counter while splash screen is shown ;Goal is to loop for ~5seconds, Using a counter to 50 and a sleep(100) roughly = sleep(5000) While $i < 50 ;Loop that will exit if the code has been entered, user has run out of time, and/or a code letter is pressed While 1 ;If the code string has the max code letters in it then check for a valid code If StringLen($test) >= 10 Then ;If the counter has less than 1 second left, or the code variable has a valid code If $i > 40 OR $test = "^^DOWNDOWN<><>BA" Then ;exit the main loop $i = 51 ;exit this loop ExitLoop EndIf ;Code variable had no valid code but user has time to enter $TEST = "" ;restart this loop ExitLoop EndIf ;Sleep for a 10th of a second Sleep ( 100 ) ;If a code key is pressed then record it If _IsPressed("26", $dll) Then $test = $test & "^" ExitLoop ElseIf _IsPressed("28", $dll) Then $test = $test & "DOWN" ExitLoop ElseIf _IsPressed("25", $dll) Then $test = $test & "<" ExitLoop ElseIf _IsPressed("27", $dll) Then $test = $test & ">" ExitLoop ElseIf _IsPressed("42", $dll) Then $test = $test & "B" ExitLoop ElseIf _IsPressed("41", $dll) Then $test = $test & "A" ExitLoop EndIf ;Increse the main loop counter to show a 10th of a second has gone by $i = $i + 1 WEnd WEnd ;Close out the dll file DllClose($dll) ;Test if the code was entered! IF $test = "^^DOWNDOWN<><>BA" Then MsgBox(0,"_IsPressed", "KONAMI CODE!") Else MsgBox(0, $test, "FAIL!") EndIf SplashOff() This is more of a easter egg proof of concept... The goal is while the splash page is displayed the user can enter in the code and if done right i'll run further operations accordingly... The reason I am using two while loops is the following: 1) I need to allow the user to enter a code and if entered in correctly i want to exit the splash screen right away. The inner while loop exits after a valid keystroke. And it will also set the main loop to exit upon a valid code entry, otherwise the program will just display the splash for 5seconds. 2) I also have found that sleeping for more than 1/4second, sleep(250) causes the program to not catch all the key strokes. Likewise anything under 1/10second, sleep(100), causes too multiple key strokes to be recoded! 3) I want to allow the user to type the code sequence as many times as possible within the 5 seconds until the program sees it.. That is why the $test = "", is there at within the inner loop if the user still has more than 1second left. Note: I receive no errors however entering at a fairly normal typing speed with the above code will result in the second message box displaying after 5seconds with a value that could be anywhere from "^^DOWNAB" to "^B", this is with me entering the code correctly each time.. I realize the code above isn't the nicest to look at however it's just test code at the moment.. My goal is to be able to record the user key strokes in real time... If anyone has suggestions, alternate methods, etc, etc, your input will be greatly appreciated!!!! Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted November 12, 2009 Moderators Share Posted November 12, 2009 RedSyphon,First, welcome to the Autoit forums. Using _Ispressed to capture multiple keystrokes is not the best way to go - as you have discovered. And keyloggers (which do exactly what you want) are persona non grata here because of the obvious possibility of malicious use.So, why not try an invisible input to capture the keystrokes? The only disadvantage that I can see is that you cannot use any of the cursor movement keys - you are limited to those keys which will display in an Input control. But that still leaves you a lot of scope. Look at this:; Create invisible GUI $hGUI = GUICreate("Test", 500, 500) $hInput = GUICtrlCreateInput("", 10, 10, 100, 20) WinSetTrans($hGUI, "", 0) GUISetState(@SW_SHOW) ;Show the splash screen^^ ;SplashImageOn("<splash code here, it works so not including>"9^^DD<><>AB ; Loop for exactly 5 seconds $iBegin = TimerInit() While TimerDiff($iBegin) < 5000 ;If the code string has the max code letters in it then check for a valid code If StringLen(GUICtrlRead($hInput)) = 10 Then ;If the counter has less than 1 second left, or the code variable has a valid code If TimerDiff($iBegin) > 4000 Or GUICtrlRead($hInput) = "^^DD<><>BA" Then ExitLoop EndIf Sleep(10) ; needed to prevent 100% CPU usage WEnd ;Test if the code was entered! If GUICtrlRead($hInput) = "^^DD<><>BA" Then MsgBox(0, "Success", "KONAMI CODE!") Else MsgBox(0, GUICtrlRead($hInput), "FAIL!") EndIf GUIDelete($hGUI) ;SplashOff()Note that using TimerInit and TimerDiff you can get exact timings without using long Sleeps - you still need a small Sleep in there to prevent the CPU burning up in a tight loop.If you think this is along the right lines, we could work on it a bit more.M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
RedSyphon Posted November 13, 2009 Author Share Posted November 13, 2009 Thanks for the reply! I haven't really considered a hidden field to capture the input... I'll play some tonight with this and see how it goes... I'm not too worried about the arrow keys as it's a "easter egg" type of thing anyhow.. All be it was requested I'll be sure to update the post. Thanks again! Link to comment Share on other sites More sharing options...
RedSyphon Posted November 13, 2009 Author Share Posted November 13, 2009 I tried adapting your method above and everything worked great save using the arrow keys.... I decided to merge the two ideas and came up with what I have copied below! It works flawlessly, I appreciate your help and the incite into using TimerInit() + TimerDiff() was killer!Now that the proof of concept is done I can clean up the code a bit (I hate long if statements), etc.Thanks Agian!Copied the code snippet below in the hopes someone else with a similar issue might benefit:expandcollapse popupDim $dll = DllOpen("user32.dll");Open the dll for input Dim $code = "" ;Holds the users entered code if any ;SpashImage features: Title=Yes, Always On Top, Windows can be moved SplashImageOn("Skydive Palatka Videoit Media Automation Program",@ScriptDir & "\skydive_palatka.jpg","1024","768","-1","-1",16) ; Loop for exactly 5 seconds dim $iBegin = TimerInit() While TimerDiff($iBegin) < 5000 ;If the code string has the max code letters in it then check for a valid code If StringLen($code) = 10 Then ;If the counter has less than 2.5 second left, or the code variable has a valid code If TimerDiff($iBegin) > 2500 Or $code = "^^dd<><>ba" Then ExitLoop Else $code = "" EndIf EndIf ;If a code key is pressed then record it If _IsPressed("26", $dll) Then $code = $code & "^" While _IsPressed("26", $dll) Sleep(10) WEnd ElseIf _IsPressed("28", $dll) Then $code = $code & "d" While _IsPressed("28", $dll) Sleep(10) WEnd ElseIf _IsPressed("25", $dll) Then $code = $code & "<" While _IsPressed("25", $dll) Sleep(10) WEnd ElseIf _IsPressed("27", $dll) Then $code = $code & ">" While _IsPressed("27", $dll) Sleep(10) WEnd ElseIf _IsPressed("42", $dll) Then $code = $code & "b" While _IsPressed("42", $dll) Sleep(10) WEnd ElseIf _IsPressed("41", $dll) Then $code = $code & "a" While _IsPressed("41", $dll) Sleep(10) WEnd EndIf Sleep(10) ; needed to prevent 100% CPU usage WEnd ;Close out the dll file DllClose($dll) ;Remove the Splash Image and continue running the program SplashOff() ;Test if the code was entered! If $code = "^^dd<><>ba" Then MsgBox(0, "Success", "KONAMI CODE!") Else MsgBox(0, $code, "FAIL!") EndIf Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now