|
-
Dec 16th, 2015, 01:43 PM
#1
Thread Starter
Addicted Member
Stop GetAsyncKeyState repeating
Is it possible to detect a keypress using GetAsyncKeyState only once instead of repeatedly? I don't want to detect it again until after the key has been released.
-
Dec 16th, 2015, 01:54 PM
#2
Re: Stop GetAsyncKeyState repeating
One way is to set a boolean when a key is down and released, something like...
Code:
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
Static KeyIsDown As Boolean ' to detect if a key is already down (no repeats).
Dim keyF3 As Short = GetAsyncKeyState(Keys.F3)
If keyF3 < 0 Then
if KeyIsDown = False then
KeyIsDown = True ' set flag key is down.
' < Do something here >
End If
Else
KeyIsDown = False ' reset key is down flag.
End If
End Sub
-
Dec 16th, 2015, 02:18 PM
#3
Re: Stop GetAsyncKeyState repeating
Not reliably. You should use other keyboard input events, such as the KeyUp event, to tell when keys are no longer pressed. If you're monitoring keystrokes towards applications that aren't yours, well, it's hard, because that's close to what a lot of shady programs do.
If we read the documentation, we see that GetAsyncKeyState() already tells us if the key's been pressed again or if it's a "repeat":
If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
But it also tells us that's not reliable. Why? Well:
Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.
In other words, "This worked 20 years ago, then we changed something that made it stop working in Windows 95, but Windows developers get upset if things change faster than every 50 years (No, seriously. VS 2010 is still 80% of our questions when for 6 years its successors have been free!), so we maintained the behavior even though it's not truthful anymore."
So it works, if no one else is using GetAsyncKeyState(). If they are, you'll both be stepping on each others' toes. "Works sometimes" is as good as "never works", in my book.
*edit* "Not Reliably" is in reference to GetAsyncKeyState(), and isn't a comment on Edgemeal's solution, which probably works, given the caveats that are associated with GetAsyncKeyState().
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 16th, 2015, 02:56 PM
#4
Thread Starter
Addicted Member
Re: Stop GetAsyncKeyState repeating
Thanks for the responses. I'll try Edgemeal's solution and see how it works in my program. If that fails, is there an alternative to GetAsyncKeyState I could use?
It's actually a program I'm making to enable the user to use an interface that has clickable elements (in another program) without using a mouse (that part of the program works). So, I need to capturing the keypresses whilst the other program is in the foreground. The issue I'm getting is that pressing the key or key combination (the user can customise it) flashing between the other program being full screen and windowed instead.
-
Dec 16th, 2015, 03:18 PM
#5
Re: Stop GetAsyncKeyState repeating
There's not a solution that's easily accessible from .NET, and really the better of the two is Dark Magic that 1) can't really be discussed from the forum and 2) is actually a little dangerous.
The first is the RegisterHotKey() function. It lets you register keys and associate them with a Window. In .NET terms, what it means is you can make sure you get an event raised any time a particular key is pressed. It's a little clunky and takes some work to use this API from .NET, but there's good tutorials out there.
The other is a keyboard hook. *hisses* This is a low-level system call that registers your program to see all keyboard input before anything else (except other keyboard hooks, if they exist.) I've played with one before, and it's doable from .NET, but it's also THE way to write a keylogger, so I don't exactly prepare tutorials or guidance. Besides, for various reasons writing hooks in .NET can lead to system instability, though it's not true for all hooks and I think some keyboard hooks are OK. Regardless, if you aren't careful you can accidentally get the system in a state where the keyboard stops working. Fun times. But I'm not talking about them.
If there's another way that I don't know about, I'd sort of like to know.
In terms of the RegisterHotKey() API, you might consider a tool like AutoHotKey. It's a scripting language for setting up hotkeys and performing automation tasks that's a good bit easier to use than VB for the same things.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 17th, 2015, 09:04 PM
#6
Thread Starter
Addicted Member
Re: Stop GetAsyncKeyState repeating
 Originally Posted by Edgemeal
One way is to set a boolean when a key is down and released, something like...
Thanks. That worked.
-
Mar 17th, 2026, 06:57 AM
#7
New Member
Re: Stop GetAsyncKeyState repeating
Thank you so much for this answer. You helped me understand a bit how GetAsyncKeyState() works and fixed my program. Even after all these years your answer was super helpful!! Thank you again very much?!!!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|