22858 total geeks with 3297 solutions
Recent challengers:
best bread maker
 Welcome, you are an anonymous user! [register] [login] Get a yourname@osix.net email address 

Articles

GEEK

User's box
Username:
Password:

Forgot password?
New account

Shoutbox
sefo
anilg, new comments are deleted automaticall y because of some abuse recently
anilg
this is plain wierd. I submitted comments twice to article 950, and they dont seem to be there. Something wrong with the comment code?
CodeX
shout-boxes in general are old + the staff thing happened to everyone after an issue 2 months ago
anilg
/me is no longer staff :(
anilg
Also, osix's shoutbox predated twitter. Heh.

Donate
Donate and help us fund new challenges
Donate!
Due Date: Jul 31
July Goal: $40.00
Gross: $0.00
Net Balance: $0.00
Left to go: $40.00
Contributors


News Feeds
The Register
UK.gov sticks to IE
6 cos it"s more
"cost effective",
innit
T-Mobile UK pumps
out the iPhone 4
Polaroid 300
instant print
camera
NatWest dumps O2
Money
YouTube ups video
time limit
Alleged expenses
fiddlers to face
justice
Nude trampolinist
bounces free from
court
Nexus One phone
rockets to 28,000ft
UK.gov drops £6m on
Google
Fake Firefox update
used to sling
scareware
Slashdot
British ISPs Favour
Well-Connected
Customers
"Bizarre"
Nanobubbles Found
In Strained
Graphene
1-in-1,000 Chance
of Asteroid Impact
In
...
2182?
2 Chinese ISPs
Serve 20% of World
Broadband Users
World"s Fastest
Hybrid OK"d For
Production
Sometimes It"s OK
To Steal My Games
Thermoelectrics
Could Let You Feel
the Heat In Games
KDE SC 4.7 May Use
OpenGL 3 For
Compositing
Perl 6, Early, With
Rakudo Star
Internal Costs Per
Gigabyte —
What Do You Pay?
Article viewer

Developing a Windows Screen saver



Written by:Obscurity
Published by:Nightscript
Published on:2004-07-01 05:41:16
Topic:C
Search OSI about C.More articles by Obscurity.
 viewed 18569 times send this article printer friendly

Digg this!
    Rate this article :
In this article you'll see how to code a Windows screen saver through the predefined screen saver library. You'll also see some basic GDI code.

In Windows there is a predefined library and header file especially for developing screen savers. This allows less coding time (and less of a mess) when developing screen savers.

So we will start off with looking at some skeleton code to start developing a screen saver. This skeleton code can qualify as a screen saver, it has everything you need; it will produce a black screen saver. Not very lively, if you ask me.

#include <windows.h>
#include <scrnsave.h>

#pragma comment(lib, "scrnsave.lib")
/*
If using Dev-C++ in the pragma comment change 'scrnsave.lib'
to 'libscrnsave.a' without the quotes.
*/

LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
       case WM_CREATE:
         break;
       case WM_DESTROY:
         PostQuitMessage(0);
         break;
       case WM_PAINT:
         break;
       default:
         return DefScreenSaverProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
    return TRUE;
}


As you can see, the code is not very big, or excessively advanced with Win32 API. As you can see you need to link the scrnsave library and add the scrnsave header file. There is a true beauty about the scrnsave library, it already has the WinMain function there so you don't need to code that into your screen saver, it registers basically a black background and that's it. That is what our skeleton code does, it's a fully functioning screen saver, but it doesn't have any the razzle dazzle you would usually see.

Let's take a look at ScreenSaverProc, in a lamen term it's the equivalent of WndProc in standard Windows applications.

LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
       case WM_CREATE:
         break;
       case WM_DESTROY:
         PostQuitMessage(0);
         break;
       case WM_PAINT:
         break;
       default:
         return DefScreenSaverProc(hwnd, message, wParam, lParam);
    }
    return 0;
}


As I said previously ScreenSaverProc is just another Windows procedure, but instead of using the return function DefWindowProc, we use DefScreenSaverProc. I've heard that some people use DefWindowProc as a return for ScreenSaverProc, but I've had runtime errors with it.

You can see there are 3 messages there (WM_CREATE, WM_DESTROY & WM_PAINT), those are specifically for the next example; usually you will see WM_CREATE, WM_DESTROY, WM_TIMER, and WM_ERASEBKGND used when developing screen savers.

I would imagine you are asking yourself what is with the other two procedures, those are formalities when developing a screen saver. They are both used when developing a dialog for screen saver adjustment. We're not going to go into that here, so the return values will suffice.

Well, here's the semi-reasonable example of a screen saver, it has some GDI basics, but that is a whole different article. I've put some comments in there so you can get the jist of what is going on.

#include <windows.h>
#include <scrnsave.h>

#pragma comment(lib, "scrnsave.lib")

HBITMAP p_bmp = NULL;

LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_CREATE:
         /* Uploading a bitmap from our hard disk */
         p_bmp = LoadImage(NULL, "C:untitled.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
         if(p_bmp == NULL){
           MessageBox(hwnd, "Fatal Error: 101", "Error", MB_OK | MB_ICONEXCLAMATION);
         break;
       case WM_DESTROY:
         DeleteObject(p_bmp); /* Deleting the bitmap when Screen saver is done */
         PostQuitMessage(0);
         break;
       case WM_PAINT:
       {
         BITMAP bm; /* Bitmap structure as seen in bmWidth & bmHeight */
         PAINTSTRUCT ps;

         HDC hdc = BeginPaint(hwnd, &ps);
         HDC hdcMem = CreateCompatibleDC(hdc);
         HBITMAP hbmOld = SelectObject(hdcMem, p_bmp);

         GetObject(p_bmp, sizeof(bm), &bm);

         bm.bmWidth = 1000;
         bm.bmHeight = 700;

         BitBlt(hdc, 5, 5, bm.bmWidth, bm.bmHeight, hdcMem, 5, 5, SRCCOPY);

         SelectObject(hdcMem, hbmOld);
         /* Deleting memory so we don't have any resource leaks */
         DeleteDC(hdcMem);

         EndPaint(hwnd, &ps);
       }
         break;
       default:
         return DefScreenSaverProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
    return TRUE;
}



NOTE: I haven't double checked all the GDI stuff, but it does compile and display a bmp.

One last thing, after you compile a screen saver, it saves automatically as an executable. You need to change the file extension to scr. eg: screensaver.scr.

As well, you need to put the screen saver in C:WinntSystem32 if you're on NT/2k. And if you're on Win9x/ME put it into C:WindowsSystem.

Can you count how many times I've said screen saver in this article?


Did you like this article? There are hundreds more.

Comments:
bb
2004-07-01 08:53:46
nice article! why dont you use it to create an osix screensaver, and i'll slap it up on the site!
Domuk
2004-07-01 14:25:41
Also, a helpful reference is the MSDN reference for screensavers
mask
2004-09-26 04:18:56
I couldnt get it to compile with dev-c++.
This is despite linking with 'libscrnsave.a' without the quotes.
Any ideas?
errors:
[Linker error] undefined reference to `DefScreenSaverProc@16'
[Linker error] undefined reference to `WinMain@16'
wizzar
2005-05-26 14:30:39
@mask:
in the menu project click on 'project options', then parameters. click 'add library or object', go to your dev-c++ directory, then into the sub directory 'lib' and add 'libscrnsave.a'. now it *should* be working.
sefo
2005-05-27 12:33:15
> "Can you count how many times I've said screen saver in this article?"

18 times
xpi0t0s
2005-06-02 08:55:53
I counted 15 "screen saver", 13 ".*screensaver.*" and 3 "screen savers".
Anonymous
2005-12-10 00:18:01
here's what I got from dev-c++ 4
when I tried to compile as win32 c++
(not that anybody cares, but here it is)
------------------------------------------------------------------------
  • 14 c:/my documents/untitled1.cpp
    ANSI C++ forbids implicit conversion from `void *' in assignment

  • 29 c:/my documents/untitled1.cpp
    ANSI C++ forbids implicit conversion from `void *' in initialization

  • 52 c:/my documents/untitled1.cpp
    parse error before `{'


------------------------------------------------------------------------

I'm just learning c & c++, so basically I have to f***ing idea what's going on there.

also I did link the libscrnsave.a
project options->parameters->add library or object






-=<VISUALIZE WHURLED PEE'S>=-
Anonymous
2006-06-28 14:09:08
Where can I download the screen saver library ?

Anonymous
2006-10-28 15:33:52
"scrnsave.lib" should come with your compiler.
An implementation is present in
MinGW/OpenWatcom.

Anonymous
2008-11-24 10:18:42
I'm only just starting to learn C++
and microsoft visual C++ 2008 express edition gives me these errors when I run the first example.
1>scrnsave.lib(scrnsave.obj) : error LNK2019: unresolved external symbol _ScreenSaverProc@16 referenced in function _RealScreenSaverProc@16

1>scrnsave.lib(scrnsave.obj) : error LNK2019: unresolved external symbol __imp__InitCommonControlsEx@4 referenced in function _WinMainN@16

1>C:\Documents and Settings\Nick Laver\My Documents\Visual Studio 2008\Projects\Screensaver\Debug\Screensaver.exe : fatal error LNK1120: 2 unresolved externals

I'm sick of my compiler doing this EVERY time I use code I get off the internet
Anonymous
2008-12-03 01:55:59
If you get link error LNK2019 it should mean that you forgot to include the library (.lib file) with the code or data that is referenced. I am using the same version of Visual Studio, and fixed the problem with the call to InitCommonControlsEx by including the header "commctrl.h" between angle brackets and including comctl32.lib in the command line for the linker. If Visual Studio feels like cooperating, the menu bar will have a "Properties" menu, and this should have a menu item called "<project name> Properties...". There, you go into "Configuration Properties", "Linker", and "Command Line", which gives you an edit window in which you can add names for more static link libraries. I solved the InitCommonControlsEx problem that way, and only have Visual Studio complaining that ScreenSaverProc and ScreenSaverConfigureDialog are not defined even though they are, everything is spelled correctly, and none of the other supposed causes of that error apply either. (Mind you Microsoft got a reputation for producing moody no-can-do technology for a reason.)
Anonymous
2009-04-22 14:20:49
If Visual Studio feels like cooperating, the menu bar will have a "Properties" menu, and this should have a menu item called "<project name> Properties...". There, you go into "Configuration Properties", "Linker", and "Command Line", which gives you an edit window in which you can add names for more static link libraries. online games
Anonymous
2010-01-19 07:33:00
http://www.bagscabin.com/mulberry bags
Anonymous
2010-02-27 16:40:12
All the world's latest and most authoritative website with all kinds of uniforms. We are recognized worldwide network of sales jersey website. Here you can choose a variety of uniforms such as MLB jerseys, NFL jerseys, NHL jerseys and NBA jerseys. Professional security identification products with credit guarantee, first-class quality and reasonable prices!
--Lin Guowang
Anonymously add a comment: (or register here)
(registration is really fast and we send you no spam)
BB Code is enabled.
Captcha Number:


Blogs: (People who have posted blogs on this subject..)
amisauv
Creating a Lexical Analyzer in C on Tue 9th Dec 11am
#include<stdio.h> #include<string.h> #include<conio.h> #include<ctype.h> /*************************************** ************************* Functions prototype. **************************************** *************************/ void Open_File(
amisauv
Controling digital circuit through computer on Tue 9th Dec 10am
this code access the lpt port.here only 4 of the total 8 pins are used but can be modified for full 8 pins.it has a complete GUI with mouse & keyboard interactive control panel.works well in win98, but not in winxp. #include<stdio.h> #include<conio.
amisauv
/* Computerised Electrical Equipment Control */ /* PC BASED DEVICE CONTROLLER * on Tue 9th Dec 10am
#include<stdio.h> #include<conio.h> #include<dos.h> void main() { void tone(void); int p=0x0378; char ex={"Created By Mrc"}; int j; char ex1={"For Further Details & Improvements"}; int k; char ex2={"Contact : E-mail : anbudan
amisauv
Calendar Program on Tue 9th Dec 10am
This program prints Weekdays of specified date. It even prints calendar of a given year too. /*Ccalendar library*/ #include<stdio.h> #include<string.h> #include<conio.h> int getNumberOfDays(int month,int year) { switch(month) { case
amisauv
Calculator: on Tue 9th Dec 10am
#include"graphics.h" #include"dos.h" #include"stdio.h" #include"math.h" union REGS i,o; char text={ "7","8","9","*","4","5","6","/","1","2", "3","+","0","00",".","-","M","M+", "M-","+/-","MR","MC","x^2","sr","OFF","A C","CE","="}; int s=0,k=0,pass
amisauv
INFECTED CODES WRITTEN IN C\C++ on Tue 9th Dec 10am
This is a simple code that changes system time and date. It is written using c/c++ but can be easily converted to java. #include "stdio.h" #include "process.h" #include "dos.h" int main(void) { struct date new_date; struct date old_date; s
amisauv
A C programme which can print the file name it is kept in on Tue 9th Dec 9am
#include<stdio.h> main(){ printf(”the source file name is %s\n”,__FILE__); } actually __FILE__ is a macro which stands for the file name the programme is kept in and the compiler does the rest .. for you ..
amisauv
BOOTSECTOR EDITOR: on Tue 9th Dec 9am
Code : /*program to save the partion table of your hard disk for future use. it will save your partition table in a file partition.dat */ #include<stdio.h> #include<bios.h> #include<conio.h> #include<stdlib.h> #include<ctype.h> void main () {
amisauv
BLINKING STAR : on Tue 9th Dec 9am
#include<conio.h> #include<graphics.h> #include<stdlib.h> #include<dos.h> void main() { int gdriver=DETECT,gmode; int i,x,y; initgraph(&gdriver,&gmode,"e: cgi"); while(!kbhit()) { x=random(640); y=random(480); setcolor
amisauv
// To print semicolons using C programming without using semicolons any where i on Tue 9th Dec 9am
// To print semicolons using C programming without using semicolons any where in the C code in program. // #include<stdio.h> #include<conio.h> void main() { char a; a=59; if(printf("%c",a)){} getch();

Test Yourself: (why not try testing your skill on this subject? Clicking the link will start the test.)
BSD sockets API by skrye

This is a test of your knowledge of the BSD socket interface
C Programming by keoki

This test is aimed at a C programmer that is at an intermediate level.


     
Your Ad Here
 
Copyright Open Source Institute, 2006