Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to detect physical mouse and/or keyboard activity ?

735 views
Skip to first unread message

R.Wieser

unread,
Mar 10, 2015, 8:49:07 AM3/10/15
to
Hello All,

I've written a small program which uses SendInput to generate mouse as well
as keyboard activity. I would like to (temporary) stop generating such
activity as soon as the physically-connected mouse or keyboard is used.

The problem is in how to dectect such physically-connected device activity.


I've tried to use RegisterRawInputDevices for the mouse, but a SendInput
(which in my test case centers the mouse) *also* generates WM_INPUT
messages. So thats a no-go.

I was also thinking of checking if WM_MOUSEMOVE, WM_KEYDOWN and -UP messages
are of the non-generated kind, but googling did not turn anything up in that
regard (I'm not even sure which search phrase I should use).

Another way would be to add a flag to the SendInput generated events, but
again my googling in that direction turned up zilch.

Regards,
Rudy Wieser



Deanna Earley

unread,
Mar 10, 2015, 9:52:28 AM3/10/15
to
On 10/03/2015 12:49, R.Wieser wrote:
> I've tried to use RegisterRawInputDevices for the mouse, but a SendInput
> (which in my test case centers the mouse) *also* generates WM_INPUT
> messages. So thats a no-go.

Surely you know what "inputs" are generated by you and you can ignore them?
I'd hope this is synchronous to SendInput(), but if not, you could detect inputs to your destination window or similar.

--
Deanna Earley (d...@earlsoft.co.uk, d...@doesnotcompute.co.uk)

(Replies direct to my email address will be printed, shredded then fed to the rats. Please reply to the group.)

JJ

unread,
Mar 10, 2015, 10:59:33 AM3/10/15
to
SendInput doesn't generate physical inputs. It only inject/insert them into
the input buffer (in the kernel memory space).

Raw Input is for for native HID USB devices only (those that don't emulate
PS/2 interface). It doesn't apply for PS/2 or COM input devices.

At user mode, you can only block keystrokes from reaching applications by
hooking the inputs via SetWindowsHookEx() low level keyboard and mouse
hooks. It can capture both injected and physical inputs as well as identify
whether an input was injected or not.

R.Wieser

unread,
Mar 10, 2015, 11:54:51 AM3/10/15
to
Deanna,

> Surely you know what "inputs" are generated by you
> and you can ignore them?

Nope. Both because I have no means to descern between "mine" and "not mine"
messages, as well as my program mostly not being the recipient of the
"inputs"

Its not about ignoring messages, its about (temporarily) not executing the
command (SendInput) that would generate them. The question is, how do I
recognise when to stop generating them.

> I'd hope this is synchronous to SendInput(),

I'm not sure what you mean here/how its related to the currently described
problem.

> but if not, you could detect inputs to your destination
> window or similar.

Sorry, not possible. The windows the messages are going to are varying,
most often part of programs I did not write myself.

Regards,
Rudy Wieser


-- Origional message:
Deanna Earley <d...@earlsoft.co.uk> schreef in berichtnieuws
mdmsuo$tl7$1...@speranza.aioe.org...

R.Wieser

unread,
Mar 10, 2015, 11:54:51 AM3/10/15
to
JJ,

> SendInput doesn't generate physical inputs.

I would hope not ! I know that my mouse does not have any motors inside, so
I would probably freak out when it would start to move around on its own.
:-)

What SendInput *does* do is inject messages at a deep enough level to make
RegisterRawInputDevice think that they where -- which I didn't expect as I
presumed that the "Raw" in that command was as in "RawInput", not as in
"RegisterRaw" (no idea what that would mean though).

> At user mode, you can only block keystrokes

You misunderstood. I do not want to *block* keystrokes (and mouse
messages), I want to stop them from being generated by SendInput by
(temporarily) not executing that command.

The problem is to *detect when* to (temporarily) stop executing that
command.

> Raw Input is for for native HID USB devices only (those
> that don't emulate PS/2 interface). It doesn't apply for
> PS/2 or COM input devices.

Which brings us back to the question: "The problem is in how to dectect such
physically-connected device activity" (and yes, I even left the typo in
there :-) )

Regards,
Rudy Wieser


-- Origional message:
JJ <jj4p...@vfemail.net> schreef in berichtnieuws
1j22k4kmzytrp.ol9b617nej5h$.dlg@40tude.net...

Deanna Earley

