Çizim İşleminin Bileşenler
Çizim kavramı pencere
içerisine yerleştirilen tüm görüntüleri içerir ve çok fazla bileşeni vardır.
Örneğin bir çizimin şekil çizgileri birkaç bileşene sahip olan kalemle yapılır.
Bir kalem çizginin biçimi, rengi, kalınlığı ile karakterize edilir. En basit
bir çizim için bile bir kaleme sahip olmak gerekir ve çizimin bu kalemle
yapılacağını sisteme açıklamak gerekir. Diğer bir biçim bileşeni fırçadır. Bir
bölgenin içi boyanacaksa bir fırçayla boyanır. Bir fırçayı fırçanın rengi ve
deseni karakterize eder. Bir yazı yazılacaksa karakterlerin görüntüsünü
belirten bir font oluşturmak gerekir. Font bir yazıdaki bütün karakterlerin
görüntü biçimlerini tanımlayan bir kavramdır.
Çizim için Handle Alınması(Display Context)
Bir çizim işlemi için
öncelikle bir handle elde edilmesi gerekir. Handle özel API fonksiyonlarıyla
elde edilebilir. Bir handle'ın elde edilmesi sırasında Windows çizim için
gereken bütün bilşenleri bir veri yapısı biçiminde dinamik olarak oluşturur ve
çizim bileşenlerine default bazı değerleri yerleştirir. Bu API fonksiyonları
handle olarak veri yapısının başlangıç adresini verirler. Çizim için alınan
handle değerinin typedef ismi HDC biçimindedir(HDC'nin gerçek türü void *'dır).
Alınan bu handle değeri çizim ile ilgili bütün API fonksiyonlarına parametre
olarak geçirilir. Böylece bu API fonksiyonları çizim bileşenlerinin neler
olduğunu anlayabilir. Çizim için handle değeri WM_PAINT mesajının başında
alınmalı sonunda geri bırakılmalıdır. Çünkü bu handle için tahsis edilen alan
dinamik bir alandır ve bütün çalışan programlar için ortak bir alan söz
konusudur. Bir programda alınmış olan bir handle'ın bırakılmaması diğer bir
program için özellikle Win3.x sistemlerinde bir kaynak azalması yaratır. 32 bit
Windows sistemlerinde GDI modülünün heap alanı çok geniş olduğu için alınan
handle'ın bırakılmaması sebebiyle ciddi bir problem çıkmayabilir. Çizim için
handle alan üç tür API fonksiyonu vardır: BeginPaint, GetDC, GetWindowDC. Eğer
handle BeginPaint fonksiyonuyla alınırsa EndPaint fonksiyonuyla bırakılmalıdır.
GetDC veya GetWindowDC fonksiyonlarıyla alınmış ise ReleaseDC fonksiyonuyla
bırakılmalıdır. BeginPaint fonksiyonu çizim handle'ını almasının yanı sıra
güncelleme alanını boş küme yapar. Oysa GetDC güncelleme alanını boş küme
yapmaz. Bu durumda WM_PAINT içerisinde BeginPaint API fonksiyonula handle almak
daha doğrudur ve uygulamada hep böyle yapılır. Örneğin tipik bir WM_PAINT
mesajı şöyle işlenmelidir:
Çizim
yapan bir API fonksiyonuna BeginPaint fonksiyonuyla alınan bir handle değeri
geçirilirse bu API fonksiyonu hiçbir zaman güncelleme alanının dışına çizim
yapamaz. Yani çizim parametreleri tüm pencereye ilişkin olsa bile yalnızca
güncelleme alanı içerisindeki bölgeyi çizerler. Aslında bu çalışma biçimi
gereksiz çizim yapılmaması için tasarlanmıştır. Ancak tabii güncelleme alanının
tamamen dışında kalan çizimler için bile API fonksiyonlarının içine
girilir(Halbuki bu fonksiyonlar reel olarak hiçbir çizim yapamayacaklardır),
böylece yine gereksiz bir zaman kaybı oluşabilecektir. Bu zaman kaybının da
oluşmaması isteniyorsa WM_PAINT içerisinde önce güncelleme alanına bakılmalı,
program akışının gereksiz çizimlere girmemesi sağlanmalıdır. Ancak çizim yapan
API fonksiyonlarına GetDC ile alınan handle geçirilirse bu API fonksiyonları
çalışma alanının her tarafına çizim yapabilirler. BeginPaint ve GetDC
fonksiyonlarıyla alınan handle için orijin noktası çalışma alanının sol üst
köşesidir. Yani bu handle'lar ile ancak çalışma alanı içerisine çizim yapılabilir.
Ancak GetWindowDC ile alınan handle için orijin noktası pencere başlığının sol
üst köşesidir. Yani pencerenin her yerine çizim yapılabilir.
BeginPaint ve EndPaint Fonksiyonları
Prototipleri:
BeginPaint fonksiyonunun
birinci parametresi çizim için alınacak handle'a ilişkin pencerenin handle
değeridir. İkinci parametre PAINTSTRUCT türünden yapının adresini alır.
BeginPaint bu yapının içerisini faydalı bilgilerle doldurur. Fonksiyonun geri
dönüş değeri çizim işlemi için elde edilen handle bilgisidir.
Alınan handle değerinin
geri bırakılması BeginPaint fonksiyonundaki parametrelerle yapılır.
Tipik bir WM_PAINT mesajı
şöyle işlenir:
Çizim İşlemlerinde Renk
Windows'daki bütün renkler
kırmızı, yeşil ve mavinin bileşiminden elde edilir. Burada bu üç rengin herbiri
0-255 arasında bir ton ile ifade edilir ve bunların karışımından da bir renk
elde edilir(RGB bilgileri video kartına bağlı olarak 8 bitten daha az olabilir.
Ancak Windows bunları uygun bir biçimde oranlamaktadır). Örneğin R=0, G=0,
B=255 değerleri kullanıldığında tam bir mavi renk elde edilir. Toplam elde
edilebilecek renk sayısı 8 * 8 * 8 biçimindedir. (24 bit True Color mode RGB
tonlarının herbirinin 1'er byte ile ifade edildiğini anlatır).
API fonksiyonları bir renk
bilgisini parametre olarak alacağı zaman bunu ayrı ayrı RGB parametreleri
biçiminde değil tek bir long sayı biçiminde alırlar. Windows.h içerisinde şöyle
bir typedef vardır:
typedef long
COLORREF;
Bütün API fonksiyonları RGB tonlarını bir long sayı içerisinde aşağıdaki
gibi beklerler:
Ayrı ayrı parametrelerle verilmiş olan RGB bilgilerini long bir sayı
biçimine dönüştüren bir makro windows.h içerisinde aşağıdaki gibi
tanımlanmıştır:
Yani sonuç olarak bir API fonksiyonu renk bilgisini COLORREF parametresiyle
ister, biz de onu RGB makrosuyla veririz.
SetPixel Fonksiyonu
.ico dosyas formatına
sahip içerisinde görüntü tek tek pixel renkleriyle kodlanmış bir biçimde
bulunan grafiksel görüntülere icon denir. Icon görüntülenme işlemleri Windows
tarafından doğrudan desteklenmektedir. Win95'e karar yalnızca 32x32'lik icon
görüntüleri kullanılıyordu. Daha sonra Win sistemleri 16x16'lık icon
görüntülerini de destekler hale gelmiştir. Windows içerisinde görev çubuğunda,
masa üstünde, pencerenin sol üst köşesinde icon görüntüleri kullanılır. Bunun
dışında programcının istediği yerde herhangi bir icon görüntülenebilir.
Programın Ana Icon'ının Oluşturulması
Genel olarak bir icon şu
adımlardan geçilerek kullanılır:
1. Icon özel editörlerle çizilir ve ico uzantısıyla diskte saklanır.
2. Icon'ın kaynak dosyasında aşağıdaki gibi belirtilmesi gerekir:
Kaynak_ismi Icon Dosya_ismi
Örnek: MYICON ICON X.ICO
3. LoadIcon API fonksiyonuyla icon kaynağı kullanıma hazır hale getirilir.
Prototipi:
HICON
LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);
Bir programın ana icon'ını
belirleme işlemi WNDCLASS yapısının hIcon elemanına LoadIcon fonksiyonundan
alınan handle değerinin yerleştirilmesiyle yapılır. Ancak Windows'da çalışmayı
kolaylaştırmak amacıyla önceden tanımlanmış özel icon handle değerleri vardır.
Bunların kullanılması için kaynak içinde belirtilmesine gerek yoktur.
Bir pencerenin parametrik
bilgileri üzerinde işlem yapan GetWindowLong, SetWindowLong fonksiyonlarının
yanı sıra bir pencerenin yaratıldığı WNDCLASS yapısının elemanları üzerinde
işlem yapan GetClassLong ve SetClassLong fonksiyonları da vardır. SetClassLong
fonksiyonunu kullanarak WNDCLASS yapısının hIcon elemanı istenildiği zaman
değiştirilebilir. Böylece herhangi bir zaman ana pencerenin icon'ı
değiştirilmiş olur. Örneğin mouse'un sol tuşuna basıldığında icon şöyle
değiştirilebilir:
Pencere İçerisine Icon Çizilmesi
Bir pencere içerisine icon
çizebilmek için icon'ın kaynakta belirtilip LoadIcon ile yüklenmesi gerekir.
LoadIcon ile yükleme işlemi örneğin WM_CREATE mesajı içerisinde yapılabilir.
Ancak çizim işleminin WM_PAINT mesajı içerisinde DrawIcon fonksiyonuyla
yapılması gerekir. Prototipi:
Burada x, y koordinatları icon'ın çizileceği bölgenin sol üst köşebnin
koordinatlarıdır.
Programın Çalışma Zamanı Sırasında Herhangi Bir Icon'ın Görüntülenmesi
LoadIcon fonksiyonu ile
HICON elde edebilmek için icon dosyasının kaynakta belirtilmiş olması gerekir.
Halbuki kaynağa yazılma işlemi programın çalışmasından önce yapılmaktadır. Bir
ico dosyasının ismini vererek hiç kaynakta belirtmeden HICON elde edebilmek
için LoadImage API fonksiyonu kullanılmaktadır. LoadImage şömyle kullanılır:
0 yorum: