çizim işleminin bileşenleri

2 Temmuz 2013 Salı Unknown 0 yorum

Ç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

 Icon İşlemleri

            .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: