|
|
|||||||||||||
|
|
Saydam Pencereler
Bu yazıda saydam pencerelerin nasıl oluşturulacağı ve Windows'taki bölge tanımlayıcılarının nasıl kullanıldığı hakkında bilgiler yer alıyor.
Pencerelerin saydamlığı temelde iki çeşittir. Bir renk belirtilerek bu renge sahip yerlerin görünmemesi ve aynı zamanda pencerenin görünen kısımlarının herhangi bir oranda saydamlaştırılması sağlanabilir.
Delphi6'da olmasına rağmen VB için ancak .NET sürümü ile gelen AlphaBlend özelliği saydam pencereler oluşturmayı kolaylaştırmıştır.
Doğrusu VB6'da bunu yapmak için yeni sürümü beklemeye gerek yoktu. Windows saydamlıkla ilgili çeşitli APİ işlevleri sunuyor. Windows 2000 ile birlikte gelen SetLayeredWindowAttributes işlevi pencereleri saydamlaştırır. (Bu, eski Windows'larda aşağıdaki kodların ve ekteki örnek uygulamaların doğru çalışmayacağı anlamına geliyor.)
Const gorunurluk = 120 'En çok 255 If (stil And WS_EX_LAYERED) = 0 Then _
var const begin stil := GetWindowLong(Handle, GWL_EXSTYLE); key:=0; if (stil and WS_EX_LAYERED) = 0 then SetLayeredWindowAttributes(Handle, 0, gorunurluk, LWA_ALPHA);
Pencereler tam olarak görüntülendiklerinde görüntülenme değeri 255'tir. Bunu 0 yapmak pencereyi tamamen gizler.
Pencerenin tamamını saydamlaştırmak yerine belirtilen bir renge ait bölgelerin tamamen gizlenmesi de sağlanabilir. Yukarıdaki kodda SetLayeredWindowAttributes işlevinin bulunduğu satırları aşağıdaki gibi düzenlemek yeterlidir. [VB] [Delphi] Ekteki Saydam uygulamasının Hakkında kutusunda beyaz kısımları gizledik. Pencere üzerinde karmaşık resimler olduğunda bile renk doğru ve hızlı bir şekilde gizleniyor.
Kutuyu sağ tuşla tıkladığınızda pencere yavaşça kaybolacak. Tabii bu bir saat bileşeni içinde AlphaBlendValue özelliğini azaltmaktan başka bir şey değildi.
Windows pencerelerin ekranda kapladıkları bölgeyi HRGN (handle of region) türündeki genel bölge belirteci ile tanımlar. Bir bölge dörtgen, elips, oval, çokgen ve bunların herhangi şekildeki birleşimi olabilir. Çözümü pek mümkün görünmeyen Logo Puzzle oyununda pencereyi bu yolla çerçevelendirmiştik.
Dörtgen oluşturmak için birkaç APİ işlevi mevcuttur. Basit bir dörtgen CreateRectRGN, eğik yuvarlak ya da bir çember oluşturmak da CreateEllipticRgn ile yapılabilir. Bir bölgeyi oluşturmak pencereleri ya da diğer şeyleri şekillendirmek için yeterli değildir. Bunu pencereye uygulamak gerekir. HRGN’nin işaret ettiği adreste yalnızca bölgenin tam olarak nasıl tanımlandığını ifade eden bilgiler yer alır. Bir dörtgen ya da çokgen için kenarlara ait noktalar bu adreste saklanır.
procedure TForm1.Button1Click(Sender: TObject);
Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long Private Sub Command1_Click()
Tabii bir form penceresini bu işlevler kullanılarak çokgen, yıldız ya da karmaşık bir başka şekle sokulabilir.
Bölgeler belli genel şekillerde olmayıp yukarıda belirtilenlerin birleşimi, kesişimi, farkları alınarak oluşturulabilirler. Bu işlem CombineRGN işlevi ile yapılır. CombineRGN sırayla sonuç bölgesini, birinci ve ikinci bölgeleri ve katıştırma tipini geçiş değişkeni olarak almaktadır. Örneğin birinci ve ikinci bölgenin birleşiminin alınması için katıştırma değerini RGN_OR yapmak gerekir. Ayrıca CombineRGN’den önce sonuç bölgesi tanımının herhangi bir şekilde yapılmış olması gerektiğini bilmelisiniz. Aşağıdaki kodda sonuç bölgesi CreateRectRGN ile rasgele bir şekilde tanımlanıyor ve CombineRGN satırında birinci ve ikinci bölgeler RGN_OR ile birleştiriliyor. bolge:=CreateRectRgn(0,0,0,0); CombineRGN katıştırma yöntemi olarak RGN_AND, RGN_COPY, RGN_DIFF, RGN_OR, RGN_XOR değerlerini alabiliyor. Yukarıdaki kodda bir daire ve dörtgen birleştiriliyor. Aşağıdaki resimlerde bunu görebilirsiniz.
Bölgelerin farkını almak çok çeşitli geometrik şekiller üretmenizi sağlayabilir. Örneğin ay şekilde bir pencere oluşturmak için kısmen çakışan iki dairenin farkını almak yeterlidir. Ya da yıldız şeklinde bir bölgeyi, köşe noktalarını doğrudan belirterek oluşturmak mümkündür. var Bir ay ve yıldız tanımlanıp bunları CombineRGN ile birleştirdiğinizde oluşacak görüntü tabii ki bu ikisinin birleşimi şeklindedir. var begin ayyildiz:= CreateRectRgn(0,0,0,0);
SetWindowRgn(handle,ayyildiz,true);
Bölge tanımlarının tersini almak da yukarıdakilerden farklı değildir. Bölgenin içinde bulunduğu dış pencere, bu bölge için evrensel küme olarak kabul edilebilir. Dış pencere bölgesi ile bu bölgenin farkı, bölgenin tümleyenini yani tersini verir.
SetWindowRgn(handle, bolge, true);
DOSYALAR: Serkan ŞAHİNOĞLU |