unread,
Mar 10, 2015, 12:51:30 PM3/10/15
to
On 10/03/2015 15:40, R.Wieser wrote:
> Its not about ignoring messages, its about (temporarily) not
> executing the command (SendInput) that would generate them. The
> question is, how do I recognise when to stop generating them.

By ignore, I meant not counting them toward "real usage".

>> I'd hope this is synchronous to SendInput(),
>
> I'm not sure what you mean here/how its related to the currently
> described problem.

If it was synchronous, set a flag saying "I'm calling XX" and clear it
when it returns.
If that flag is set when your callback executes, you know it's your
"input" and can be ignored.
If that flag isn't set, it's not come from you, and is either from some
other app, or the real user, therefore counting towards your "Computer
is in use, don't do anything".

>> but if not, you could detect inputs to your destination
>> window or similar.
>
> Sorry, not possible. The windows the messages are going to are
> varying, most often part of programs I did not write myself.

But you know where you're sending them to don't you?

JJ

unread,
Mar 10, 2015, 6:01:23 PM3/10/15
to
On Tue, 10 Mar 2015 16:55:30 +0100, R.Wieser wrote:
>
> The problem is to *detect when* to (temporarily) stop executing that
> command.

I've already mentioned a method that can be used to differentiate between
physical and injected inputs. Isn't that not enough?

R.Wieser

unread,
Mar 11, 2015, 4:11:49 AM3/11/15
to
Deanna,

> By ignore, I meant not counting them toward "real usage".

I wish it would be that simple. But alas, I have absolutily no data about
what SendInput does behind the/its screens (it might just send a single
WM_xxx message for each SendInput one, but it could easily be less
(collation) or maybe even more. Who knows ?). I would thoroughly dislike
the possibility that, on some version of the OS the whole thing starts to
stutter because the "not counting towards real usage" becomes a tad too
smal, and faked input starts to turn up as real.

I could do some empyrical tests to see if I can find something that
identifies a non "real usage" status. The only problem is that absolute
anything could throw a wrench into that kind of solution (I thought you
would understand that, being a stickler for following the MS rules ...)

> If it was synchronous, set a flag saying "I'm calling XX" and
> clear it when it returns.

Ah, thataway. Well, I did not see anything on the SendInput functions MSDN
page to be able to determine how it behaves (and if I can depend on it).

> But you know where you're sending them to don't you?

Nope, as I'm not sending them *to* anything at all. Its the currently
focussed app that will receive the result of what SendInput is generating.

Also, as mentioned earlier, the "focussed app" is more-often-than-not not
written by me, and have no control over what it does internally.

In short: My program calls SendInput to generate "faked" mouse/keyboard
activity. Its also my program that should detect "real" mouse/keyboard
activity -- it should not rely on interaction with unknown other programs to
do so.

Regards,
Rudy Wieser


-- Origional message
Deanna Earley <d...@earlsoft.co.uk> schreef in berichtnieuws
mdn7ea$ppg$5...@speranza.aioe.org...

R.Wieser

unread,
Mar 11, 2015, 4:26:59 AM3/11/15
to
JJ,

> I've already mentioned a method that can be used to
> differentiate between physical and injected inputs.
> Isn't that not enough?

My apologies, I read your "At user mode, you can only block keystrokes",
decided you didn't understand what I was asking, and skipped the paragraph
as irrelevant.

But yes, if everything else fails I suppose it has to do. I've found
references to the method when I googled the cr*p outof the problem, but
can't say I'm happy to 1) use a system-wide hook, 2) which can only be used
from within a DLL (which I would need to specially construct for this).

