Wygaszacze ekranu

Strona g│≤wna

 

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