Wygaszacze ekranu.
1) Co to jest wygaszacz ekranu?
Wygaszacz ekranu jest specjalnym programem, kt≤ry
uruchamiany jest przez system po stwierdzeniu d│u┐szego czasu
bezczynno╢ci u┐ytkownika. Jego podstawowym zadaniem jest
zabezpieczanie monitora, a w│a╢ciwie jego warstwy luminoforu, przed
zniszczeniem poprzez d│ugotrwale wy╢wietlanie tego samego obrazu.
Dodatkowo mo┐e on pe│niµ funkcje prostego zabezpieczenia przed
wykorzystaniem komputera przez osoby niepowo│ane.
Z punktu widzenia systemu Windows wygaszacz jest
programem, mo┐na siΩ o tym przekonaµ zmieniaj▒c rozszerzenie
dowolnego programu na scr i odwrotnie. Nie jest to jednak zwyk│y
program. Aby pracowa│ on poprawnie jako wygaszacz ekranu musi spe│niaµ
kilka warunk≤w.
2) Jak utworzyµ wygaszacz ekranu.
Najprostsz▒ metod▒ stworzenia w│asnego
wygaszacza ekranu jest wykorzystanie znajduj▒cej siΩ w systemie
Windows biblioteki scrnsave.dll. Biblioteka ta zawiera w sobie kilka
funkcji u│atwiaj▒cych tworzenie wygaszaczy ekranu. Przede wszystkim
jest to funkcja main wraz z kodem inicjalizuj▒cym u┐ycie wygaszacza.
Dba ona o wywo│ywanie w odpowiednim momencie okna dialogowego, do
ustawiania parametr≤w wygaszacza, lub wywo│anie samego wy╢wietlacza.
Dodatkowo sama zamyka wygaszacz po reakcji u┐ytkownika, a przy jego
wywo│ywaniu czy╢ci t│o.
Aplikacja powinna zawieraµ zdefiniowane trzy
funkcje: ScreenSaverConfigureDialog i ScreenSaverProc
RegisterDialogClasses. Dodatkowo w zasobach powinno byµ zdefiniowane
okno o dialogowe o identyfikatorze 2003. To okno konfiguracyjne jest wy╢wietlane
wtedy, gdy u┐ytkownik wybierze przycisk Ustawienia z zak│adki Wygaszacz
ekranu okna W│a╢ciwo╢ci ekranu.
Aby utworzyµ taki wygaszacz potrzeby jest dowolny
kompilator jΩzyka C, umo┐liwiaj▒cy tworzenie aplikacji dla Windows.
Przyk│adem mog▒ byµ darmowe GCC-MINGWIN i
LCC-WIN32.
(http://www.cs.virginia.edu/~lcc-win32/index.html)
A wiec zaczynamy od tego ze tworzymy nowy projekt,
ustawiamy jego typ na aplikacje Windows (zazwyczaj nazywa siΩ to
Windows App), i pouczamy linkiera aby z naszym projektem linkowa│
biblioteki: scrnsave.lib i comctl32.lib. Oczywi╢cie dodajemy ,o ile
jest to konieczne a zazwyczaj jest, zasoby w kt≤rych zdefiniowane jest
okno dialogowe o nazwie 2003
3) Budowa wygaszacza.
Kod bardzo prostego wygaszacza znajduje siΩ poni┐ej.
// WygaszaczMig
#include <windows.h>
#include <commctrl.h>
#include <scrnsave.h>
#define IlePunktowMax 500
#define NazwaKlucza "SOFTWARE\\ProgramyAdama\\WygaszaczMiganie"
long IlePunkt; // Liczba punkt≤w wy╢wietlanych na raz
long predkosc, iSzerokosc, iWysokosc;
UINT uTimer;
void Odczytaj();
void Zapisz();
void RysujWygaszacz(HDC kont);
// Procedura dialogu konfiguracyjnego
BOOL WINAPI ScreenSaverConfigureDialog(HWND dialog,
UINT komunikat, WPARAM wParam, LPARAM lParam)
{
switch(komunikat)
{
case WM_INITDIALOG:
// Odczytaj ustawienia z rejestru
Odczytaj();
// Ustaw zakres paska przesuwnego na 0-20
SendDlgItemMessage(dialog, 110, TBM_SETRANGE, TRUE, MAKELONG(1,20));
// Ustaw pozycjΩ suwaka zale┐nie od prΩdko╢ci
SendDlgItemMessage(dialog, 110, TBM_SETPOS, (WPARAM)TRUE, predkosc);
// Ustaw zakres paska przesuwnego na 5-500
SendDlgItemMessage(dialog, 111, TBM_SETRANGE, TRUE, MAKELONG(5,500));
// Ustaw pozycjΩ suwaka zale┐nie od prΩdko╢ci
SendDlgItemMessage(dialog, 111, TBM_SETPOS, (WPARAM)TRUE, IlePunkt);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
predkosc = SendDlgItemMessage(dialog, 110, TBM_GETPOS, 0, 0);
IlePunkt = SendDlgItemMessage(dialog, 111, TBM_GETPOS, 0, 0);
// Zapisz ustawienia do rejestru
Zapisz();
EndDialog(dialog, TRUE);
case IDCANCEL:
EndDialog(dialog, FALSE);
return TRUE;
case 112:
MessageBox(dialog,"Ten program jest prostym wygaszaczem ekranu. \n Mo┐e byµ
w dowolny spos≤b kopiowany i rozpowszechniany. \n Autor: Adam Kowalczyk.
akowalc1@elka.pw.edu.pl", "O Wygaszaczu...", 0);
return FALSE;
}
}
return FALSE;
}
BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
InitCommonControls();
return TRUE;
}
LONG WINAPI ScreenSaverProc(HWND okno, UINT komunikat, WPARAM wParam, LPARAM lParam)
{
HDC kont;
switch(komunikat)
{
case WM_CREATE:
Odczytaj();
/* W│▒cz zegar generuj▒cy komunikaty WM_TIMER co okres czasu = prΩdko╢µ*1/20 [sek] */
iSzerokosc=GetSystemMetrics(SM_CXSCREEN);
iWysokosc=GetSystemMetrics(SM_CYSCREEN);
uTimer = SetTimer(okno, 1, predkosc*50, NULL);
break;
case WM_TIMER:
kont = GetDC(okno);
RysujWygaszacz(kont);
ReleaseDC(okno,kont);
break;
case WM_DESTROY:
if (uTimer) KillTimer(okno, uTimer);
break;
}
return DefScreenSaverProc(okno, komunikat, wParam, lParam);
}
// Funkcja odczytuje ustawienia wygaszacza z rejestru
void Odczytaj()
{
HKEY klucz;
DWORD rozm = 4;
// Otw≤rz odpowiedni klucz rejestru
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, NazwaKlucza, 0,
KEY_QUERY_VALUE, &klucz) == ERROR_SUCCESS)
{
// Odczytaj prΩdko╢µ
RegQueryValueEx(klucz, "PrΩdko╢µ", 0, NULL, (BYTE *)&predkosc, &rozm);
if(predkosc<0 || predkosc>20) predkosc = 2;
// Odczytaj liczbe punktow
RegQueryValueEx(klucz, "LiczbaPunktow", 0, NULL, (LONG *)&IlePunkt, &rozm);
if (IlePunkt<5) IlePunkt=5;
if (IlePunkt>IlePunktowMax) IlePunkt=IlePunktowMax;
// Zamknij otwarty klucz rejestru
RegCloseKey(klucz);
} else
{
// ustawienia domy╢lne, wa┐ne przy pierwszym uruchomieniu programu
IlePunkt=20;
predkosc = 5;
}
}
// Funkcja zapisuje parametry wygaszacza do rejestru
void Zapisz()
{
HKEY klucz;
DWORD akcja;
// Otw≤rz odpowiedni klucz rejestru
RegCreateKeyEx(HKEY_LOCAL_MACHINE, NazwaKlucza , 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &klucz, &akcja);
// Zapisz informacje o prΩdko╢ci
RegSetValueEx(klucz, "PrΩdko╢µ", 0, REG_DWORD, (CONST BYTE *)&predkosc, 4);
// Zapisz informacje o liczbe punktow
RegSetValueEx(klucz, "LiczbaPunktow", 0, REG_DWORD, (CONST BYTE *)&IlePunkt, 4);
// Zamknij otwarty klucz rejestru
RegCloseKey(klucz);
}
// Funkcja rysuje zawarto╢µ ekranu
void RysujWygaszacz(HDC kont)
{
long i;
long x,y;
COLORREF k;
// wstawianie losowe punkt≤w
for(i=0; i<IlePunkt; i++)
{
// losujemy wsp≤│rzΩdne punktu gdzie╢ na ekranu
x=rand() % iSzerokosc;
y=rand() % iWysokosc;
// losuje kolor
k=RGB(rand()%256, rand()%256, rand()%256 );
// wstawiam gwiazdki w danym po│o┐eniu
//*
// ***
// *
SetPixelV(kont,x,y,k);
SetPixelV(kont,x+1,y,k); SetPixelV(kont,x,y+1,k);
SetPixelV(kont,x-1,y,k); SetPixelV(kont,x,y-1,k);
}
}
Plik z zasobami do niego:
#include <windows.h>
ID_APP ICON Wygaszacz.ico
2003 DIALOG 168, 47, 241, 174
EXSTYLE WS_EX_DLGMODALFRAME
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE
| WS_CAPTION | WS_SYSMENU
CAPTION "Ustawienia wygaszacza."
FONT 8, "MS Sans Serif"
{
CONTROL "OK", IDOK, "BUTTON",
BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 16, 144, 50, 14
CONTROL "Cancel", IDCANCEL,
"BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
160, 144, 50, 14
CONTROL "PrΩdko╢µ zmian", 100,
"BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
15, 58, 210, 46
CONTROL "", 110,
"msctls_trackbar32", 0x0 | WS_TABSTOP, 25, 80, 188, 20
CONTROL "Szybko", 101, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 20, 70, 30, 10
CONTROL "Wolno", 102, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 191, 70, 20, 10
CONTROL "Liczba punkt≤w.", 104,
"BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
15, 7, 211, 46
CONTROL "", 111,
"msctls_trackbar32", 0x0 | WS_TABSTOP, 25, 25, 189, 20
CONTROL "5", 2006, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 20, 15, 30, 10
CONTROL "500", 2007, "STATIC",
SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 195, 15, 20, 10
CONTROL "Autor", 112, "button",
BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 88, 144,
50, 14, 0
}
Wygaszacz ten w wersji skompilowanej wraz ze ╝r≤d│ami
jest zawarty w spakowanym pliku WygMig.zip.
Dzia│anie przedstawionego powy┐ej wygaszacza
polega na losowym wy╢wietlaniu na ekranie punkt≤w. Szybko╢µ z jaka
siΩ one pojawiaj▒ i ich liczbΩ mo┐na regulowaµ w okienku z
ustawieniami.
Jego rdze± stanowi▒ wspomniane wcze╢niej
funkcje ScreenSaverConfigureDialog, ScreenSaverProc i RegisterDialogClasses.
Nazwy tych funkcji i ich nag│≤wki s▒ niezbΩdne i musza wygl▒daµ
dok│adnie tak jak to zosta│o pokazane w przyk│adzie. Inaczej nie
zostan▒ one zlokalizowane.
Funkcja ScreenSaverConfigureDialog jest
odpowiedzialna za obs│ugΩ okna dialogowego s│u┐▒cego do
konfiguracji wygaszacza. Natomiast funkcja ScreenSaverProc jest w│a╢ciw▒
funkcj▒ obs│uguj▒ca sam wygaszacz podczas pracy. Jej podstawowym
zadanie jest obs│ug▒ komunikat≤w przychodz▒cych od systemu. Najwa┐niejsze
z nich to: WM_CREATE, WM_TIMER, WM_DESTROY.
Komunikat WM_CREATE jest pierwszym komunikatem jaki otrzymuje
program po uruchomieniu.
Jego obs│uga powinna zawieraµ:
- wczytanie danych konfiguracyjnych z rejestru,
(funkcja Odczyt),
- inicjacje zmiennych i struktur danych programu,
- inicjacje timera.
Komunikat WM_TIMER przychodzi regularnie do
aplikacji po uruchomieniu timera. W jego obs│udze powinna byµ zawarta
cala obs│uga animacji zwi▒zanych z wygaszaczem, a wiΩc przede
wszystkim rysowanie zawarto╢ci ekranu. Zadanie to wykonuje funkcja
RysujWygaszacz.
Komunikat WM_DESTROY jest sygna│em do zako±czenia
pracy programu. W trakcie jego wykonywania program usuwa zainicjowany
wcze╢niej timer.
Komunikat WM_ERASEBKGND jest wywo│ywany
gdy system zamierza wyczy╢ciµ t│o przy uruchamianiu wygaszacza. Jest
on wywo│ywany przed wyczyszczeniem t│a, w czasie jego obs│ugi
systemowa funkcja obs│ugi zdarze± czy╢ci zawarto╢µ okna. Dlatego
jego przechwytywanie umo┐liwia operowanie na oryginalnej zawarto╢ci
ekranu.
Zapis ustawie± wygaszacza mo┐e byµ
przeprowadzany bezpo╢rednio w rejestrze systemowym. W tym celu program
musi stworzyµ w│asny klucz. Mo┐na umie╢ciµ go w ga│Ωzi: HKEY_LOCAL_MACHINE//SOFTWARE//NazwaFirmy//NazwaProgramu//..
lub :HKEY_CURRENT_USER//software//NazwaFirmy//NazwaProgramu//.
Pierwsza ga│▒╝ s│u┐y do zapisu informacji
konfiguracyjnych specyficznych dla ca│ego systemu, natomiast druga jest
przeznaczona na informacje zwi▒zane z konkretnym u┐ytkownikiem.
Np. ..//JacekiWacek//WygaszaczLatajaceSledzie
Przy pierwszym uruchomieniu wygaszacz powinien
potrafiµ siΩ zorientowaµ ┐e jest uruchamiany pierwszy raz i stworzyµ
odpowiedni klucz.
Trzeci▒ funkcja jaka nale┐y zdefiniowaµ tworz▒c
w│asny wygaszacz jest: RegisterDialogClasses. Jej zadaniem jest
rejestracja przez program w│asnych obiekt≤w steruj▒cych lub klas
dodatkowych okien.
4) Jaki mo┐e byµ wygaszacz i co on bΩdzie robi│?
To ju┐ zale┐y tylko i wy│▒cznie od
wyobrazili jego tw≤rcy czyli twojej. Ja ze swej strony mogΩ ci tylko
troszkΩ podpowiedzieµ
Wygaszacze
ekraru podzieli│ bym na kategorie:
- punktowo - obiektowe,
- bitmapowe,
- obrazowe.
Wygaszacz punktowo-obiektowy to taki w kt≤rym
obraz na ekranie powstaje z szeregu punkt≤w (lub innych prostych obiekt≤w).
Program sam je generuje na podstawie odpowiedniego algorytmu i sam je w
odpowiednim momencie usuwa. W ten spos≤b mo┐na zrealizowaµ mn≤stwo
pomys│≤w kt≤re opieraj▒ siΩ na uk│adach prostych element≤w
(punkty, linie, ko│a). Tego typu jest zaprezentowany powy┐ej
wygaszacz.
Wygaszacz bitmapowy jest podobny do wspomnianego
wy┐ej z tym ze nie generuje sam ca│ego obrazu ale korzysta z gotowego
zestawy bitmap zapisanych w programie. Mo┐e on pokazywaµ przesuwaj▒cy
siΩ obiekt po ekranie, lub ten sam obiekt w ro┐nych widokach ( ka┐dy
z widok≤w to oddzielna bitmapa).
Wygaszacz obrazowy to taki kt≤ry nie generuje sam
obrazu ale zajmuje siΩ przekszta│caniem obrazu widocznego na monitorze
w momencie jego wywo│ania. Mo┐e go np. ╢ciemniaµ, rozmywaµ lub
deformowaµ i inny spos≤b. Mo┐liwe jest wiele r≤┐nych przekszta│ce±.
Oczywi╢cie wszystkie powy┐sze pomys│y mo┐na
jak najbardziej │▒czyµ ze sob▒. Nie ma tu ┐adnych regu│. Czym
ciekawsze i nieoczekiwane bΩdzie zachowanie programu tym lepiej.
Przyk│adem jest znany mi wygaszacz przedstawiaj▒cy
chodz▒cego sobie po ekranie stworka, kt≤ry co jaki╢ czas wygryza kawa│ek
ekranu. Jest on po│▒czeniem dw≤ch ostatnich technik. Zachowywana jest
dotychczasowa zawarto╢µ ekrany na kt≤rej stworek jest wy╢wietlany
jako animacja.
5) Wygaszacz ekrany i d╝wiΩk.
W wygaszaczach d╝wiΩk odgrywa
pomocnicza role i czΩsto nie wystΩpuje. Tym niemniej mo┐na zastosowaµ
proste efekty d╝wiΩkowe. Czasami mog▒ byµ one wa┐nym elementem
wygaszacza. Przypomnia│ mi siΩ tu wygaszacz przedstawiaj▒cy ╢pi▒ca
sylwetkΩ Dino (taki zwierzaczek z kresk≤wki Flinstonowie) a z g│o╢nika
dobiega bardzo realistyczne chrapanie.
Jedna uwaga. U»YTKOWNIK ZAWSZE MUSI MIE╞ MO»LIWOª╞
WYúíCZENIA D¼WI╩KU W WYGASZACZU.
6) Na koniec.
DziΩkujΩ tym wszystkim kt≤rzy dotarli do ko±ca
tego tekstu i ┐yczΩ owocnej pracy.
BΩdΩ wdziΩczny za wszelkie uwagi krytyczne na jego
temat. Prosi│ bym r≤wnie┐ aby osoby korzystaj▒ce z niego i do│▒czonych
do niego pochwali│y siΩ swoimi projektami.
7) Literatura.
Zawarte w niemniejszym dokumencie informacje pochodz▒
w znacznej czΩ╢ci z w│asnych do╢wiadcze±, czΩ╢µ z nich za╢
pochodzi z ksi▒┐ki:
Janusz Karmi±ski "Praktyczny kurs programowania
w Windows 95.". Helion.
Adam Kowalczyk. akowalc1@elka.pw.edu.pl
12.06.2001
http://home.elka.pw.edu.pl/~akowalc1