Isn't there really anything simpler ? No way to tell SendInput to mark its
resulting WM_xxx messages with a special "I'm generated" flag ? No method
to apply to the WM_xxx message to ask from which device it came ? No way
to actually detect physical device activity ? Absolutily nothing ?
Bummer. :-(

Regards,
Rudy Wieser

P.s.
Whats up with that Delphi example for sending keystrokes to a specific
window ? I've not seen you respond to that thread anymore. And yes, I'm
still stuck there.


-- Origional message:
JJ <jj4p...@vfemail.net> schreef in berichtnieuws
hxseqk2un7gw$.1lqtllr6pf3xp$.dlg@40tude.net...

Deanna Earley

unread,
Mar 11, 2015, 4:51:15 AM3/11/15
to
On 11/03/2015 08:12, R.Wieser wrote:
> Also, as mentioned earlier, the "focussed app" is more-often-than-not not
> written by me, and have no control over what it does internally.

So you're sending input to random, unknown applications?

Richard Heathfield

unread,
Mar 11, 2015, 5:29:56 AM3/11/15
to
On 11/03/15 08:50, Deanna Earley wrote:
> On 11/03/2015 08:12, R.Wieser wrote:
>> Also, as mentioned earlier, the "focussed app" is more-often-than-not not
>> written by me, and have no control over what it does internally.
>
> So you're sending input to random, unknown applications?

It sure sounds like it. It may be kinder to say that he is sending input
to applications decided upon by the user at run-time.

At least, I hope he is. The alternative doesn't bear thinking about.

I am reminded of a little hack that we cobbled together at MumbleCo
during Y2K - I wrote a client, and a colleague wrote a server, that
between them would allow a remote user to:

(a) send keystrokes;
(b) pop up a dialog box with a given title and message;
(c) execute a specified program

on the box that was running the server. We then installed the server on
Dave's computer (we hid it by launching it from the registry on bootup,
and gave it a sufficiently official-sounding name that he wouldn't
easily be able to spot it in Task Manager's process list), and waited
for him to work out why Word or Notepad or Excel would occasionally fire
up of its own accord, and why his source code would occasionally
spontaneously generate a few extra letters, eg turning x = y + z; into
xj =3 yq0 + ,z;.

It took him all morning, but eventually he worked it out, not so much
from a technical perspective as from all the suppressed giggling.

As with so many of these ideas, we eventually turned it into something
useful: we were asked to come up with a way of running the same program
simultaneously (+/- 5 seconds) on all the machines on a LAN, and it was
a perfect match for that requirement.

--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

R.Wieser

unread,
Mar 11, 2015, 7:58:40 AM3/11/15
to
Deanna,

> So you're sending input to random, unknown applications?

Nope, they're very known. To me that is (or rather the user, eyeballing
them), not to my program. To it the applications are fully unknown. Better
yet, it does not even need to know anything about them either.

... but ... what has that (sending to "random, unknown applications" or
not) to do with the problem as I stated it ? Would it change anything if
I would tell you the application the SendInput generated messages are going
to is "Windows explorer" ? or IE ? Or the desktop ? Or FF ? Or ...
any other application you can think of ? None of them are, internally,
under my control.

What info do you think you need that I've not yet divulged ?

Regards,
Rudy Wieser



-- Origional message:
Deanna Earley <d...@earlsoft.co.uk> schreef in berichtnieuws
mdovlv$8qf$1...@speranza.aioe.org...

R.Wieser

unread,
Mar 11, 2015, 8:17:35 AM3/11/15
to
Richard,

> It may be kinder to say that he is sending input
> to applications decided upon by the user at run-time.

Exactly.

> I am reminded of a little hack that we cobbled together
> at MumbleCo during Y2K

You caught me. :-)

That is, I'm sending mouse and keyboard activity to a media-center 'puter,
which screen is (ofcourse) visible to me at all times I want to use it.
And that is than the "background info" for why I need to detect the
computers physical mouse and keyboard activity: to, as I described, lock-out
the "remote" user in favour of a/the local one.

I don't think the above will help in any way to solve the problem as I
described it ...

Regards,
Rudy Wieser

P.s.
The "old scool" way of the same trick was to simply swap keyboards with the
computer on the opposite side of the table. Fun as long as everybody
in-the-know can keep down the laughter. :-)


-- Origional message:
Richard Heathfield <r...@cpax.org.uk> schreef in berichtnieuws
mdp1t3$ekd$1...@dont-email.me...

JJ

unread,
Mar 11, 2015, 1:41:54 PM3/11/15
to
On Wed, 11 Mar 2015 09:27:41 +0100, R.Wieser wrote:
>
> But yes, if everything else fails I suppose it has to do. I've found
> references to the method when I googled the cr*p outof the problem, but
> can't say I'm happy to 1) use a system-wide hook, 2) which can only be used
> from within a DLL (which I would need to specially construct for this).

Unfortunately, yes. It requires a system wide hook. But unlike the other
window hook types, low level mouse & keyboard hooks can be setup from the
EXE itself. They don't need to be put into separate DLL although it's a
global hook.

> Isn't there really anything simpler ? No way to tell SendInput to mark its
> resulting WM_xxx messages with a special "I'm generated" flag ? No method
> to apply to the WM_xxx message to ask from which device it came ? No way
> to actually detect physical device activity ? Absolutily nothing ?
> Bummer. :-(

The low level keyboard & mouse hooks are the only ones that expose the input
injection flag (in user mode). AFAIK, there's no other Microsoft helper DLLs
or API that utilize low level keyboard/mouse hooks. The other is using
kernel mode by utilizing upper device filters for keyboard and mouse class
devices. i.e. device drivers. Even if there's a helper DLL (without using
custom device driver), it will still need to use the low level hooks in
order to retrieve the injection flag.

