Menangani Pengaman Layar
Microsoft Win32 API mendukung aplikasi khusus yang disebut pengaman layar. Screen saver mulai berjalan ketika mouse dan keyboard tidak aktif selama jangka waktu tertentu. Mereka digunakan karena dua alasan ini:
- Untuk melindungi layar dari pembakaran fosfor yang disebabkan oleh gambar statis.
- Untuk menyembunyikan informasi sensitif yang tersisa di layar.
Topik ini dibagi menjadi bagian berikut.
Tentang Pengaman Layar
Aplikasi Desktop di Panel Kontrol Windows memungkinkan pengguna memilih dari daftar pengaman layar, menentukan berapa banyak waktu yang harus berlalu sebelum pengaman layar dimulai, mengonfigurasi pengaman layar, dan pengaman layar pratinjau. Pengaman layar dimuat secara otomatis ketika Windows dimulai atau ketika pengguna mengaktifkan pengaman layar melalui Panel Kontrol.
Setelah pengaman layar dipilih, Windows memantau penekanan tombol dan gerakan tetikus lalu memulai penghemat layar setelah periode tidak aktif. Namun, Windows tidak memulai pengaman layar jika ada salah satu kondisi berikut:
- Aplikasi aktif bukan aplikasi berbasis Windows.
- Jendela pelatihan berbasis komputer (CBT) tersedia.
- Aplikasi aktif menerima pesan WM_SYSCOMMAND dengan parameter wParam diatur ke nilai SC_SCREENSAVE, tetapi tidak meneruskan pesan ke fungsi DefWindowProc.
Konteks Keamanan Pengaman Layar
Konteks keamanan pengaman layar bergantung pada apakah pengguna masuk secara interaktif. Jika pengguna masuk secara interaktif saat pengaman layar dipanggil, pengaman layar berjalan dalam konteks keamanan pengguna interaktif. Jika tidak ada pengguna yang masuk, konteks keamanan pengaman layar bergantung pada versi Windows yang digunakan.
- Windows XP dan Windows 2000 - pengaman layar berjalan dalam konteks LocalSystem dengan akun yang dibatasi.
- Windows 2003 - pengaman layar berjalan dalam konteks LocalService dengan semua hak istimewa dihapus dan grup administrator dinonaktifkan.
- Tidak berlaku untuk Windows NT4.
Konteks keamanan menentukan tingkat operasi istimewa yang dapat dilakukan dari pengaman layar.
Windows Vista dan yang lebih baru: Jika perlindungan kata sandi diaktifkan oleh kebijakan, pengaman layar dimulai terlepas dari apa yang dilakukan aplikasi dengan pemberitahuan SC_SCREENSAVE.
Pengaman layar berisi fungsi, definisi sumber daya, dan deklarasi variabel tertentu yang diekspor. Pustaka pengaman layar berisi fungsi utama dan kode startup lainnya yang diperlukan untuk pengaman layar. Saat pengaman layar dimulai, kode pengaktifan di pustaka pengaman layar membuat jendela layar penuh. Kelas jendela untuk jendela ini dinyatakan sebagai berikut:
WNDCLASS cls;
cls.hCursor = NULL;
cls.hIcon = LoadIcon(hInst, MAKEINTATOM(ID_APP));
cls.lpszMenuName = NULL;
cls.lpszClassName = "WindowsScreenSaverClass";
cls.hbrBackground = GetStockObject(BLACK_BRUSH);
cls.hInstance = hInst;
cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_DBLCLKS;
cls.lpfnWndProc = (WNDPROC) ScreenSaverProc;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
Untuk membuat pengaman layar, sebagian besar pengembang membuat modul kode sumber yang berisi tiga fungsi yang diperlukan dan menautkannya dengan pustaka pengaman layar. Modul pengaman layar hanya bertanggung jawab untuk mengonfigurasi dirinya sendiri dan untuk memberikan efek visual.
Salah satu dari tiga fungsi yang diperlukan dalam modul pengaman layar adalah ScreenSaverProc. Fungsi ini memproses pesan tertentu dan meneruskan pesan yang tidak diproses kembali ke pustaka pengaman layar. Berikut adalah beberapa pesan umum yang diproses oleh ScreenSaverProc.
Pesan | Arti |
---|---|
WM_CREATE | Ambil data inisialisasi apa pun dari file Regedit.ini. Atur pengatur waktu jendela untuk jendela pengaman layar. Lakukan inisialisasi lain yang diperlukan. |
WM_ERASEBKGND | Hapus jendela pengaman layar dan bersiaplah untuk operasi menggambar berikutnya. |
WM_TIMER | Lakukan operasi menggambar. |
WM_DESTROY | Hancurkan timer yang dibuat saat aplikasi memproses pesan WM_CREATE. Lakukan pembersihan tambahan yang diperlukan. |
ScreenSaverProc meneruskan pesan yang tidak diproses ke pustaka pengaman layar dengan memanggil fungsiDefScreenSaverProc. Tabel berikut ini menjelaskan cara fungsi ini memproses berbagai pesan.
Pesan | Perbuatan |
---|---|
WM_SETCURSOR | Atur kursor ke kursor null, menghapusnya dari layar. |
WM_PAINT | Cat latar belakang layar. |
WM_LBUTTONDOWN | Hentikan pengaman layar. |
WM_MBUTTONDOWN | Hentikan pengaman layar. |
WM_RBUTTONDOWN | Hentikan pengaman layar. |
WM_KEYDOWN | Hentikan pengaman layar. |
WM_MOUSEMOVE | Hentikan pengaman layar. |
WM_ACTIVATE | Hentikan penghemat layar jika parameter wParam diatur ke FALSE. |
Fungsi kedua yang diperlukan dalam modul pengaman layar adalah ScreenSaverConfigureDialog. Fungsi ini menampilkan kotak dialog yang memungkinkan pengguna mengonfigurasi pengaman layar (aplikasi harus menyediakan templat kotak dialog yang sesuai). Windows menampilkan kotak dialog konfigurasi ketika pengguna memilih tombol Penyetelan dalam kotak dialog Pengaman Layar Panel Kontrol.
Fungsi ketiga yang diperlukan dalam modul pengaman layar adalah RegisterDialogClasses. Fungsi ini harus dipanggil oleh semua aplikasi pengaman layar. Namun, aplikasi yang tidak memerlukan jendela khusus atau kontrol kustom dalam kotak dialog konfigurasi cukup mengembalikan TRUE. Aplikasi yang memerlukan jendela khusus atau kontrol kustom harus menggunakan fungsi ini untuk mendaftarkan kelas jendela yang sesuai.
Selain membuat modul yang mendukung tiga fungsi yang baru saja dijelaskan, pengaman layar harus menyediakan ikon. Ikon ini hanya terlihat ketika pengaman layar dijalankan sebagai aplikasi mandiri. (Untuk dijalankan oleh Panel Kontrol, pengaman layar harus memiliki ekstensi nama file .scr; untuk dijalankan sebagai aplikasi mandiri, ia harus memiliki ekstensi nama file .exe.) Ikon harus diidentifikasi dalam file sumber daya pengaman layar dengan konstanta ID_APP, yang ditentukan dalam file header Scrnsave.h.
Satu syarat terakhir adalah string deskripsi pengaman layar. File sumber daya untuk pengaman layar harus berisi string yang ditampilkan Panel Kontrol sebagai nama pengaman layar. String deskripsi harus menjadi string pertama dalam tabel string file sumber daya (diidentifikasi dengan nilai ordinal 1). Namun, string deskripsi diabaikan oleh Panel Kontrol jika pengaman layar memiliki nama file yang panjang. Dalam kasus seperti itu, nama file akan digunakan sebagai string deskripsi.
Menggunakan Fungsi Pengaman Layar
Bagian ini menggunakan contoh kode yang diambil dari aplikasi pengaman layar untuk mengilustrasikan tugas-tugas berikut:
- Membuat Pengaman Layar
- Menginstal Screensaver Baru
- Menambahkan Bantuan ke Kotak Dialog Konfigurasi Pengaman Layar
Membuat Pengaman Layar
Pada interval mulai dari 1 hingga 10 detik, aplikasi dalam contoh ini mengecat ulang layar dengan salah satu dari empat warna: putih, abu-abu muda, abu-abu gelap, dan hitam. Aplikasi ini melukis layar setiap kali menerima pesan WM_TIMER. Pengguna dapat menyesuaikan interval di mana pesan ini dikirim dengan memilih kotak dialog konfigurasi aplikasi dan menyesuaikan satu bilah gulir horizontal.
Koleksi pengaman layar
Fungsi pengaman layar statis terkandung dalam pustaka pengaman layar. Ada dua versi pustaka yang tersedia, Scrnsave.lib dan Scrnsavw.lib. Anda harus menautkan proyek Anda dengan salah satu dari ini. Scrnsave.lib digunakan untuk pengaman layar yang menggunakan karakter ANSI, dan Scrnsavw.lib digunakan untuk pengaman layar yang menggunakan karakter Unicode. Pengaman layar yang ditautkan dengan Scrnsavw.lib hanya akan berjalan pada platform Windows yang mendukung Unicode, sementara pengaman layar yang ditautkan dengan Scrnsave.lib akan berjalan di platform Windows apa pun.
Mendukung penggunaan kotak dialog konfigurasi
Sebagian besar pengaman layar menyediakan kotak dialog konfigurasi untuk memungkinkan pengguna menentukan data kustomisasi seperti warna unik, kecepatan menggambar, ketebalan garis, font, dan sebagainya. Untuk mendukung kotak dialog konfigurasi, aplikasi harus menyediakan templat kotak dialog dan juga harus mendukung fungsiScreenSaverConfigureDialog. Berikut ini adalah templat kotak dialog untuk aplikasi sampel.
DLG_SCRNSAVECONFIGURE DIALOG 6, 18, 160, 63
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Sample Screen-Saver Setup"
FONT 8, "MS Shell Dlg"
BEGIN
GROUPBOX "Redraw Speed", 101, 0, 6, 98, 40
SCROLLBAR ID_SPEED, 5, 31, 89, 10
LTEXT "Fast", 103, 6, 21, 20, 8
LTEXT "Slow", 104, 75, 21, 20, 8
PUSHBUTTON "OK", ID_OK, 117, 10, 40, 14
PUSHBUTTON "Cancel", ID_CANCEL, 117, 32, 40, 14
END
Anda harus menentukan konstanta yang digunakan untuk mengidentifikasi templat kotak dialog dengan menggunakan nilai desimal 2003, seperti dalam contoh berikut:
#define DLG_SCRNSAVECONFIGURE 2003
Contoh berikut menunjukkan fungsiScreenSaverConfigureDialog yang ditemukan dalam aplikasi sampel.
#define MINVEL 1 // minimum redraw speed value
#define MAXVEL 10 // maximum redraw speed value
#define DEFVEL 5 // default redraw speed value
LONG lSpeed = DEFVEL; // redraw speed variable
extern HINSTANCE hMainInstance; // screen saver instance handle
CHAR szAppName[80]; // .ini section name
CHAR szTemp[20]; // temporary array of characters
CHAR szRedrawSpeed[ ] = "Redraw Speed"; // .ini speed entry
CHAR szIniFile[MAXFILELEN]; // .ini or registry file name
BOOL WINAPI ScreenSaverConfigureDialog(hDlg, message, wParam, lParam)
HWND hDlg;
UINT message;
DWORD wParam;
LONG lParam;
HRESULT hr;
{
static HWND hSpeed; // handle to speed scroll bar
static HWND hOK; // handle to OK push button
switch(message)
{
case WM_INITDIALOG:
// Retrieve the application name from the .rc file.
LoadString(hMainInstance, idsAppName, szAppName,
80 * sizeof(TCHAR));
// Retrieve the .ini (or registry) file name.
LoadString(hMainInstance, idsIniFile, szIniFile,
MAXFILELEN * sizeof(TCHAR));
// TODO: Add error checking to verify LoadString success
// for both calls.
// Retrieve any redraw speed data from the registry.
lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,
DEFVEL, szIniFile);
// If the initialization file does not contain an entry
// for this screen saver, use the default value.
if(lSpeed > MAXVEL || lSpeed < MINVEL)
lSpeed = DEFVEL;
// Initialize the redraw speed scroll bar control.
hSpeed = GetDlgItem(hDlg, ID_SPEED);
SetScrollRange(hSpeed, SB_CTL, MINVEL, MAXVEL, FALSE);
SetScrollPos(hSpeed, SB_CTL, lSpeed, TRUE);
// Retrieve a handle to the OK push button control.
hOK = GetDlgItem(hDlg, ID_OK);
return TRUE;
case WM_HSCROLL:
// Process scroll bar input, adjusting the lSpeed
// value as appropriate.
switch (LOWORD(wParam))
{
case SB_PAGEUP:
--lSpeed;
break;
case SB_LINEUP:
--lSpeed;
break;
case SB_PAGEDOWN:
++lSpeed;
break;
case SB_LINEDOWN:
++lSpeed;
break;
case SB_THUMBPOSITION:
lSpeed = HIWORD(wParam);
break;
case SB_BOTTOM:
lSpeed = MINVEL;
break;
case SB_TOP:
lSpeed = MAXVEL;
break;
case SB_THUMBTRACK:
case SB_ENDSCROLL:
return TRUE;
break;
}
if ((int) lSpeed <= MINVEL)
lSpeed = MINVEL;
if ((int) lSpeed >= MAXVEL)
lSpeed = MAXVEL;
SetScrollPos((HWND) lParam, SB_CTL, lSpeed, TRUE);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_OK:
// Write the current redraw speed variable to
// the .ini file.
hr = StringCchPrintf(szTemp, 20, "%ld", lSpeed);
if (SUCCEEDED(hr))
WritePrivateProfileString(szAppName, szRedrawSpeed,
szTemp, szIniFile);
case ID_CANCEL:
EndDialog(hDlg, LOWORD(wParam) == ID_OK);
return TRUE;
}
}
return FALSE;
}
Selain menyediakan templat kotak dialog dan mendukung fungsiScreenSaverConfigureDialog, aplikasi juga harus mendukung fungsiRegisterDialogClasses. Fungsi ini mendaftarkan kelas jendela nonstandar yang diperlukan oleh pengaman layar. Karena aplikasi sampel hanya menggunakan kelas jendela standar dalam prosedur kotak dialognya, fungsi ini hanya mengembalikan TRUE, seperti dalam contoh berikut:
BOOL WINAPI RegisterDialogClasses(hInst)
HANDLE hInst;
{
return TRUE;
}
Mendukung prosedur jendela pengaman layar
Setiap pengaman layar harus mendukung prosedur jendela bernama ScreenSaverProc. Seperti kebanyakan prosedur jendela, ScreenSaverProc memproses serangkaian pesan tertentu dan meneruskan pesan yang tidak diproses ke prosedur default. Namun, alih-alih meneruskannya ke fungsi DefWindowProc, ScreenSaverProc meneruskan pesan yang tidak diproses ke fungsiDefScreenSaverProc. Perbedaan lain antara ScreenSaverProc dan prosedur jendela normal adalah bahwa handle yang diteruskan ke ScreenSaverProc mengidentifikasi keseluruhan desktop daripada jendela klien. Contoh berikut menunjukkan prosedur jendela ScreenSaverProc untuk pengaman layar sampel.
LONG WINAPI ScreenSaverProc(hwnd, message, wParam, lParam)
HWND hwnd;
UINT message;
DWORD wParam;
LONG lParam;
{
static HDC hdc; // device-context handle
static RECT rc; // RECT structure
static UINT uTimer; // timer identifier
switch(message)
{
case WM_CREATE:
// Retrieve the application name from the .rc file.
LoadString(hMainInstance, idsAppName, szAppName, 80 * sizeof(TCHAR));
// Retrieve the .ini (or registry) file name.
LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN * sizeof(TCHAR));
// TODO: Add error checking to verify LoadString success
// for both calls.
// Retrieve any redraw speed data from the registry.
lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,
DEFVEL, szIniFile);
// Set a timer for the screen saver window using the
// redraw rate stored in Regedit.ini.
uTimer = SetTimer(hwnd, 1, lSpeed * 1000, NULL);
break;
case WM_ERASEBKGND:
// The WM_ERASEBKGND message is issued before the
// WM_TIMER message, allowing the screen saver to
// paint the background as appropriate.
hdc = GetDC(hwnd);
GetClientRect (hwnd, &rc);
FillRect (hdc, &rc, GetStockObject(BLACK_BRUSH));
ReleaseDC(hwnd,hdc);
break;
case WM_TIMER:
// The WM_TIMER message is issued at (lSpeed * 1000)
// intervals, where lSpeed == .001 seconds. This
// code repaints the entire desktop with a white,
// light gray, dark gray, or black brush each
// time a WM_TIMER message is issued.
hdc = GetDC(hwnd);
GetClientRect(hwnd, &rc);
if (i++ <= 4)
FillRect(hdc, &rc, GetStockObject(i));
else
(i = 0);
ReleaseDC(hwnd,hdc);
break;
case WM_DESTROY:
// When the WM_DESTROY message is issued, the screen saver
// must destroy any of the timers that were set at WM_CREATE
// time.
if (uTimer)
KillTimer(hwnd, uTimer);
break;
}
// DefScreenSaverProc processes any messages ignored by ScreenSaverProc.
return DefScreenSaverProc(hwnd, message, wParam, lParam);
}
Membuat file definisi modul
Fungsi ScreenSaverProc dan ScreenSaverConfigureDialog harus diekspor dalam file definisi modul aplikasi; RegisterDialogClasses tidak boleh diekspor. Contoh berikut menunjukkan file definisi modul untuk aplikasi sampel.
NAME SSTEST.SCR
DESCRIPTION 'SCRNSAVE : Test'
STUB 'WINSTUB.EXE'
EXETYPE WINDOWS
CODE MOVEABLE
DATA MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 4096
EXPORTS
ScreenSaverProc
ScreenSaverConfigureDialog
Menginstal Pengaman Layar Baru
Saat mengkompilasi daftar pengaman layar yang tersedia, Panel Kontrol mencari direktori Startup Windows untuk file dengan ekstensi .scr. Karena pengaman layar adalah file standar yang dapat dijalankan Windows dengan ekstensi .exe, Anda harus mengganti namanya sehingga memiliki ekstensi .scr dan menyalinnya ke direktori yang benar.
Menambahkan Bantuan ke Kotak Dialog Konfigurasi Pengaman Layar
Kotak dialog konfigurasi untuk pengaman layar biasanya menyertakan tombol Bantuan. Aplikasi pengaman layar dapat memeriksa pengidentifikasi tombol Bantuan dan memanggil fungsiWinHelpdengan cara yang sama seperti Bantuan disediakan di aplikasi berbasis Windows lainnya.