| GRAFİK ARABİRİM |
|
|
|
| Yazar Hanzala | |||||||
| Sunday, 26 December 2004 | |||||||
GRAFİK ARABİRİMİ
6.1. Cihaz Ortamları
Windows için yazılan bir programda bütün çıkışlar bir cihaz ortamı kullanılarak yapılmalıdır. Cihaz ortamı Windows Graphıcs Device Interface’in (GDI - Grafik Cihaz Arabirimi) önemli bir parçasıdır. Cihaz ortamları cihazdan bağımsız çıkış, sağlamak için Windows ve uygulamalar tarafından kullanılır.
Bu bölümün konuları kısaca şöyledir :
· Windows’da kullanılan farklı cihaz ortamı tipleri ve onları destekleyen MFC sınıfları,
· Cihaz harita modlarını kullanma,
· Windows uygulamalarınızda GDI nesnelerinin kullanılması,
· Windows’da metin çıkışı için farklı seçeneklerin kullanılması.
Ayrıca metin çıkışlarında bir cihaz ortamının nasıl kullanıldığını gösteren bir örnek program da oluşturacaksınız
6.1.1. Cihaz Ortamı Nedir?
Genelde DC olarak kısaltılan (Device Context) bir cihaz ortamı bir program bir cihaza çıkış vereceğinde gereken bilgileri saklayan ve Windows tarafından idare edilen bir yapıdır. Cihaz ortamı çizim yüzeyi ve onun yetenekleriyle ilgili bilgileri saklar. GDI çıkış fonksiyonlarından herhangi birini kullanabilmek için önce bir cihaz ortamı oluşturmanız gerekir.
Windows’un derinliklerinde bulunan cihaz ortamları, aslında GDI’nın bir pencereye ilişkin o anki çıkış durumunu izlemek için kullandığı yapılardır. Ancak bir cihaz ortamının üyelerine asla teker teker erişemezsiniz; cihaz kontrollerine erişim fonksiyon çağrılarıyla mümkündür.
Cihaz ortamları kullanmanın en basit sebebi gerekli olmalarıdır; bunlar bir Windows programında çıkış almanın başka bir yolu yoktur. Ancak, bir ortamı kullanmak Windows’da mevcut GDI özelliklerinin çoğunu kullanan ilk adımdır. Cihaz ortamlarının nasıl çalıştığını anlamak Windows programlarınızı daha verimli hale getirecektir.
GDI Nesnelerinin Tipleri
Bir GDI nesnesini bir cihaz ortamıyla ilişkilendirmeye yaygın bir GDI nesnesini cihaz ortamına seçmek denir. Bir GDI nesnesi, DC için çizim yetenekleri sağlamak için bir cihaz ortamına seçilebilir. Her GDI nesi farklı tipte bir çıkış oluşturmak için kullanılabilir. Cihaz ortamlarıyla en sık olan GDI nesneleri Tablo 6.l’de listelenmiştir.
Tablo 6.1. Windows Programlarında Sık Kullanılan GDl Nesnelerı
Nesne Amaç
Brush Bölgeleri doldurma Bitmap Resimleri görüntüleme Font Yazıtipi karakteristikleri
Şekil 6.1. Varsayılan GDI nesneleri kümesiyle oluşturulmuş bir cihaz ortamı
Cihaz Ortamı Tipleri
Windows ve MFC sınıf kütüphanesi aşağıdaki dört farklı temel tipte cihaz ortamına sahiptir. Bu cihaz ortamları farklı durumlarda kullanılmasına rağmen bunların kullanımındaki temel kurallar aynıdır.
· Görüntüleme DC’leri, standart bir video terminalinde bilgi görüntülemek için kullanılır. Bunlar bir Windows programında en sık kullanılan cihaz ortamlarıdır.
· Yazıcı DC’leri, bir yazıcı veya çiziciye çıkış göndermede kullanılır.
· Uyumlu cihaz ortamları da denilen bellek DC’leri, bir bitmap üzerinde çizim işlemleri yapmak için kullanılır.
· Bilgi DC’leri, bir cihazda bilgi toplamak için kullanılır. Bu DC’ler küçük ve hızlıdır fakat gerçek çıkış için kullanılamaz.
Donanım Bağımsızlığı
Cihaz ortamları kullanmanın ardındaki amaç Windows için yazılan programlarda donanım bağımsızlığı sağlamaktır. Biraz dikkat ederseniz programınız bir Windows donanım sürücüsünün desteklediği herhangi bir ekran veya yazıcıda çalışabilir.
Windows otomatik olarak destek vermiyorsa yeni çıkış cihazlarının çoğu bir sürücü sağlar. Bunun anlamı, bugün yazdığınız programların henüz geliştirilmemiş görüntü cihazlarıyla da çalışacağıdır. Cihaz ortamlarının Windows için yazılan bir programı gerçek cihaz donanımından ayırması nedeniyle genellikle “çıkış bir cihaz ortamına yazılıyor” denir.
Gerçek donanım bağımsızlığını sağlamak için birkaç önlem almak gerekir:
· Programınızda boyutları sayısal olarak belirtmeyin. Sayısal olarak belirtilmiş boyutlar daha büyük veya küçük ekranlarda ya da yazıcılarda bozulmuş veya eğri görünür.
· Windows’un belli bir çözünürlükteki bir ekranda çalıştığını varsaymayın. Özellikle monitörlerle ilgili varsayımlarda bulunmak kötü bir fikirdir. Birçok kullanıcının sizin düşündüğünüz çözünürlük veya boyutları kullanmadığı kesindir.
· Belli bir renk kümesinin her durumda kullanılabileceğini veya uygun olduğunu düşünmeyin. Örneğin, çalışma arka planının her zaman beyaz renkte olduğunu varsaymayın. Birçok Windows kullanıcısının VGA ekranları simüle eden diz üstü bilgisayarları vardır. Bazı kullanıcılar ise renk düzenini sıklıkla değiştirirler. Kullanılan renklerin seçimi kullanıcıya kalmıştır.
Cihaz ortamları donanım bağımsızlığını sağlamak için gerekli bilgilerin çoğunu sağlar.
Cihaz Ortamları Nasıl Kullanılır?
Visual C++ kullanırken bir cihaz ortamına erişmek için hemen hemen her zaman bir MFC sınıfı kullanmanız gerekir. MFC sınıf kütüphanesi bir Windows programında çıkış görüntülerken işlerinizi kolaylaştıran bir değil, dört farklı görüntüleme cihaz ortamı sınıfı içerir:
· CDC: Bütün cihaz ortamı sınıfları için taban sınıfı,
· CPaintDC: Bir pencere WM_PAINT mesajına karşılık verirken bazı fonksiyonları çağırır,
· CCIientDC: Bir cihaz aracı yalnızca bir pencerenin istemci alanında çıkış için kullanılacağı zaman kullanılır.
· CWindowsDC: Tüm pencereye çizim yapılabileceği zaman kullanılır. Bulardan başka daha MFC cihaz ortamı sınıflan vardır, fakat onlar özelleştirilmiş amaçlar için kullanılır Cihaz Ortamları İçin Sihirbaz Desteği
ClassWizard veya AppWizard’ı kullanarak bir sınıf oluşturduğunuzda, bir cihaz ortamı oluşturan veya kullanan kod genellikle otomatik olarak üretilir. Örneğin, tipik bir görünüm sınıfı için OnDraw fonksiyonu Kod 6.l’de verilmektedir.
Kod 6.1. Tipik Bir OnDraw Fonksiyonu
void CDispIayView::OnDraw(CDC* pDC) { CDocument* pDoc = GetDocument( ); // TODO : Buraya çizim kodu ekle }
OnDraw fonksiyonu için kullanılan cihaz ortamı OnDraw fonksiyonu çağrılmadan önce MEC yapısı tarafından oluşturulur. Her OnDraw fonksiyonunun bir çıkış görüntülemesi gerektiğinden sizin kod yazmanıza gerek kalmadan cihaz ortamı otomatik olarak sizin için oluşturulur.
Bir cihaz ortamına ihtiyaç duyan çoğu fonksiyon OnDraw fonksiyonu gibi hazır olarak bir parametreye sahiptir. Bu sayede MFC kodunuzu yazmayı kolaylaştırır ve aynı zamanda kodunuzu daha güvenli hale getirir.
Bir GDI Nesnesi Seçmek
Cihaz ortamlarını kullanırken en sık yapılan hatalardan biri bir cihaz ortamına bir GDI nesnesi seçerken olur. Bir cihaz ortamı oluşturulurken başlangıçta bir GDI nesneleri kümesine sahiptir.
Yeni bir GDI nesnesi (örneğin, bir bitmap) bir cihaz ortamına seçildiğinde, varsayılan GDI bitmap’i çağıran fonksiyona dönüş değeri olarak aktarılır. Bu dönüş değerinin daha sonra cihaz ortamına döndürülebilmesi için kaydedilmesi gerekir. Kod 6.2 yeni bir bitmap’ı bir cihaz ortamına seçmeli ve seçilen GDI nesnesini fonksiyonun sonunda döndürmeyi göstermektedir.
Kod 6.2. Bir GDI Nesnesi Seçme Ve Saklama.
Cbitmap bmpHello; bmpHello.LoadBitmap( IDB_HELLO ); CBitmap* pbmpOld = dcMem.SelectObject( &bmpHello ); if( pbmpOld != NULL ) { // // Bitmap’ı kullanın // dcMem.SelectObject( pbmpOld ); }
pmbmpOld değerinin NULL olup olmadığının kontrol edildiğine dikkat edin. BelectObject fonksiyon çağrısı başarıyla sonuçlanmazsa orijinal bitmap döndürülmez. Bu durumda orijinal bitmap’i cihaz ortamına döndürmeye gerek olmaz çünkü yeni bir bitmap hiç seçilmemiştir.
Cihaz ortamıyla işiniz bittiğinde orijinal durumuna geri getirmeniz gerekir. Bunu yapmazsanız bir cihaz ortamına seçtiğiniz kaynaklar düzgün olarak serbest bırakılmayabilir ve bu durum programınızın giderek daha fazla GDI nesnesi tüketmesine yol açabilir. Bu tür bir sorun kaynak sızıntısı olarak bilinir ve izlenmesi çok zordur. Orijinal nesneyi daima cihaz ortamına iade etme alışkanlığını edinmek çok daha iyidir.
Stok Nesneleri
Windows’da stok nesneleri (stock objects) olarak bilinen ve yaygın olarak kullanılan GDI nesneleri vardır. Bu nesneleri kullanmak sizin oluşturacağınız nesneleri kullanmaktan daha kolaydır. Bir cihaz ortamına bir stok nesnesi seçmek için SelectStockObject fonksiyonunu kullanın:
HPEN hOldPen = pDC->SelectStockObject(BLACK_PEN);
Stok nesnelerinin kullanıldıktan sonra yok edilmesine gerek olmamasına rağmen, bir stok nesnesini yok etmeye çalışmak zararlı değildir. Stok nesnelerinden birini yok etmeye çalışırsanız Windows bunu görmezden gelecektir.
Cihaz Ortamı Harita Modunu Ayarlama
Bir cihaz ortamı yaratıldığında zaten seçilmiş birçok stok nesnesi vardır. Örneğin, varsayılan kalem BLACK_PEN stok nesnesidir ve varsayılan fırça da NULL_BRUSH stok nesnesidir. Harita modu (map mode) bir cihaz ortamınm o anda kullandığı koordinat sistemidir. Windows’da çizim fonksiyonlarında kullanılan birimlerin büyüklüğünü ve yönünü tanımlamak için harita modları kullanırsınız.
Bir Windows programcısı olarak çeşitli farklı koordinat sistemleri kullanabilirsiniz. Harita modları fiziksel veya mantıksal boyutlar kullanır ve ekranda üstten, aşağıdan ve herhangi bir noktadan başlayabilirler.
Windows’da toplam sekiz farklı harita modu kullanılabilir. GetMapMode fonksiyonunu kullanarak bir cihaz ortamının o anda kullandığı harita modunu öğrenebilir ve SetMapMode fonksiyonunu kullanarak yeni bir harita modu belirleyebilirsiniz. Kullanılabilecek harita modları aşağıda verilmektedir:
MM_ANISOTROPIC: Mantıksal birimleri uygulama tarafından tanımlanan bir değere ölçeklemek için bir görünüm penceresi (viewport) kullanır. Birimleri, yönü ve ölçeklemeyi değiştirmek için SetWindowExt ve SetViewportExt üye fonksiyonları kullanılır.
MM_HIENGLISH: Her mantıksal birim 0.001 inç değerine çevrilir. Pozitif x sağa doğru, pozitif y yukarı doğrudur.
MM_HIMETRIC: Her mantıksal birim 0.01 milimetre değerine çevrilir. Pozitif x sağa doğru, pozitif y yukarı doğrudur.
MM_ISOTROPIC: Mantıksal birimlerin eşit ölçeklenmiş eksenli keyfi birimlere çevrildiği MM_ ANISOTROPIC moduna benzer, yani x-ekseni üzerindeki bir birim daima y-ekseni üzerindeki bir birime eşittir. Eksenlerin birimlerini ve yönünü belirtmek için SetWindowExt ve SetViewportExt üye fonksiyonlarını kullanın.
MM_LOENGLISH: Her mantıksal birim 0.01 inç değerine çevrilir. Pozitif x sağa doğru, pozitif y yukarı doğrudur.
MM_LOMETRIC: Her mantıksal birim 0.1 milimetre değerine çevrilir. Pozitif x sağa doğru, pozitif y yukarı doğrudur.
MM_TEXT: Her mantıksal birim bir cihaz pikseline çevrilir. Pozitif x sağa doğru, pozitif y aşağı doğrudur.
MM_TWIPS: Her mantıksal birim bir puntonun l / 20’sine eşittir. Bir punto bir inçin 1 / 72’sine eşit olduğundan bir twip 1 / 1440 inçtir. Bu harita modu yazıcıya çıktı gönderirken kullanışlıdır. Pozitif x sağa doğru, pozitif y yukarı doğrudur.
6.1.2. Bir Cihaz Ortamı Örneği
Cihaz ortamlarının nasıl kııllanılabileceğiyle ilgili bazı temel kavramlarını görmek için DCTest adında örnek bir SDI programı oluşturacaksınız. GDI örnekleri için yazılması gereken kod miktarını azaltmak amacıyla DCTest programı “İkonlar ve İmleçler’ adlı bölümde kullanılacaktır.
DCTest; o anki cihaz ortamı, harita modu ve varsayılan yazıtipi hakkında bilgi görüntüleyecek bir SDI programıdır. Bir iletişim kutusu kullanarak görünümün harita modunu değiştirmek mümkün olacaktır.
DCTest örneğini oluşturmaya başlamak için MFC AppWizard’ı kullanarak DCTest adında bir SDI programı oluşturun. AppWizard’ın önerdiği seçeneklerden istediklerinizi seçebilirsiniz çünkü bunların hiçbiri örnek projeyi etkilemeyecektir.
Map Mode İletişim Kutusunu Değiştirmek
IDD_MAP_MODE iletişim kutusundaki bileşik kutuyu o anki harita modunu izlemek amacıyla kullanılabilecek şekilde değiştirin. Bileşik kutu kontrolünün içeriğini değiştirmek için özellik iletişim kutusundan Data sekmesini seçebilirsiniz. Bu bileşik kutu sabit bir liste içerdiğinden bunları kaynak editörüne eklemek OnInitDialog fonksiyonuna gerekli kodu eklemekten daha kolaydır. Aşağıdaki listedeki maddeleri bileşik kutuya ekleyin:
MM_ANISOTROPIC
MM_HIENGLISH
MM_HIMETRIC
MM_ISOTROPIC
MM_LOENGLISH
MM_LOMETRIC
MM_TEXT
MM_TWİPS
Bir Menü Maddesi Eklemek
View menüsüne bir madde ve CDCTestView sınıfına bir mesaj-yönetimi fonksiyonu eklemek için Tablo 6.2’deki değerleri kullanın. CDCTestView sınıfı bu menü seçimini yönetecektir.
Tablo 6.3. CDCTestview Sınıfı İçin Yeni Üye Fonksiyonları
Menü ID Başlık Olay Fonksiyon Adı
ID_VIEW_MAP_MODE &Map Mode... COMMAND OnViewMapMode
Kod 6.3, yeni menü maddesi seçildiğinde gönderilen mesajı yöneten OnViewMapMode fonksiyonunun kaynak kodunu içermektedir. OK düğmesine tıklanırsa bileşik kutunun içerdiği değere bağlı olarak yeni harita modu hesaplanır. Görünüm dikdörtgeni geçersizleştirilir ve görünüm tekrardan çizilir.
Kod 6.3. CDcTestView::OnViewMapMode Fonksiyonu
Void CDCTestView::OnViewMapMode( ) { CMapModeDlg dlg; if( dlg.DoModaI( ) = = IDOK) { POSITION pos; pos = m_map.GetStartPosition( ); while( pos !=NULL) { CString szMapMode; int nMapMode; m_map.GetNextAssoc(pos,nMapMode,szMapMode); if(szMapMode = = dlg.mszCombo) { m_nMapMode = nMapMode; break; } } InvalidateRect( NULL ); } }
CDCTestView sınıfının CMapModeDlg sınıf bildirimine erişebilmesi için DCTestView.cpp dosyasına bir #include deyimi ekleyin. DCTestView.cpp dosyasında diğer #include deyimlerinin altına aşağıdaki satırı ekleyin:
#include “MapModeDIg.h”
Bir Cihaz Ortamından Bilgi Toplama
CDG sınıfı bilgi toplamak için yaygın olarak kullanılan iki üye fonksiyona sahiptir:
· Bir cihaz ortamıyla ilişkili fiziksel cihaz hakkında bilgi almak için kullanılan GetDeviceCaps
· O anda seçili yazıtipi ile ilgili bilgi almak için kullanılan GetTextMetrics
GetDeviceCaps Fonksiyonunu Kullanmak
GetDeviceCaps fonksiyonunu kullanmanın bir amacı cihaz ortamıyla ilişkili cihaz için mantıksal inç başına düşen piksel sayısını belirlemektir. Yatay yöndeki (x eksenindeki) mantıksal inç başına düşen piksel sayısını öğrenmek için CetDeviceCaps fonksiyonunu çağırın ve parametre olarak LOGPIXELSX indeks değerini gönderin.
int cxLog = pDC->CetDeviceCaps( LOGPIXELSX );
Daha sonra “CDCTstView Sınıfını Değiştirmek” adlı kısımda bu bilgiyi DCTest örneğinde görüntülemek için GetDeviceCaps fonksiyonunu kullanacaksınız.
GetDeviceCaps fonksiyonu temel olarak yazdırma işlemleri sırasında kullanılır; yazıcının belli GDI fonksiyonlarını destekleyip desteklemediğini öğrenmek için bu fonksiyonu kullanabilirsiniz. Daha ileriki bölümlerde bir yazıcıya bitmap aktarılıp aktarılamayacağını belirlemek için GetDeviceCaps fonksiyonunun nasıl kullanıldığını göreceksiniz.
GetTextMetrics Fonksiyonunu Kullanmak
GetTextMetrics fonksiyonu bir TEXTMETRIC yapısını bilgiyle doldurmak için kullanılır:
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm)
TEXTMETRIC yapısı, o anda seçili yazıtipi hakkında bilgi içeren birçok üye değişkene sahiptir. TEXTMETRIC yapısının en sık kullanılan üyeleri Tablo 6.4’te verilmektedir.
Tablo 6.4. TextMetric Yapısının Sık Kullanılan Üye Değişkenleri
Üye Açıklama
tmAscent Mevcut yazı tipinin satır çizgisinin üstünde kalan kısmının boyutunu belirler.
tmDescent Mevcut yazı tipinin satır çizgisinin altında kalan kısmının boyutunu belirler.
tmHeight Mevcut yazı tipinin toplam yüksekliğini belirler. Bu değer tmAscent ve tmDescent değerlerinin toplamına eşittir.
tmInternalLeading Yazıtipi ile ilişkili özel işaretler için ayrılan alanı belirler. Bu alan tmAscent alanının içindedir.
tmExternalLeading Metin satırları arası boşluğunu belirler. Bu alan tmAscent alanının dışındadır.
tmAveCharWidth Mevcut seçili yazı tipinin kalın olmayan ve italik olmayan karakterlerinin ortalama genişliğini belirler.
O anda seçili yazıtipinin yüksekliğini öğrenmek için GetTextMetrics fonksiyonunu çağırın ve tmHeight üye değişkeninde saklanan değeri kullanın :
TEXTMETRIC tm; pDC->GetTextMetrics(&tm); nFontHeight = tm.tmHeight;
CDCTestView Sınıfını Değiştirmek
O anki harita moduyla ilgili bilgi görüntülemek için önce şablon grubu sınıflarından olan CMap sınıfına dayalı bir grup oluşturmanız gerekir. CMap değişkeni m_map bir tamsayı harita modu değerini harita modunu tanımlayan bir CString nesnesiyle ilişkilendirir. Kod 6.4’te gösterildiği gibi CDCTestView sınıf bildiriminde Attributes kısmına iki yeni değişken ekleyin.
Şekil 6.3. DCtest örneğini çalıştırma
Kod 6.4. CDCTestView Sınıf Bildirimine Eklenen Yeni Üye Değişkenler
// Özellikler private: Cmap < int, int, CString, CString > m_map; int m_nMapMode;
Bir projede MFC grup sınıflarından birini kullanırken proje dizinindeki stdfx.h dosyasına #include “afxtempl.h” deyimini mutlaka eklemeniz gerekir. Bu include deyimi, MFC şablon bildirimlerini projenin önceden derlenmiş başlık dosyasına ekleyerek projenin derlenme süresini kısaltır.
|
|||||||
| < Önceki | Sonraki > |
|---|