Microsoft simply don't include the input injection flag in any of the window
messages - or at least officially. If you're in the mood to do some
research, you may want to inspect the reserved bits of the WM_KEYxxx message
lParam to see if any of them is used for the injection flag. Or perhaps the
message include extra information that Microsoft didn't mention.

JJ

unread,
Mar 11, 2015, 1:48:35 PM3/11/15
to
On Thu, 12 Mar 2015 00:41:56 +0700, JJ wrote:
>
> ... If you're in the mood to do some
> research, you may want to inspect the reserved bits of the WM_KEYxxx message
> lParam to see if any of them is used for the injection flag. Or perhaps the
> message include extra information that Microsoft didn't mention.

Or check all flag based fields of the raw inputs for any undocumented bits.

R.Wieser

unread,
Mar 12, 2015, 5:01:26 AM3/12/15
to
JJ,

> low level mouse & keyboard hooks can be setup from the
> EXE itself. They don't need to be put into separate DLL
> although it's a global hook.

I thought I read something different. So I revisited the MSDN page about
the function, and re-read. It turns out you're right. I've read too
quickly and skipped the "a thread created by a different process". :-| Hmm
... Still dislike the "system wide" aspect of it though.

> The low level keyboard & mouse hooks are the only ones
> that expose the input injection flag (in user mode).

I was thinking/hoping that one of the flags in the INPUT structure would be
free for such usage.

> If you're in the mood to do someresearch, you may want to
> inspect the reserved bits of the WM_KEYxxx message
>lParam to see if any of them is used for the injection flag

I did something similar: I did set some unused flags in the MOUSEINPUT
structure, and checked to see if maybe one of those bits in the
WM_MOUSEMOVE message would follow it. Alas, no such luck.

> Or perhaps the message include extra information that
> Microsoft didn't mention.

It does, though I only found a reference to it in the description of the
SendInput function: the dwExtraInfo field

In the related WM_xxx (including WM_INPUT) messages both my mouse & keyboard
only show Zero. A changed/set dwExtraInfo field when executing SendInput is
directly visible. Don't like the solution much either (no idea what other
mouses and keyboards might put in there), but there is only a 1 to 2^32
chance that my inserted value will match anything else ...

Regards,
Rudy Wieser

P.s.
Some messages back you mentioned this:

> Raw Input is for for native HID USB devices only (those
> that don't emulate PS/2 interface). It doesn't apply for PS/2
> or COM input devices.

I've got an older 'puter here which still has PS/2 for both mouse and
keyboard, which have no problem with approaching them as HID devices. I
suppose I misunderstood you ?


-- Origional message:
JJ <jj4p...@vfemail.net> schreef in berichtnieuws
1dnnvduw1hkyw$.v3xjtaevydsz$.dlg@40tude.net...

JJ

unread,
Mar 12, 2015, 1:30:52 PM3/12/15
to
On Thu, 12 Mar 2015 10:01:03 +0100, R.Wieser wrote:
>
> I thought I read something different. So I revisited the MSDN page about
> the function, and re-read. It turns out you're right. I've read too
> quickly and skipped the "a thread created by a different process". :-| Hmm
> ... Still dislike the "system wide" aspect of it though.

You didn't read it wrong. MSDN doesn't actually mention it.
It clearly says that if dwThreadId is zero (which means a global hook), lpfn
must point to a hook handler in a DLL.
That's what I first thought too, based only on the MSDN.
But later I found from elsewhere (non Microsoft site, of course) that it can
actually reside in the EXE itself, if the hook type is one of those low
level hooks.

> P.s.
> Some messages back you mentioned this:
>
>> Raw Input is for for native HID USB devices only (those
>> that don't emulate PS/2 interface). It doesn't apply for PS/2
>> or COM input devices.
>
> I've got an older 'puter here which still has PS/2 for both mouse and
> keyboard, which have no problem with approaching them as HID devices. I
> suppose I misunderstood you ?

No. I'm the one that misunderstood the Raw Input API. MSDN emphasizes too
much on HID since technically, COM / PS/2 input devices aren't part of HID
device class.

The fact that the API mixes all inputs in one interface tells me that it's a
central place to get access to all kinds of inputs (including injected
inputs). However, the "raw" thing is questionable since it apparently
doesn't expose keyboard/mouse input injection flag.
0 new messages