Page 2 of 2

Posted: Sun Jan 04, 2009 3:07 pm
by Trond
You know, just for shits and giggles (as the saying goes) I decided to try
Trond's code. And you know what? Not only did it NEVER miss the "n" key
when I pressed it, my own app STILL captured all of them too! So, what
do you have to say now?
I'm saying that you didn't have another thread/process with higher priority using all available cpu time while you tested the code. And maybe you have a dual-core, that would lessen the error rate somewhat. But there may still be errors if both cores are occupied with something else.

Heck, on this older computer it skips letters even when the computer is not under load, when the key is held down instead of pressed multiple times (I've set the repeat rate to fastest in the control panel, because that's how I like it).

PB, I'm sure that if you think about why it may fail sometimes, you will understand it without problems.

Posted: Sun Jan 04, 2009 9:12 pm
by PB
> I'm saying that you didn't have another thread/process with higher
> priority using all available cpu time while you tested the code

I think running Doom3 while downloading files from the internet is a big CPU
hit for my app, and yet it still works. Not a dual-core either, just a P4 at 2 ghz,
but my code also used to work on a P3 at 667 mhz.

> if you think about why it may fail sometimes, you will understand it

I know what you're saying, but in reality it doesn't fail. Anyway, we're just
going round and round, aren't we? :)

Posted: Sun Jan 04, 2009 11:01 pm
by Trond
What part of "higher priority" is it that you can't see?

http://willhostforfood.com/files3/6478740/failed.avi

The "fail factor" is dependent on the delay. Shorter delay means less failing, but the possibility is always there.

Posted: Mon Jan 05, 2009 12:19 pm
by PB

Posted: Mon Jan 05, 2009 2:39 pm
by Trond
I know it may work. I'm just saying that it may also fail.

Posted: Mon Jan 05, 2009 9:13 pm
by PB

Re: Replace text while typing

Posted: Sat Jul 17, 2010 7:04 pm
by rsts
I followed this discussion with interest and implemented getAcyncKeyState in my program.

Trond is correct. It can fail - (and most likely, eventually will).

cheers

Re: Replace text while typing

Posted: Sun Jul 18, 2010 12:41 am
by PB
> I followed this discussion with interest and implemented getAcyncKeyState in my program.
> Trond is correct. It can fail - (and most likely, eventually will).

Why'd you re-open this old wound, over a year later? I'm not getting into it again. ;)

Re: Replace text while typing

Posted: Sun Jul 18, 2010 4:29 am
by rsts
Sorry, it was not meant to open any wounds. It was offered merely as additional information, since after reading this, I was unsure and tried using getasynchkeystate, hoping it would work. It usually does, but not always. Just didn't want someone else to follow in my footsteps, because it can take a while to surface.

cheers

Re: Replace text while typing

Posted: Sun Jul 18, 2010 10:59 am
by netmaestro
rsts wrote:I was unsure and tried using getasynchkeystate, hoping it would work. It usually does, but not always.
Your experience bears out what MSDN says the case should be. GetAsyncKeystate is advertised as being capable of returning a) whether the key is currently down at the time the function call is executed; and b) whether or not the key has been pressed (whether currently down or not) since the last call to GetAsyncKeystate. Testing for a) involves examining the most significant bit of the return value (result & 32768). If you get a true return there, you can believe the key is down, 100% of the time. b) however, which you test for by examining the least significant bit, was reliable with Win9x and older but is not anymore. This is because those 16bit OS's used a non-preemtive approach to multitasking, which was changed when NT/2000/XP was introduced. Multitasking in current Windows versions is preemptive and this means that if another process tests AsyncKeystate since your last test, they can steal your least-significant-bit result right out of the buffer, which makes your test unreliable. Anyway, here's the relevant text from MSDN:
MSDN wrote: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.
There is no basis for a difference of opinion on this subject as Microsoft has made this behavior perfectly clear. Bottom line is, if you want reliability in global keypresses, use a hook.

Re: Replace text while typing

Posted: Sun Jul 18, 2010 11:19 am
by PB
Okay, I'll just reply to this, because I don't want to continue this year-old debate:

> Testing for a) involves examining the most significant bit of the return value (result & 32768).
> If you get a true return there, you can believe the key is down, 100% of the time.

That's what I'm testing for: whether the key is currently down. And as you've confirmed,
this is 100% reliable, no matter which other process may be testing GetAsyncKeyState too.
My app is not concerned with "previous presses" at all. Just the current state of the key.
And in my 5+ years of using it, it's NEVER, NEVER, NEVER MISSED A SINGLE KEYSTROKE.
Not even when used in conjunction with CPU-intensive games (such as Doom3 and Crysis).

Maybe the others who tested it were testing for previous keystrokes, which of course can
make it fail, as you've said. But the way I've coded it, the only way for my app to miss a
keystroke is for the user to be typing at a rate of more than one keystroke per millisecond,
which is physically impossible. And I've had ZERO support emails from ANYONE using my app
in those 5+ years, complaining that it misses keystrokes. So, it works. It's out there in the
field in a real-world app and it works. Not just for me, but also for all my users. Peace. :)

Re: Replace text while typing

Posted: Sun Jul 18, 2010 11:28 am
by netmaestro
The question originally asked was how to capture global keypresses in other applications (mail, e.g. was the example given). Hooks are the answer and remain so. I don't know anything about your applications and I don't see how referring to them is relevant to this discussion.

Re: Replace text while typing

Posted: Sun Jul 18, 2010 5:38 pm
by rsts
>IF you get a true return there, you can believe the key is down, 100% of the time.

I don't believe he said it works 100% of the time. He said IF you get a return, there's been a keypress.

You can MISS a return when a key has been pressed. It can fail. That's all I'm saying. Anyone who codes an app, depending on getasynchkeystate capturing ALL keyboard activity is setting themselves up for possible failure.

It works for you and that's great. But it doesn't always work.

If you want to argue it, try these guys.

http://en.wikipedia.org/wiki/Keystroke_logging

"Passive Methods: Here the coder uses operating system APIs like GetAsyncKeyState(), GetForegroundWindow(), etc. to poll the state of the keyboard or to subscribe to keyboard events. These are the easiest to write, but where constant polling of each key is required, they can cause a noticeable increase in CPU usage and can miss the occasional key. "