Introduction
Have you ever wanted a program to record and then simulate certain keyboard and mouse actions but didn't know how to? Well then I might have the solution for you.
This is revision of the Global Mouse and Keyboard Library by Brian Geiman.
This article focuses mostly on the Global Macro Recorder Example included in the MouseKeyboardLibrary
solution. The other included form called HookTestForm
is very simplistic and does exactly what it says on the tin.
However, when I was testing and trying out the Global Macro Recorder, I felt that there was just something missing. It's a perfect example, don't get me wrong, but if you want something to fool your friends; it won't do.
Thus the reason why I love Code Project's Open License, I took the form and revised it. Glory to the benefit of Open Source.
This is the result of the revision.
What This Did
Clean up Process
If you had read my Manage YouTube using C# and YouTube API 1.6, a lot of the same process here.
When creating a new form, Microsoft Visual Studio always puts in the most used references in a list and waits for you to use them (like System
, System.Drawing
, System.Windows.Forms
). Basically, extra items that are loaded and stand there being pretty hoping that you would use them. However, if you do not use them, they slow down the boot up and response time of your application.
I remove all the ones that are not needed into run the program.
Before:
After:
The difference in application boot up time is quite noticeable. Of course, you need to remove the using
references to see the performance boost application wide.
After I did that, I did some blank clean up on the code. A perfect example is when you are trying to do Form Designer code outside of the form.designer
you do not need to type all of:
mouseHook.MouseMove += new MouseEventHandler(mouseHook_MouseMove);
All you need to type is:
mouseHook.MouseMove += mouseHook_MouseMove;
The compiler will do the rest.
Now let's talk about something that most people hardly care about but is very important. Let's talk about thread-safety! Thread safety is my most favorite topic being that multi-threaded programs are becoming more and more apparent in today's society. This goes on to do with the fact of race conditions/hazards. If you are making a program to do a set process; you want to make sure that it does that process without having any issues with other threads running.
In C#, you have the ultimate power of assigning attributes to control the semantics of your property. When you are assigning properties, you have the chance to change its memory visibility semantics.
Giving an example when you have a field that will not change its value nor its meaning like:
private KeyboardHook keyboardHook = new KeyboardHook();
you can add a readonly
field:
private readonly KeyboardHook keyboardHook = new KeyboardHook();
to make it thread-safe. It changes how the value is compiled and declared. For readonly
read this for more information on how it works and why it is important.
Now let's go through redundancy checking.
When you are initializing a field, don't be worried if a value is not attached to it at the same time. Just make sure that when the field is used it will have a value. MacroForm was a very well written program with only a single field having a redundant default value.
It was the lastTimeRecorded
int
field. The reason why it was redundant was because on first use it was initialized with Environment.TickCount
. So it completely overwrote the default value to begin with. It makes no difference when you are doing an int
, but if you are doing an object
, depending on the object
and how complicated it is, it can make a couple seconds wasted.
What is New
Now that the little picky stuff is out of the way, let's find what we can now do!
First, let's look at the old form:
Now at the new form:
The new form spots these upgraded specs:
- Buttons are only enabled when they need to be.
Bool
values to see if the program is recording or if the hotkey warnings have been said.
- A
backworker
(called Playworker
) for the playback of the process (made so that we can stop the playback).
- Hide Window option when playing back.
- Stop when mouse has selected the form option.
- Integration of my favorite Global Hotkey Activation.
- If the Hotkey is activated, you can enable forever loop and loop the playback until the Global hotkey is pressed.
- Added progress bar to retrieve progresses reports
I know people are going to ask, but NO I did not include a serializer to save mouse or keyboard movements. Saving a mouse event is a pain in the butt (being that you need to break down the event and create different variables for each of the internal objects). Nevertheless, if you save the mouse movement and then take it to another computer system with a different screen resolution, you can get an out of bounds pointer exception. It a mess of error corrections that will need to be done to get it working right.
Now that I explained why I did not include a save button, let's move on.
The Global Hotkeys work from setting a System IntPtr struct
from the inputted key code and modifier under Windows.Forms.
Keys. When the hotkey is pressed, there is a protected override void
that's activated. From that void
, it runs another void
called HandleHotkey
to handle the hotkey event.
The Backworker and Progress Bar are quite simple; it does what was programmed in for playback with the addition of three things.
- Before the
Backworker
is even told to do work, the recorded events are counted and set to the progress bar maximum.
- An internal variable then counts the events that the
backworker
ran and outputs that to the progress bar.
- Before the next event is run, there is a check to see if the worker has a cancellation pending; if there is, it exits the
foreach
command.
The Hide Window and Stop on Select are simple options that are self-explanatory. To be noted there is a check to see if the Hide Window is checked before changing the value of the progress bar. This is to counter an exception you can get when you hide the form but change a designer item's status.
Conclusion
Whether you wanted this application to see how to record mouse and keyboard inputs or if you wanted to have fun with your friend; it does the same thing.
Feel free to download both of the sources and compare them. It's tons of fun to play around with.
Cheer fellow nerds!