I'm trying to write a small program to record my input on another program. I decided to use Allegro 5's event system so that I don't lose events. It works great since even if I have an al_rest(1.0), the program catches all events. The problem is that it only works if the program window has the focus. If I switch to another window, the program no longer catches keyboard events even though it keeps running in the background.
I know this is the normal behavior but is there a way to force an Allegro 5.0.4 program to keep generating keyboard events even if it's window doesn't have the focus?.
Thanks.
[EDIT:] Forgot to mention, I want to do this on Windows XP.
This is a very key logger way to do things.
A typical message is passed through the programs that have focus. I'd pass a message to the foremost program and wait for its response to that key press. If it returns TRUE that it had handled it, nothing else receives that message. If it returns false, it means that it didn't understand how to process it and is giving it back so someone else "higher up" can try to process it.
In many cases, the OS itself blocks this message from reaching your background-suspended program. The only exceptions to this occur when you have drivers that place hooks on the system events. These always get processed, and CAN block the message from going any further, although key loggers are typically smart enough to let the key press actually reach their destination or the user would quickly know something was wrong when they start entering their bank information and nothing is appearing in their browser window.
Can you describe why you'd want to keep receiving those messages? If I play your game, then switch to write an email, I wouldn't want my WASD keys to start moving a ship around while I can't see it (and where it shouldn't even be accepting inputs).
Can you describe why you'd want to keep receiving those messages?
I'm playing a game I downloaded and I want to record my input on that game so that I can replay it later (and probably fine tune it).
A while ago I tried to do the same thing with Allegro 4. On Allegro 4 the program keeps receiving keyboard input if you use set_display_switch_mode(SWITCH_BACKGROUND) but in order to not lose any key presses you must not rest() so the program takes 100% of the CPU and slows the actual game (maybe this wouldn't be an issue if I had a 2 cores CPU).
With Allegro 5's event system it seemed like catching the key presses would require practically no CPU usage but, unlike Allegro 4, it doesn't have an option like set_display_switch_mode().
I tried the Windows API function AttachThreadInput() but looks like it doesn't do what I expected it to. Right now I'm watching an example on how to set a keyboard hook.
If you're interesting just in the end result (you don't really care about learning how to do this), there are several programs, some free, that allow you to do this.
I want to be able to customize it for my needs while also learning how to do it.
After searching and trying some of the examples without luck, I decided to look at the code of MyHook, a really simple keylogger, and found that the keyboard hook code was OK but in order to actually get to the callback, I had to explicitly handle the Windows' messages (at least that's what MyHook does and it's the only method I got to work until now).
I made a few more changes to my code and I got it to work although not quite as I expected. Only key events performed when the Allegro 5 window is active are inserted into the Allegro event queue; key events performed when the Allegro 5 window is inactive are detected by the hook callback function but are not inserted into the Allegro event queue. CPU usage is low so I guess this might work.
I'll clean the mess in my code and post it here.
I think you might want to look into user events. You could have the hook callback function throw one of those.
Yes, that's what I did. This is the sample code I'm using for setting the keyboard hook. I marked the lines that do the actual work for the keyboard hook.
By using PeekMessage() the Allegro program keeps running normally so it's responsive to, for example, adding a GUI to start/stop recording input. GetMessage(), on the other hand, waits for a message. Both have it's pros and cons.
Some of the fields I'm filling in the user events are redundant; that's because I'm experimenting.
Now I want to save the input to a file. I'm planning to simply write the contents of the event variable as I go through the user event queue by saving sizeof(ALLEGRO_EVENT) bytes at a time. Then I should be able to read them back into an ALLEGRO_EVENT variable, right?.