Ekran Koruyucu Yazma
________________________________________
Aslında ekran koruyucu (screen saver) programların normal programlardan pek farkı yoktur. Ekran koruyucuları normal bir program gibi yazılır ancak derlenirken uzantı yerine EXE değil de SCR verilir. Windows ekran koruyucuyu çalıştırırken bazı özel komut satırı parametreleri kullanır. Bu parametreleri programınızdan işlerseniz ekran koruyucu programı uygun şekilde çalıştırmış olursunuz.
Bir ekran koruyucu programda bulunması gereken işlemleri şu adımlarla özetleyebiliriz.
1. Ekran koruyucunun işlevini yerine getirecek kod. Örneğin ekrana rasgele çizimler yapacak kod. Bunu genellikle bir Timer kontrolünün Timer olayına yazabilirsiniz.
2. Ekran koruyucunun iki defa çalışmasını önleyecek kod.
3. Alt+Tab ve Ctrl+Alt+Del tuşlarını önleyecek kod.
4. Fare veya Klavyeden bir tuşa basıldığıdan ekran koruyucuyu sonlandırma.
5. /s, /p , /c parametrelerini işleyerek Windowstan gelen mesajlara göre ekran koruyucuyu çalıştıracak kod.
6. Formun tam ekran haline getirilmesi ve başlığının kaldırılması.
7. Ekran koruyucu uygulamasının SCR uzantısıyla derlenmesi ve Windows'a tanıtılması.
Şimdi bu adımları sırasıyla anlatarak bir örnekte uygulayalım.
1- Ekran koruyucunun işlevini yerine getirecek kod
________________________________________
Bu kısım ekran koruyucunuzun ekranda yapacağı işlemleri içerir. Ekranda animasyonlar, müzik veya çizimler yaptırabilirsiniz.
Örnek olarak ekranda rasgele daireler çizecek bir ekran koruyucu yapalım. bunun için formumuza bir Timer yerleştirin ve Interval özelliğini 100 yaparak aşağıdaki kodu yazın.
- Kod:
-
Private Sub Timer1_Timer()
FillColor = RGB(Rnd * 255, Rnd * 255, Rnd * 255)
FillStyle = 0
Circle (Rnd * Width, Rnd * Height), Rnd * Width, RGB(Rnd * 255, Rnd * 255, Rnd * 255)
End Sub
Bu kodumuz, form üzerine aşağıdaki gibi rastgele daireler çizecektir.
2- Ekran koruyucunun iki defa çalışmasını önleyecek kod.
________________________________________
Ekran koruyucunun iki defa çalışmasını önlemek için VB'deki App nesnesinin PrevInstance özelliğini kullanabiliriz. Eğer uygulama zaten çalışıyorsa bu özellik true değerini alacaktır. Bu özelliği kontrol ederek, zaten çalışıyorsa tekrar çalışmamasını sağlayabiliriz.
- Kod:
-
Private Sub Form_Load()
Timer1.Interval = 100
If App.PrevInstance Then
Unload Me
End If
End Sub
3- Alt+Tab ve Ctrl+Alt+Del tuşlarını önleyecek kod.
________________________________________
Ekran koruyucu çalışırken Alt+Tab ve Ctrl+Alt+Del gibi Windows'a ait özel tuşların görevlerini yerine getirmemesi gerekir. Bunu yapabilmek için SystemParametersInfo api'sini kullanabiliriz. Ekran koruyucu çalıştığında bu Api'yi kullanarak ekran koruyucunun çalışmaya başladığını Windows'a bilidirmemiz, ekran koruyucu çalışmasını bitirdiğinde de yine aynı Api ile uygulamanın sona erdiğini bildirmemiz gerekir.
Bu işlem için formun Load ve UnLoad olaylarında durumu Windows'a aşağıdaki gibi bildirebiliriz.
- Kod:
-
Option Explicit
Private Const SPI_SCREENSAVERRUNNING = 97
'Api tanımı
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any,ByVal fuWinIni As Long) As Long
Private Sub Form_Load()
Timer1.Interval = 100
If App.PrevInstance Then
Unload Me
End If
'Ekran koruyucunun çalışmaya başladığını bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1, ByVal 1&, False
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Ekran koruyucunun bittiğini bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 0, ByVal 1&, False
End Sub
4-Fare veya Klavye hareketlerini işleme
________________________________________
Ekran koruyucu çalışırken bir tuşa basıldığında, fare hareket ettirildiğinde veya fare tıklandığında ekran koruyucunun sona ermesi gerekir. Formun KeyDown, Click, DblClick ve MouseMove olaylarına aşağıdaki gibi çıkış için gerekli kodu yazmak gerekir.
- Kod:
-
Private Sub Form_Click()
Unload Me
End Sub
Private Sub Form_DblClick()
Unload Me
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Unload Me
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Unload Me
End Sub
Bu kodun normal çalışması beklenir ancak MouseMove olayında problem çıkacaktır. Çünkü form çalıştığı anda formun MouseMove olayı meydana gelir ve program sona erer. Ayrıca farenin en ufak hareketinde sona ermemesi için belli bir aralık konabilir. Mouse belli bir miktar hareket ettikten sonra programın sona ermesi istenir. Bu işlem için MouseMove olayı aşağıdaki gibi değiştirilmelidir.
- Kod:
-
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
Static ox, oy
'İlk defa çalışıyorsa veya önceki koordiatlardan 5 birimden daha az hareket etmişse etkilenme
If ((ox = 0) And (oy = 0)) Or ((Abs(ox - x) < 5) And (Abs(oy - y) < 5)) Then
'koordinatları sakla
ox = x'
oy = y
Exit Sub
Else
Unload Me
End If
End Sub
5- /s, /p , /c parametrelerini işleyecek kod
________________________________________
Windows bir ekran koruyucuya çalıştırırken bazı parametreler gönderebilir. Bunlar komut satırı parametreleridir ve ekran koruyucuya yapması gereken işi bildirir. Komut satırı parametrelerini VB'de Command fonksiyonuyla öğrenerek gelen parametreleri yorumlayabiliriz.
Windows'un göndereceği parametreler şunlardır:
/s : Ekran koruyucuyu normal çalıştır.
/c : Kullanıcı ekran koruyucu ayarlarını yapmak istemiştir. Varsa ayar formunuzu gösterin.
/p handle: Preview-Önizleme modunu çalıştır. Denetim Masasındaki Görüntü simgesini çift tıkladığınızda açılan pencerenin Ekran Koruyucu kısmına geçip bir ekran koruyucu seçerseniz penceredeki küçük ekranda ekran koruyucunun çalıştığını görürsünüz. İşte bu parametre ile o pencerenin handle numarası gelir. Bu handle numarasını kullanarak çiziminizi o pencere içine yaptırabilirsiniz.
/s parametresi
Command fonksiyonu ile komut satırında /s parametresi kullanılıp kullanılmadığını kontrol edebilirsiniz. Eğer /s parametresi kullanılmışsa ekran koruyucunun normal olarak çalışması gerekir.
Örneğimizde Timer1 kontrolüne yazdığımız kod ekran koruyucunun işlevini yerine getiriyordu. Fomun Load olayında /s parametresini kontrol ederek Timer'i aktif hale getirebiliriz.
- Kod:
-
Private Sub Form_Load()
Timer1.Interval = 100
Timer1.Enabled = False
If App.PrevInstance Then
Unload Me
End If'Ekran koruyucunun çalışmaya başladığını bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1, ByVal 1&, False
If Command = "/s" Then Timer1.Enabled = True
End Sub
/c parametresi
Command fonksiyonu ile komut satırında /c parametresi kullanılıp kullanılmadığını kontrol edebilirsiniz. Eğer /c parametresi kullanılmışsa ekran koruyucunun ayarlarının yapılabileceği yeni bir formu gösterebilirsiniz.
Örneğimizde ayar olarak kullanıcının Text kutusuna bir şeyler yazabilmesini ve yazdığı metnin çizimle birlikte yazılmasını sağlayalım. Ayrıca kullanıcı fontu da belirleyebilsin.
Bunun için programınıza Project-Add Form menüleri ile yeni bir form ekleyip aşağıdaki gibi hazırlayın.
Formdaki Combo1 içinde font isimlerini gösterebilmek ve Tamam düğmesi ile formu kapatıp ayarları Registry içine saklamak için de aşağıdaki kodları Form2'nin kod penceresine yazalım.
'Bu kod Form2'ye yazılacak
- Kod:
-
Private Sub Command1_Click()
SaveSetting "BizimEkranKoruyucu", "Ayarlar", "Metin", Text1
SaveSetting "BizimEkranKoruyucu", "Ayarlar", "Font", Combo1.Text
Unload Me
End Sub
Private Sub Form_Load()
Dim i
For i = 0 To Screen.FontCount - 1
Combo1.AddItem Screen.Fonts(i)
Next
End Sub
Şimdi Form1 içinde gerekli düzenlemeleri yaparak /c paramatresi kullanılmışsa ayar kutusunun gösterilmesini sağlayalım.
- Kod:
-
Private Sub Form_Load()
Timer1.Interval = 100
Timer1.Enabled = False
If App.PrevInstance Then
Unload Me
End If
'Ekran koruyucunun çalışmaya başladığını bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1, ByVal 1&, False
Caption = Command
If Command = "/s" Then Timer1.Enabled = True
If Left(Command, 2) = "/c" Then Form2.Show: Unload Me
End Sub
Ayrıca yaptığımız ayarlara göre kullanıcının Text kutusuna yazdığı yazıyı çizimle birklikte ekrana yazabilmek için Registry'den ilgili ayarları okumamız gerekir. Bunun için Form1'deki kodu aşağıdaki gibi değiştirelim.
- Kod:
-
Dim metin, fontadi
Private Sub Form_Load()
Timer1.Interval = 100
Timer1.Enabled = False
If App.PrevInstance Then
Unload Me
End If
'Ekran koruyucunun çalışmaya başladığını bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1, ByVal 1&, False
Caption = Command
If Command = "/s" Then Timer1.Enabled = True
If Left(Command, 2) = "/c" Then Form2.Show: Unload Me
metin = GetSetting("BizimEkranKoruyucu", "Ayarlar", "Metin", "İhsan Karagülle")
fontadi = GetSetting("BizimEkranKoruyucu", "Ayarlar", "Font", "Times New Roman")
End Sub
Private Sub Timer1_Timer()
FillColor = RGB(Rnd * 255, Rnd * 255, Rnd * 255)
FillStyle = 0
Circle (Rnd * Width, Rnd * Height), Rnd * Width, RGB(Rnd * 255, Rnd * 255, Rnd * 255)
FontName = fontadi
FontSize = Rnd * 50 + 8
Print metin
End Sub
Böylece kullanıcı ayar penceresi ile ekran koruyucu programımıza ait bazı ayarları yapabilecektir.
/p parametresi
Eğer ekran koruyucu /p parametresi ile çalıştırılmışsa aşağıdaki penceredeki küçük bölgede ekran koruyucuyu çalıştırmamız gerekir.
Bu bölgenin handle numarası /p parametresi ile birlikte gelir. Formun Load olayına yazacağımız kodla komut satırı parametresinin ilk iki harfinin /polup olmadığını kontrol edebilir ve /p paramtersi varsa boluktan sonraki sayıyı öğrenebiliriz. Bu sayı bize yukarıdaki küçük pencerenin handle numarasını bildirecektir.
- Kod:
-
If Left(Command, 2) = "/p" Then
dim yer
yer=Instr(Command," ") 'Boşluğun yerini bul
handleNo = Val (Mid(Command, yer+1)) 'Boşluktan sonraki değer
End If
Bu numarayı öğrendikten sonra programımıza ait formu bu küçük alanın bir child formu haline getirebiliriz. Bu işlem için şu adımları uygulamamız gerekir.
1. GetWindowLong Api'si aracılığıyla formumuzun stili alınır.
2. SetWindowLong Api'si aracılığı ile formumuz Child form haline getirilir.
3. SetParent Api'si ile handle numarasını öğrendiğimiz pencere formumuzun parenti olarak belirlenir.
4. SetWindowLong Api'si ile bu değişiklik aktif hale getirilir.
5. GetClientRect Api'si ile preview penceresinin boyutları öğrenilir.
6. SetWindowPos Api'si ile formumuzun boyutları preview penceresinin boyutlarını küçültülür.
Bu işlemde kullanılacak Api ve diğer sabit tanımlarını formumuzun en başına yazın.
- Kod:
-
Private Const SPI_SCREENSAVERRUNNING = 97
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
Dim metin, fontadi, handleno
Private Const GWL_STYLE = -16
Private Const GWL_HWNDPARENT = -8
Private Const WS_CHILD = &H40000000
Private Const HWND_TOPMOST = -1&
Private Const HWND_TOP = 0&
Private Const SWP_NOZORDER = &H4
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Dim DispRec As RECT
Private Sub Form_Load()
Timer1.Interval = 100
Timer1.Enabled = False
If App.PrevInstance Then
Unload Me
End If
'/s parametresi. Ekran koruyucuyu çalıştır
If Command = "/s" Then
Timer1.Enabled = True
'Ekran koruyucunun çalışmaya başladığını bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1, ByVal 1&, False
'formu en üstte tut
SetWindowPos Form1.hwnd, -1,0,0,0,0, &H10 Or &H40 Or &H1 Or &H2
End If
'/c parametresi. Ayar penceresini göster
If Left(Command, 2) = "/c" Then
Form2.Show 'Ayar formunu göster
Unload Me
End If
'p parametresi. Preview yap.
If Left(Command, 2) = "/p" Then
Dim yer
yer = InStr(Command, " ") 'Boşluğun yerini bul
'Preview penceresinin handle numarasını öğren
handleno = Val(Mid(Command, yer + 1)) 'Boşluktan sonraki değer
Form1.Caption = "Önizleme"
Dim style
style=GetWindowLong(Form1.hwnd, GWL_STYLE) ' Form stilini öğren
style = style Or WS_CHILD 'Child özelliğini ver
SetWindowLong Form1.hwnd,GWL_STYLE,style'Yeni özelliği aktifyap
SetParent Form1.hwnd,handleno'preview penceresini formumuza parent yap
SetWindowLong Form1.hwnd,GWL_HWNDPARENT,handleno'Bu değişikliği etkinleştir
GetClientRect handleno,DispRec'Preview penceresinin boyutlarını al
'Formumuzu preview penceresine yerleştir.
SetWindowPos Form1.hwnd, HWND_TOP, 0&, 0&, DispRec.Right, DispRec.Bottom, SWP_NOZORDER Or SWP_NOACTIVATE Or SWP_SHOWWINDOW
Timer1.Enabled = True
End If
metin = GetSetting("BizimEkranKoruyucu", "Ayarlar", "Metin", "İhsan Karagülle")
fontadi = GetSetting("BizimEkranKoruyucu", "Ayarlar", "Font", "Times New Roman")
End Sub
6-Formun tam ekran haline getirilmesi
________________________________________
Ekran koruyucunun tam ekran olarak ve başlıksız çalışması gerekir. Bunun için formun BorderStyle özelliğine 0, WindowState özelliğine tam ekran vermemiz ve Capiton özelliğini de kaldırmamız gerekir. Bütün bu işlemleri formun Load olayında yapabiliriz.
- Kod:
-
BorderStyle = 0 'Çerçevesiz form
WindowState = 2 'tam ekran
Caption = "" 'Başlıksız
7-Ekran Koruyucuyu Derleme
________________________________________
Ekran koruyucu programı hazırladıktan sonra onu derleyerek SCR uzantılı hale getirmemiz ve WindowsSystem dizinine kopyalamamız gerekir. SCR uzantısının EXE uzantısından hiç bir farkı yoktur. Bu yüzden File menüsündeki Make Project1.EXE komutunu kullanacağız. Bu komutu seçtiğinizde aşağıdaki pencere ile programın derlenecek adı sorulacaktır.
Buraya c: - windows - system - bizim.scr yazarak uygulamamızın bizim.scr ismiyle Windows System dizinine derlenmesini sağlayabiliriz.
Şimdi ekran koruyucuyu Windows'ta izleyelim Denetim masasından Görüntü kısmına girin ve açılan aşağıdaki pencerenin Ekran Koruyucu kısmına geçin.
Penceredeki ComboBox'u aşağı doğru açarsanız bizim ekran koruyucuyu listede görebilirsiniz.
Yaptığımız ekran koruyucunun tam kodu aşağıdaki gibidir:
'ÖRNEK: Ekran Koruyucu
- Kod:
-
Option Explicit
Private Const SPI_SCREENSAVERRUNNING = 97
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
Dim metin, fontadi, handleno
Private Const GWL_STYLE = -16
Private Const GWL_HWNDPARENT = -8
Private Const WS_CHILD = &H40000000
Private Const HWND_TOPMOST = -1&
Private Const HWND_TOP = 0&
Private Const SWP_NOZORDER = &H4
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Dim DispRec As RECT
Private Sub Form_Click()
Unload Me
End Sub
Private Sub Form_DblClick()
Unload Me
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Unload Me
End Sub
Private Sub Form_Load()
Timer1.Interval = 100
Timer1.Enabled = False
Timer2.Interval = 100
Timer2.Enabled = False
BorderStyle = 0 'Çerçevesiz form
WindowState = 2 'tam ekran
Caption = "" 'Başlıksız
If App.PrevInstance Then
Unload Me
Exit Sub
End If
'/s parametresi. Ekran koruyucuyu çalıştır
If Command = "/s" Then
Timer1.Enabled = True
'Ekran koruyucunun çalışmaya başladığını bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1, ByVal 1&, False
'formu en üstte tut
SetWindowPos Form1.hwnd, -1, 0, 0, 0, 0, &H10 Or &H40 Or &H1 Or &H2
End If
'/c parametresi. Ayar penceresini göster
If Left(Command, 2) = "/c" Then
Form2.Show 'Ayar formunu göster
Unload Me
End If
'p parametresi. Preview yap.
If Left(Command, 2) = "/p" Then
Dim yer
yer = InStr(Command, " ") 'Boşluğun yerini bul
'Preview penceresinin handle numarasını öğren
handleno = Val(Mid(Command, yer + 1)) 'Boşluktan sonraki değer
Form1.Caption = "Önizleme"
Dim style
style = GetWindowLong(Form1.hwnd, GWL_STYLE) ' Form stilini öğren
style = style Or WS_CHILD 'Child özelliğini ver
SetWindowLong Form1.hwnd, GWL_STYLE, style 'Yeni özelliği aktifyap
SetParent Form1.hwnd, handleno 'preview penceresini formumuza parent yap
SetWindowLong Form1.hwnd, GWL_HWNDPARENT, handleno 'Bu değişikliği etkinleştir
GetClientRect handleno, DispRec 'Preview penceresinin boyutlarını al
'Formumuzu preview penceresine yerleştir.
SetWindowPos Form1.hwnd, HWND_TOP, 0&, 0&, DispRec.Right, DispRec.Bottom, SWP_NOZORDER Or SWP_NOACTIVATE Or SWP_SHOWWINDOW
Timer1.Enabled = True
End If
metin = GetSetting("BizimEkranKoruyucu", "Ayarlar", "Metin", "İhsan Karagülle")
fontadi = GetSetting("BizimEkranKoruyucu", "Ayarlar", "Font", "Times New Roman")
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
Static ox, oy
If ((ox = 0) And (oy = 0)) Or ((Abs(ox - x) < 5) And (Abs(oy - y) < 5)) Then
ox = x
oy = y
Exit Sub
Else
Unload Me
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Ekran koruyucunun bittiğini bildir
SystemParametersInfo SPI_SCREENSAVERRUNNING, 0, ByVal 1&, False
End Sub
Private Sub Timer1_Timer()
FillColor = RGB(Rnd * 255, Rnd * 255, Rnd * 255)
FillStyle = 0
Circle (Rnd * Width, Rnd * Height), Rnd * Width, RGB(Rnd * 255, Rnd * 255, Rnd * 255)
FontName = fontadi
FontSize = Rnd * 50 + 8
Print metin
End Sub
Private Sub Timer2_Timer()
Unload Me
End Sub