2010. február 15., hétfő

Write a Screensaver


Problem/Question/Abstract:

How to Write a Screensaver in Delphi

Answer:

In order to write a screensaver we need to include several procedures:

FormShow - hide cursor, setup message processing, start screensaver display
FormHide - stop screensaver display, show cursor
DeactivateScrSaver - process messages, deactivate if keys / mouse pressed

Typical code for these procedures is shown below.

You should ensure that your form is designed with the style fsStayOnTop. You also need to make sure only one instance of your program is running in the usual way. Finally you need to include the compiler directive {$D SCRNSAVE programname Screen Saver} in your project unit (*.dpr).

Once your program is compiled then change it's filename extension to SCR and copy it to your \WINDOWS\SYSTEM folder.

If running on Windows 98 you must disable the screensaver calls when it is running. I have not needed to do this for versions of windows prior to 98 but it should work on all versions. To do this insert the following call into your FormCreate method:

SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, nil, 0);

You must reverse this in your FormClose method:

SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, nil, 0);

var
  crs: TPoint; {original location of mouse cursor}

procedure TScrForm.FormShow(Sender: TObject);
{starts the screensaver}
begin
  WindowState := wsMaximized; {ensure program fills screen}
  GetCursorPos(crs); {get current cursor position}
  Application.OnMessage := DeactivateScrSaver; {check for Mouse/Keys}
  ShowCursor(false); {hide the cursor}
  {start screensaver display...}
  //
end; {procedure TScrForm.FormShow}

procedure TScrForm.FormHide(Sender: TObject);
{returns control to the user}
begin
  Application.OnMessage := nil; {discard the message}
  {stop the screensaver...}
  //
  ShowCursor(true); {bring the cursor back}
end; {procedure TScrForm.FormHide}

procedure TScrForm.DeactivateScrSaver(var Msg: TMsg; var Handled: boolean);
{detects Mouse movement or Keyboard use}
var
  done: boolean;
begin
  if Msg.message = WM_MOUSEMOVE then {mouse movement}
    done := (Abs(LOWORD(Msg.lParam) - crs.x) > 5) or
      (Abs(HIWORD(Msg.lParam) - crs.y) > 5)
  else {key / mouse button pressed?}
    done := (Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP) or
      (Msg.message = WM_SYSKEYDOWN) or (Msg.message = WM_SYSKEYUP) or
      (Msg.message = WM_ACTIVATE) or (Msg.message = WM_NCACTIVATE) or
      (Msg.message = WM_ACTIVATEAPP) or (Msg.message = WM_LBUTTONDOWN) or
      (Msg.message = WM_RBUTTONDOWN) or (Msg.message = WM_MBUTTONDOWN);
  if done then
    Close;
end; {procedure TScrForm.DeactivateScrSaver}

Nincsenek megjegyzések:

Megjegyzés küldése