While working for a software company, I found the need for and wrote a KeepAlive program for Windows. This is a very simple application which keeps windows from automatically logging you out when the computer has been setup to require you to log back into the computer after a certain amount of inactivity. This feature can be very annoying when you are using your computer in meetings, when reading, or doing other activities where you don't actually move the mouse or touch the keyboard every 5 minutes.
On the network I was on, the timeout period was set to 5 minutes, so this program is hardcoded to move the mouse a few pixels every five minutes. The amount of movement is so minimal that even when actively using the computer you will never notice the movement.
This program was written in Borland Delphi, but could easily be ported over to any language capable of making Windows API calls. All of the code for the program is in the project file, which I will walk through and explain. If you are interested in downloading the source code and a compiled version of the utility, it is available for free from our
website, or by clicking
here.
program KeepAlive;
The first line of the project file just declares the name of the program. This line is automaticly added by Delphi when creating a new project.
uses
Forms,
ExtCtrls,
Windows,
SysUtils,
Dialogs,
Messages
;
The above section is what is called the uses clause. This is where other units are included that contain functions and classes that we will be using throughout this unit. These are all standard Delphi units that we are including here.
{$R *.RES}
The above line is another one that is automatically added by Delphi. I am not entirely sure on its purpose, but it looks like it has to do with including any resource files. Since this program doesn't use any, I don't think this line has any effect on this program.
type
TUselessObject = class( TObject )
procedure OnTimer( Sender: TObject );
end;
Above is the type section. This is where we can define any classes, or other types. Here I have defined a class called TUselessObject. I named it this because the only reason we even need to create this class is because later in the program we need a callback function that has to be "of object". What this means is that it has to be a function that is part of an object. Normally, we might create this function as part of a form, but since this program does not have any forms, I needed to create a class just to hold this function. The name of the function is OnTimer and it takes a TObject named Sender as a parameter. When I get time I will write an article about callback functions, but in the mean time, try some of the recommended reading at the end of this article.
{ TUselessObject }
procedure TUselessObject.OnTimer(Sender: TObject);
Here we are starting the implementation of the OnTimer function that was defined as part of the TUselessObject class above.
var
Pt : TPoint;
The var section is optional but when present always comes before the begin for the actual code of the funciton. Here I have defined a variable of type TPoint.
begin
GetCursorPos( Pt );
The first thing we do when entering this function is call the Windows API function GetCursorPos. This function take a variable of type TPoint, so we pass it the variable we just defined above. The function will then fill Pt with the current coordinates of the cursor on the screen.
if Pt.x < Screen.Width then
Pt.x := Pt.x + 5
else
Pt.x := Pt.x - 5;
Here we have a simple if condition that is checking to see if the cursor is not already at the right edge of the sreen. If it isn't, it will move the cursor to the right. If it is, then it will move the cursor to the left.
Pt.x := Round(Pt.x * (65535 / Screen.Width));
Pt.y := Round(Pt.y * (65535 / Screen.Height));
The above two lines, as far as I understand it, are converting the values from pixels to what are called mickeys. My understanding is that mickeys are a system for mouse coordinates that are not affected by screen resolution. There are 65,535 by 65,535 mickeys on the screen whether the computer's resolution is set to 640x480 or 800x600.
So anyway, GetCursorPos returns pixels and Mouse_Event, which is the next function we are about to call, accepts mickeys.
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_MOVE,
Pt.x,
Pt.y,
0,
0);
Here we are calling a Windows API function called Mouse_Event. This is the function that sets the position of the mouse cursor. We are passing Pt.x and Pt.y, so it will set the cursor to the position that we modified above.
end;
The above end simply signifies the end of the code for the function OnTimer. Now, starting below, we will start the actual code that is automatically executed when the application starts. It is written much like a function with a var section and a begin/end that contains the code.
var
Timer : TTimer;
Msg : TMsg;
a : TUselessObject;
begin
In the var section we are defining three variables. First is an instance of a TTimer class, which is a standard Delphi class which we use to get our timing of 5 minutes. Next is a Msg variable, which is used to hold information about a Windows message. Last is an object named a of type TUselessObject. This is where we are instantiating an instance of the class we defined up in the type section.
Timer := TTimer.Create( nil );
a := TUselessObject.Create;
try
First we have to create instances of the TTimer and TUselessObject classes to be held in our variables.
Timer.Interval := 300000;
Timer.Enabled := True;
Timer.OnTimer := a.OnTimer;
These three lines are setting some properties of the TTimer object we created. The first one is the interval. This defines how often the timer should fire. We are passing 300,000 milliseconds, which equates to 5 minutes. Next we are setting the Timer to be enabled, so that it will fire when it is ready. Last, we are setting its OnTimer method pointer to the function we defined as part of TUselessobject. This is where an understanding of callbacks is needed. We are essentially giving Timer a pointer to our function OnTimer, so that it can call that function whenever its interval is up. So in other words, Timer will call OnTimer, every 5 minutes.
while GetMessage( Msg, 0, 0, 0 ) do
begin
TranslateMessage( Msg );
DispatchMessage( Msg );
end;
The above is a standard windows message loop. This is needed to keep the program running and handling any messages that Windows might send to it.
finally
FreeAndNil( Timer );
FreeAndNil( a );
end;
When the program ends, the last thing it will do is free our variables Timer ( of TTimer ) and a ( of TUselessObject ).
end.
As mentioned earlier, a downloadable version of this utility ( including source code ) is available from our website. You can get to it by clicking
here.
For more reading on some of the concepts covered in this article, watch this blog, and check out some of the following recommened books on Delphi and Object Oriented Programming.
 | Mastering Borland ® Delphi 2005 Marco Cantu Average Customer Review: | | |
 | Object-Oriented Programming
Peter Coad, Jill Nicola Average Customer Review: | | |
 | Delphi for .NET Developer's Guide Xavier Pacheco Average Customer Review: | | |