Post by Daniel Jam » Sun, 07 Sep 2008 07:54:06

I have an application that provides a simple keystroke record/playback
macro facility using WH_JOURNALRECORD and WH_JOURNALPLAYBACK hooks. The
app can save keystroke sequences to a file so that they can be reloaded
and played back at a later date. The record hook only handles keyboard
(keyup and keydown) messages, not mouse or any other messages, and only
from the same application.

I have some questions that go somewhat beyond what the SDK docs say ...

1. On playback, the hWnd in the EVENTMSG structure seems to be ignored
.. this is just as well as we may record a macro one day and play it
back another day in a different run of the app, where none of the
window handles from the original app will be valid. Is it safe to
assume that the hWnd is ignored or would I be better off setting it to
zero or -1 (or something)?

2. There's a potential problem if (say) CAPS LOCK is on when the macro
is recorded and off when it is played back. I'd like to capture the
CAPS (and other) LOCK state(s) when recording and force the same state
for playback ... what's the best way?

3. If a macro is played back on a PC with a different keyboard layout
from the one on which it was recorded the scan codes in the EVENTMSG
structure won't tally with the virtual key codes ... is this a problem?
It seems to me that when the macro is played back the application only
needs to look at the VK codes, and the scan codes may be ignored (I
haven't tested this yet). Ideally I'd like to be able to create
EVENTMSG structures with only the VK code (e.g. provide a macro editing
interface that dealt only in VK codes) ... is this possible, or does
the message loop that the keystrokes are played back into require the
scan codes?

4. Is there any more detailed documentation than is in the Platform SDK
documentation? It's really very sketchy.



Post by Alex Blekh » Sun, 07 Sep 2008 17:33:40

SHORT n = GetKeyState(VK_CAPITAL);
if(n & 1)
// CAPS LOCK is On
// CAPS LOCK is Off




Post by Daniel Jam » Sun, 07 Sep 2008 21:21:06


Not directly, no ... there is no corresponding SetKeyState ... but

I know I can obtain the keyboard state (as you've shown), but if my
macro is recorded with (say) CAPS LOCK on, and played back with CAPS
LOCK off what's the *best* way for my macro replay code to turn CAPS
LOCK back on at the start of the replay (and off again afterwards).

Should I do that by adding keypresses for the CAPS LOCK key at the
start and end of the macro (doable ... but can I just stuff in an
EVENTMSG with the VK code for CAPS LOCK or do I have to flesh it out
with the correct scan code for CAPS LOCK on the keyboard currently in
use (which I can presumably get from MapVirtualKey)?) ... or should I
mess around with Get/SetKeyboardState ... or what?

What works and what doesn't?

I'm just hoping that someone here has already tried these things and is
prepared to share their findings so I don't have to waste time myself
working out what the documentation Microsoft don't provide would say