hoSSohbeT.com  Sohbet  forumlari

Anasayfa Bugünki Mesajlar Forumları Okundu Kabul Et
Geri git   hoSSohbeT.com Sohbet forumlari > Bilgisayar ve İnternet Dünyası > Bilgisayar - İnternet > Bilgisayar Dünyası > Programlama > C ve C++
Kayıt ol Yardım Sohbet Gazete oku Diyetsaglik Üye Listesi Ajanda Arama Bugünki Mesajlar Forumları Okundu Kabul Et



Cevapla
 
LinkBack Seçenekler Stil
Alt 04-09-08, 17:37   #1
Dokunma Yanarsın
 
aLayıNaiSyaN - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: 04-02-08
Nerden: . . .
Mesajlar: 1,981
Tecrübe Puanı: 496 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000
C++ Mesajlar ve MFC Mimarisi

MESAJLAR ve MFC MİMARİSİ



Mesajlar, bütün Windows programlarının merkezini oluşturur. Windows işletim sisteminin nasıl mesaj gönderdiğini anlamanız kendi programlarınızı yazarken size çok yardımcı olacaktır.

Bu bölümde öğreneceğiniz konular şunlar:


· Windows uygulamalarının işletim sistemiyle ve uygulamadaki nesnelerle iletişim kurmak için mesajları nasıl kullandığı,

· MFC yapısı kullanılarak mesajların nasıl yönetildiği,

· Her MFC uygulamasında kullanılan MFC taban sınıfları.

Ayrıca bu bölümde Windows işletim sisteminin uygulamalara mesajları nasıl aktardığını öğrenmek için basit bit örnek program da oluşturacaksınız.

5.1. Windows Programlama Modeli

Windows için yazılan programlar konsol-modu (consol-mode) programların ço­ğundan farklıdır. Daha önceden oluşturduğunuz konsol modu programlar, konsol-­modu bir pencerede tam hakimiyete sahip küçük ardışıl programlardı.

Ardışıl programlar (sequential programs) C++ dilinin temelleri gibi basit kav­ramları açıklamaya yetseler de Microsoft Windows gibi çok görevli bir ortamda pek işe yaramazlar. Windows ortamında her şey paylaşılır: ekran, klavye, fare (hatta kullanıcı bile). Windows için yazılan programlar Windows ile ve aynı anda çalışıyor olabilecek diğer programlarla işbirliğinde bulunmalıdır.

Windows gibi diğer programlarla birlikte çalışılan bir ortamda, programı etkileyen bir olay olduğunda programa mesajlar gönderilir. Bir programa gönderilen her mesajın belli bir amacı vardır. Örneğin, bir program başlatılması gerektiğinde, menü seçimleri yapıldığında ve bir pencerenin tekrar çizilmesi gerektiğinde me­sajlar gönderilir. Olay mesajlarına karşılık vermek çoğu Windows programının a­nahtar kısmıdır.

Windows programlarının bir başka özelliği kaynakları paylaşmak zorunda olmala­rıdır. Birçok kaynak kullanılmadan önce işletim sisteminden istenmelidir ve kulla­nıldıktan sonra diğer programların da kullanabilmesi için işletim sistemine geri ve­rilmelidir. Windows kontrollerinin ekran ve diğer fiziksel cihazlara erişim için kullandığı bir yol budur.

Kısaca, bir pencerede çalışan bir program iyi bir vatandaş olmalıdır. Çalıştığı bilgisayar üzerinde tam hakimiyete sahip olduğunu düşünmemelidir; herhangi merkezi bir kaynağı kullanmaya başlamadan önce izin almalı ve gönderilen mesajlara tepki vermeye hazır olmalıdır.

Mesaj Nedir?

Microsoft Windows için yazılan programlar bir programın ana penceresine gön­derilen olaylara tepki verirler. Olaylara örnek olarak fare işaretçisini hareket ettir­mek, bir düğmeye tıklamak veya bir tuşa basmak denilebilir. Bu olaylar pencereye mesajlar biçiminde gönderilir. Her mesajın belli bir amacı vardır: pencereyi yeni­den çizmek, pencerenin büyüklüğünü değiştirmek, pencereyi kapatmak gibi.

Varsayılan pencere prosedürü, Windows’un sunduğu ve özel bir işlem gerekmiyorsa mesajı yöneten özel bir mesaj yönetimi fonksiyonudur. Uygulama birçok mesajı varsayılan pencere prosedürüne gönderebilir.

Bir Windows programı ayrıca diğer pencerelere de mesajlar gönderebilir. Bir Windows programında kullanılan her kontrol bir pencere olduğundan kontrol­lerle iletişim kurmak için de çoğu zaman mesajlar kullanılır.

Bir Windows programında iki tip mesaj yönetilir:

· İşletim sistemi tarafından gönderilen mesajlar,

· Kullanıcı girişleriyle ilgili kontrollere gönderilen ve bunlardan alınan me­sajlar.

İşletim sisteminden gönderilen mesajlar, programa başlayıp sonlanmasını söyle­mek veya bir pencereye büyüklüğünün değiştirildiğini ya da taşındığını söylemek için kullanılır. Kontrollere gönderilen mesajlar bir pencerenin kullandığı yazıtipini veya pencerenin başlığını değiştirmek için kullanılabilir. Bir kontrolden alınan me­sajlar, bir düğmeye basıldığını veya bir düzenleme kontrolüne bir karakter girildi­ğini bildiren mesajlardır.

Windows programlarında mesajların bu kadar yoğun olarak kullanılmasının iki sebebi vardır:

· Bir fonksiyon çağrısından farklı olarak mesajlar fiziksel veri kümeleridir, bu nedenle kolaylıkla sıraya sokulabilir ve önceliğe sahip olabilirler.

· Mesajlar belli bir dile veya işlemci tipine bağlı değildir, bu nedenle mesaj tabanlı bir program kolaylıkla Windows NT’de yapıldığı gibi başka CPU’lara taşınabilir.

Olay güdümlü programlamada kuyruklar çok işe yarar. Bir olay olduğunda bir mesaj oluşturulup uygun pencere veya program için kuyruğa sokulabilir. Kuyruğa so­kulan her mesajla sırayla ilgilenilebilir.

Mesajların dilden bağımsız olması Windows’un yıllardır büyümesini sağlamıştır. Günümüzde Visual Basic, Delphi, Visual C++ veya PowerBuilder gibi çok çeşitli diller kullanarak Windows programları yazabilirsiniz. Mesajlar dilden bağımsız ol­duğundan bu programlar arasında kolaylıkla gönderilebilirler. Mesaj arabirimi yazdığınız programlara yeni özellikler eklemenize ve Windows’un gelecekte de büyümesine yardımcı olur.

Microsoft Windows gibi olay güdümlü bir programlama modeli kullanırken mesaj sırasından her zaman emin olmalısınız. Farklı kullanıcıların bir programı kullanmalarındaki ufak bir farklılık mesajların farklı bir sırada a­lınmasına neden olabilir. Bu nedenle bir olayı yönetirken yalnızca o söz konusu olayla ilgilenmeli, başka bir olayın da olduğunu varsaymamalısınız.

Fare Tıklamalarını Test Etmek İçin Bir Program

Uygulamanıza olayları bildirmek için mesajların nasıl kullanıldığını gösteren örnek bir program oluşturmak üzeresiniz. MouseTst adlı bu program, fare istemci alan i­çinde bir yere tıklandığında bir mesaj görüntüleyecektir. MouseTst programını oluşturmak için ilk adım bir SDI uygulaması oluşturmak için AppWizard’ı kullanmaktır. AppWizard’ın önerdiği seçeneklerden istediklerinizi seçebilir veya çıkartabilirsiniz, çünkü bu özelliklerin gösteriye bir etkisi yoktur.


Mesaj Kuyruğu Nedir?

Mesajlar, olay alması gereken tüm pencerelere gönderilir. Örneğin, fare işaretçisi­nin bir Windows programının ana penceresi üzerinde hareket ettirilmesi çok sayı­da mesaj üretir. Bir pencereye gönderilen mesajlar bir kuyruğa yerleştirilir ve bir programın sırayla her mesajı incelemesi gerekir.

Mesajlar Nasıl Yönetilir?

Kullanıcı fareyi bir programın ana penceresi üzerinde hareket ettirdiğinde prog­ramın pencere prosedürüne iki mesaj gönderilir:

1. Fare menü veya başlık çubuğu üzerinde hareket ettirildiğinde WM_NCMOUSEMOVE mesajı gönderilir.

2. Fare pencerenin istemci alanının üzerindeyken WM_MOUSEMOVE mesajı
gönderilir.

Bir başka fare mesajı türü, birincil fare düğmesine basıldığında gönderilen WM_LBUTTONDOWN mesajıdır. Bu çoğu kullanıcı için farenin sol düğmesi oldu­ğundan mesajın adı WM_LBUTTONDOWN’dır. Genellikle sağ düğme olan ikincil düğmeye tıklandığında WM_RBUTTONDOWN mesajı gönderilir.

Bu ve diğer mesajlar bir pencerenin pencere prosedürüne gönderilir. Bir pencere prosedürü mesajı aldığında mesajla birlikte aktarılan parametreler mesajın nasıl yönetilmesi gerektiğine karar vermede yardımcı olur.




5.1.1. Mesajları ClassWizard İle Yönetmek

MFC ClassWizard adı da verilen ClassWizard belli bir mesaj yönetimi fonksiyonu için kullanılan kodu ekler. Genelde tekrar kullanılabilen bu kod hataların daha da azalmasına yardımcı olabilir çünkü bu kod kesinlikle hatasızdır. Kod 5.1 WM_LBUTTONDOWN mesajını yönetmek için ClassWizard tarafından oluşturulan bir fonksiyon örneğidir.

Kod 5.1. ClassWizard Tarafından Oluşturulan OnLButtonDown
Fonksiyon

void CMyView::OnLButtonDown(UINT rıFlags, CPoint point)
{
// TODO: Mesaj taşıyıcı kodu buraya ekleyin ve/veya varsayılanı çağırın.
CView::OnLButtonDown(nFIags, point);
}

Mesaj haritası, bir programa gönderilen mesajları o mesajları yönetme­si gereken fonksiyonlara bağlar. AppWizard veya ClassWizard bir mesaj yönetimi fonksiyonu eklediğinde sınıfın mesaj haritasına bir giriş eklenir. Kod 5.2 bir mesaj haritası örneği göstermektedir.
__________________
aLL Hope iS Gone

aLayıNaiSyaN isimli Üye şimdilik offline konumundadır  
Digg this Post!Bookmark Post in Technorati
Alıntı ile Cevapla
Alt 04-09-08, 17:37   #2
Dokunma Yanarsın
 
aLayıNaiSyaN - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: 04-02-08
Nerden: . . .
Mesajlar: 1,981
Tecrübe Puanı: 496 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000
Cevap: C++ Mesajlar ve MFC Mimarisi

Kod 5.2. CMyView Sınıfı İçin Bir Mesaj Haritası

BEGIN_MESSAGE_MAP(CMyView,CView)
// {{AFX_MSG_MAP(CMyView)
ON_WM_LBUTTONDOWN( )
// }}AFX_MSG_MAP
// Standart yazdırma komutları
ON_COMMAND(ID_FILE_PRINT,Cview::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,Cview::OnFilePrint )
ON_COMMAND(ID_FILE_PRINT_PREVİEW,CView::OnFilePrin tpreview)
END_MESSAGEMAP( )

Mesaj haritası BEGIN_MESSAGE_MAP makrosuyla başlar ve D_MESSAGE_MAP makrosuyla biter. ClassWizard’ın kullanması için ayrılan satırlar //{{AFX_MSG MAP ile başlar ve //}}AFX MSG_MAP ile biter. Mesaj haritasında siz elle bir değişiklik yaparsanız ClassWizard için ayrılan girişleri değiştirmeyin, bunlar otomatik olarak düzenlenir.

MouseTst Tarafından Yönetilen Mesajlar

MouseTst programı fare olaylarını sezmek ıçin kullanılan dört mesajı yönetmeli­dir. MouseTst’in kullandığı mesajlar Tablo 5.l’de gösterilmektedir.




Tablo 5.1. MouseTst Tarafından Yönetilen Mesajlar

Mesaj Fonksiyon Tanımı


WM_LBUTTONDOWN OnLButtonDown Farenin sol tuşu tıklandı

WM_LBUTTONDBLCLK OnLButtonDblClk Farenin sol tuşu çift
tıklandı

WM_RBUTTONDOWN OnRButtonDown Farenin sağ tuşu
tıklandı

WM_RBUTTONDBLCLK OnRButtonDblClk Farenin sağ tuşu çift
tıklandı

Ayrıca WM_PAINT mesajı alındığında MFC yapısı OnDraw üye fonksiyonunu çağırır. MouseTst görüntüyü o anki fare konumu ve son mesajla güncellemek için On Draw fonksiyonunu kullanacaktır.

MouseTst View Sınıfını Güncelleme

Fare olaylarını yöneten tüm kod CMouseTstView sınıfında gerçeklenecektir. Mou­seTst programında fare olaylarıyla ilgili bilgi görüntülemek için iki adım vardır:

1. Dört fare olayından biri olduğunda olay tipi ve farenin konumu kaydedilir ve görünümün çerçevesi geçersiz hale getirilir. Bu durumda Windows WM_PAINT mesajını üretir ve MouseTst uygulamasına gönderilir.

2. MouseTst WM_PAINT mesajını aldığında CMouseTstView::OnDraw üye fonksiyonu çağrılır ve fare olayı ile konumu görüntülenir.

Bütün işlemler WM_PAINT mesajına karşılık olarak yapılır. WM_PAINT mesajı bir pencerenin istemci alanı geçersiz hale geldiğinde gönderilir. Bu genellikle pencerenin üzerinin kaplanması veya pencerenin tekrar açılması nedeniyle olur. WM_PAINT mesajına karşılık olarak pencerenin tekrar çi­zilmesi gerektiğinden Windows için yazılan programların çoğu tüm çizim işlemlerini WM_PAINT mesajına karşılık olarak yapar ve pencerenin güncellenmesi gerektiğinde pencereyi geçersizleştirirler.

Fare olayını ve konumunu izlemek için CMousTstView sınıfına iki üye değişken eklemeniz gerekir. MouseTstView.h dosyasında kapatma küme parantezinden önce son üç satır olarak Kod 5.3’deki üç satırı ekleyin.

Kod 5.3. CMouseTstView Sınıfı İçin Yeni Üye Değişkenleri


private:
CPoint m_ptMouse;
CString m_szDescription;

Mesaj Yönetim Fonksiyonları Eklemek

MouseTst programında yönettiğiniz dört fare olayı için ClassWizard’ı kullanarak mesaj yönetim fonksiyonları ekleyin. Ctrl+W tuşlarına basarak veya kaynak kod penceresinde farenin sağ tuşuyla tıklayıp menüden Classwizard’ı seçerek Class­Wizard’ı açın. Classwizard göründükten sonra şu adımları izleyin:

1. Object ID liste kutusundan CMouseTstView sınıfını seçin; Message liste kutusunda CmouseTstView sınıfına gönderilen mesajların listesi görünür.

2. Message liste kutusundan WM_RBUTTONDOWN mesajını seçin ve Add Function düğmesine tıklayın.

3. ClassWizard’ı kapatmak için OK düğmesine tıklayın.

Kod 5.4’deki her mesaj yönetim fonksiyonu farenin konumunun ve olayı tanımlayan bir yazıyı saklar.


Kod 5.4. CMouseTstView İçin Dört Fare Yönetimi Fonksiyonu


void CMouseTstView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
m_ptMouse = point;
m_szDescription = “Left Button Double Click”;
InvalidateRect( NULL );
}
void CMouseTstView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptMouse = point;
m_szDescription = “Left Button Down”;
invalidateRect( NULL );
}
void CMouseTstView::OnRButtonDbldlk(UINT nFlags, CPoint point)
{
m_ptMouse = point;
m_szDescription = “Right Button Double Click”;
InvaidateRect( NULL );
}
void CMouseTstView::OnRButtonDown(UINT nFlags, CPoint point)
{
m_ptMouse = point;
m_szDescription = “Right Button Down”;
InvalidateRect( NULL );
}

Olayı MouseTst Programında Görüntüleme

Bir sonraki adım, olayı götüntülemek için CMouseTstView::OnDraw fonksiyonunu kullanmaktır. CMouseTstView::OnDraw fonksiyonunu Kod 5.5’de gösterildiği gibi değiştirin. AppWizard’ın eklemiş olduğu kod satırlarını çıkartın.


Kod 5.5. CMouseTstView İçin OnDraw Üye Fonksiyonu



void CMouseTstView::OnDraw(CDC* pDd)
{
pDC->TextOut( m_ptMotıse.x, m_ptMouse.y, m_szDescription );
}



Şekil 5.1. Bir fare olayını gösteren MouseTst programı

5.1.2. MFC Taban Sınıfları Nelerdir?

MFC sınıf kütüphanesi Windows programcılığına uygun çok sayıda sınıf içerir. Bu sınıfların birçoğu MFC sınıf hiyerarşisinin kökünde yer alan CObject sınıfından tü­retilmiştir. Ayrıca, bir pencere veya kontrolü temsil eden herhangi bir sınıf, tüm pencerelerde ortak olan temel fonksiyonları yöneten CWnd sınıfından türetilmiştir.

CObject ve CWnd sınıfları, programınızın bir taban işaretçisi aracılığıyla genel amaçlı fonksiyonlara erişmesine olanak tanıyan sanal fonksiyonlar kullanırlar. Bu sayede MFC yapısıyla etkileşimde bulunurken CObject veya CWnd sınıfla­rından türetilmiş herhangi bir nesneyi kolaylıkla kullanabilirsiniz.

CObject Taban Sınıfı

Bir MFC programında kullanılan hemen hemen her sınıf CObject sınıfından türetilmiştir. CObject sınıfı dört tip hizmet sunar:

1. Teşhis amaçlı bellek yönetimi bellek yetersizliği durumunda teşhise yöne­lik mesajlar verir. Bu yetersizlikler genelde dinamik olarak oluşturulmuş nesnelerin serbest bırakılmamasından kaynaklanır.

2. Dinamik oluşturma desteği nesnelerin programın yürütülmesi sırasında oluşturulmasına olanak sağlayan CRuntimeClass sınıfını kullanır. Bu, new operatörünü kullanarak dinamik olarak nesne oluşturmaktan farklıdır.

3. Serileştirme desteği bir nesnenin nesne yönelimli programlamaya uygun biçimde saklanmasına ve yüklenmesine olanak sağlar. Serileştirme daha sonra “Program Verilerini Saklamak İçin MFC’nin Kullanılması” adlı bölümde ele alınmaktadır.


4. MFC sınıf kütüphanesi, programınızda hatalar keşfedildiğinde size teşhise yönelik bilgi sunmak için yürütme-zamanı (runtime) sınıf bilgilerini kullanır. Yürütme zamanı sınıf bilgileri ayrıca nesneleri serileştirirken de kullanılır.

CWnd Taban Sınıfı

CWnd sınıfı CObject sınıfından türetilmiştir ve bir MFC programına tüm pencere­lerin paylaştığı büyük bir işlevsellik katar. Bu aynı zamanda özelleştirilmiş pencere tipleri olan iletişim kutularını ve kontrolleri içerir. Şekil 5.2 CWnd sınıfından türe­tilmiş bazı önemli MFC sınıflarını göstermektedir.




CWnd

CView

CSplitterWnd




CDialog

CFrameWnd

CContolBar

CpropertySheet

ControlClasses







Şekil 5.2. CWnd sınıfından türetilmiş önemli MFC sınıfları

Bir MFC programındaki hemen hemen her nesne bir CObject nesnesidir. Bu sa­yede birçok bellek yetersizliği sorununun ve diğer programlama hatalarının sebe­bini bulmak için MFC desteğinden faydalanabilirsiniz. CObject sınıfı aynı zaman­da yürütme-zamanında teşhise yönelik mesajlar ve serileştirme desteği sağlamak i­çin kullanılabilir. Bir MFC programındaki her pencere bir CWnd nesnesidir. CWnd sınıfı CObject sınıfından türetildiğinden CObject’in bütün işlevselliğini içerir. Programınızdaki tüm pencere ve kontrolleri yönetmek için CWnd sınıfını kullanmak polymorphism’den yararlanmanıza olanak sağlar; CWnd sınıfı bütün pencere tipleri için genel pencere fonksiyonlarını içerir.

5.1.3. CObject ve CWnd Taban Sınıflarını Kullanan Bir Örnek

CObject ve CWnd sınıfları farklı şekillerde kullanılır. CObject sınıfı normalde kendi sınıflarınızı oluştururken taban sınıf olarak kullanılır. CWnd sınıfı çoğunlukla bir fonksiyon parametresi olarak aktarılır veya bir değer olarak döndürülür ve bir MFC programında herhangi tipte bir pencereye işaretçi olarak kullanılır.

Bu kısımda CObject sınıfının nasıl kullanıldığını gösteren basit bir konsol-modu program oluşturacaksınız. Örneğe başlamak için Runtime adlı yeni bir konsol-modu program oluşturun. Sibirbaz ekranı oluşturulacak konsol-modu uygulamanın tipini sor­duğunda An Application That Supports MFC seçeneğini seçin.

CObject’i Taban Sınıf Olarak Kullanmak

CObject sınıfı her zaman taban sınıf olarak kullanılır; sade bir CObject nesnesiyle pek bir şey yapılamaz. Taban sınıf olarak kullanıldığında CObject sınıfı bir sınıfa büyük bir işlevsellik katar. Türetilen sınıfın bildiriminde ve tanım dosyalarında makrolar kullanarak Cobject’in sunduğu işlevsellik miktarını kontrol edebilirsiniz. CObject sınıfından türetilen sınıflara dört farklı seviyede destek sunulur:

· Bellek yetersizliklerini sezen temel destek makro gerektirmez.

· Yürütme-zamanı sınıf belirleme desteği, sınıf bildiriminde DE­CLARE_DYNAMIC makrosunun ve sınıfın gerçeklenmesinde IMPLE­MENT_DYNAMIC makrosunun kullanılmasını gerektirir.

· Dinamik nesne yaratma desteği, sınıf bildiriminde DECLARE_DYNCREATE makrosunun ve sınıf tanımında IMPLEMENT_DYNCREATE makrosunun kullanımını gerektirir.

· Serileştirme desteği, sınıf bildiriminde DECLARE_SERIAL makrosunun ve sınıf tanımında IMPLEMENT_SERIAL makrosunun kullanımını gerektirir.

· Her CObject makrosu benzer biçimde kullanılır. Bütün DECLARE makrolarının tek bir parametresi vardır (sınıfın ismi). IMPLEMENT makroları genelde iki parametre­ye sahiptir (sınıfın ismi ve taban sınıfın ismi). Kod 5.6, CObject sınıfından türetilmiş basit bir sınıf olan CMyObject’in sınıf bildi­rimidir. CMyObject sınıfı dinamik yaratmayı desteklediğinden DECLARE_DYNCREATE makrosunu içermektedir.

Kod 5.6. CObject Sınıfını Taban Olarak Kullanan CMyObject Sınıf

Bildirimi


class CMyObject : public CObject
{
DECLARE_DYNCREATE( CMyObject);
// Yapılandırıcılar
public:
CmyObiect( );
// Özellikler
public:
void Set( const Cstring& szName );
CString Get( ) const;
// Uygulama
private:
CString m_szName;
} ;

Kod 5.6’dakı kaynak kodu Runtime proje dizininde MyObj.h adıyla kaydedın. Bu sadece bir başlık dosyasıdır, bu nedenle projeye dahil etmeyin. CMyObject üye fonksiyonlarının kaynak kodu Kod 5.7’de verilmektedir. Bu kodu MyObj.cpp olarak kaydedin ve Runtime projesine dahil edin. Bu kaynak kod, sınıf bildirimindeki DECLARE_DYNCREATE makrosuyla eşleşen IMPLEMENT_DYNCREATE makrosunu içerir.

Kod 5.7. CMyObject Sınıfı İçin Üye Fonksiyonları

#include “stdafx.h”
#include “MyObj.h”
IMPLEMENT_DYNCREATE( CMyObject, CObject );
CMyObject::CMyObject( )
{
{
void CMyObject::Set( const CString& . szName )
{
m_szName = szName;
}
Cstring CMyObject:et( ) const
}
return m_szName;
}

DECLARE ve IMPLEMENT makrolarının iki farklı yerde kullanıldığını unutmayın. DECLARE_DYNCREATE gibi bir DECLARE makrosu sınıf bildi­riminde kullanılır. IMPLEMENT DYNCREATE gibi bir IMPLEMENT makrosu yalnızca sınıf tanımında kullanılır.
aLayıNaiSyaN isimli Üye şimdilik offline konumundadır  
Digg this Post!Bookmark Post in Technorati
Alıntı ile Cevapla
Alt 04-09-08, 17:38   #3
Dokunma Yanarsın
 
aLayıNaiSyaN - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: 04-02-08
Nerden: . . .
Mesajlar: 1,981
Tecrübe Puanı: 496 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000
Cevap: C++ Mesajlar ve MFC Mimarisi

Yürütme Sırasında Bir Nesne Oluşturmak


Dinamik olarak nesne oluşturmanın iki yolu vardır. İlk yöntem dinamik olarak bir nesne tahsis etmek için C++’taki new operatörünü kullanır.

CMyObject* pObject = new CMyObject;


İkinci yöntem temel olarak MFC yapısı tarafından kullanılır ve CRuntimeClass adlı özel bir sınıfı ve RUNTIME_CLASS makrosunu kullanır. Bir nesnenin tipini belir­lemek veya yeni bir nesne oluşturmak için CRuntimeClass sınıfını kullanabilirsiniz.

5.2. Doküman / Görünüm Mimarisi

Bu bölümde öğreneceğiniz konular :

· MFC sınıf kütüphanesinin ve AppWizard ile ClassWizard gibi araçların sunduğu Doküman / Görünüm desteği,

· Doküman / Görünüm mimarisini gerçeklemek için kullanılan MFC sınıfları,

· İşaretçiler ve referanslar kullanmayı ve bunların Doküman / görünüm mimarisindeki rolü.

5.2.1. Doküman / Görünüm Mimarisi için VisuaI C++ Desteği

MFC ve AppWızard Wındows için yazılan programları düzenlemek için Doküman / Görünüm mimarisini kullanır. Doküman / Görünüm programları dört ayrı sınıfa ayırır:

· CDocument sınıfından türetilmiş bir doküman sınıfı

· CView sınıfından türetilmiş bir görünüm sınıfı

· CFrameWnd sınıfından türetilmiş bir çerçeve sınıfı

· CWinApp sınıfından türetilmiş bir uygulama sınıfı

Bu sınıflardan her birinin bir MFC Doküman / Görünüm uygulamasında belli bir rolü vardır. Doküman sınıfı programın verilerinden sorumludur. Görünüm sınıfı doküman ile kullanıcı arasında etkileşimi yönetir. Çerçeve sınıfı görünüm, menü ve araç çubukları gibi kullanıcı arabirimi öğelerini içerir. Uygulama sınıfı, programı başlatmadan ve Windows ile bazı genel amaçlı etkileşim işlerini yönetmekten sorumludur.

Doküman / Görünüm adı sizi yalnızca kelime işlemci uygulamalarıyla sınırlıyor gibi görünse de bu mimari çeşitli türdeki programlarda kullanılabilir. CDocument tarafından yönetilen veri üzerinde herhangi bir kısıtlama yoktur; bu veri bir kelime işlemci dosyası, bir çizelge veya bir ağ bağlantısının öbür ucundan bilgisayarınıza veri sağlayan bir bilgisayar olabilir. Benzer biçimde çok çeşitli görünüm türleri vardır.

Bir görünüm, basit SDI uygulamalarında kullanıldığı gibi basit bir görünüm olabilir veya bir iletişim kutusunun tüm yeteneklerine sahip CFormView sınıfından türetilmiş olabilir.

SDI ve MDI Uygulamaları

İki temel Doküman / Görünüm program tipi vardır:

· SDI (Single Document Interface - Tek Dokümanlı Arabirim)

· MDI (Multiple Document Interface - Çok Dokümanlı Arabirim)

Bir SDI programı tek tip doküman destekler ve hemen her zaman tek bir görü­nümü destekler. Bir anda tek bir doküman açık olabilir. Bir SDI uygulaması belli bir göreve odaklanır. Bir MDI programında çeşitli farklı doküman tipleri kullanılabilir ve bu dokümanların her biri bir veya daha fazla görünüme sahip olabilir. Bir anda birden fazla doküman açık olabilir ve açık olan doküman o dokümanın ihtiyaçlarına uy­gun özelleştirilmiş bir araç çubuğu ve menüler kullanır.

Doküman / Görünüm Niçin Kullanılır?

Doküman / Görünüm mimarisini kullanmanın ilk sebebi bedavadan büyük miktar­larda uygulama kodu sunmasıdır. Mümkün olduğunca az yeni kod yazmaya çalış­malısınız, yani MFC sınıflarını kullanmalı ve AppWizard ile ClassWizard’m birçok işi sizin yerinize yapmasını sağlamalısınız. MFC sınıfları ve AppWizard kodu olarak sizin için yazılan kodun büyük bölümü Doküman / Görünüm mimarisini kullanır.

Doküman / Görünüm mimarisi bir Windows programında kullanılan sınıflar için çeşitli ana kategoriler tanımlar. Doküman / Görünüm herhangi bir Windows prog­ramı oluşturmak için kullanabileceğiniz esnek bir yapı sunar. Doküman / Görünüm mimarisinin büyük avantajlarından birisi, bir Windows programındaki işleri iyi ta­nımlanmış kategorilere bölmesidir. Birçok sınıf bu dört ana sınıf kategorisinden birine girer:

· Belli bir görünümle ilgili kontroller ve kullanıcı arabirimi öğeleri

· Bir dokümana ait olan veri ve veri-yönetimi sınıfları

· Genellikle çerçeve sınıfına ait olan araç çubuğu, durum çubuğu ve menüler

· CWinApp sınıfından türetilmiş sınıfta meydana gelen Windows ile uygula­ma arasındaki etkileşim

Programınızın yaptığı işleri bölümlere ayırmak programınızın tasarımını daha et­kili bir biçimde yönetmenize olanak sağlar. Doküman / Görünüm mimarisini kul­lanan programları genişletmek oldukça kolaydır çünkü dört ana Dokuman / Görü­nüm sınıfı birbiriyle iyi tanımlanmış arabirimler aracılığıyla iletişim kurar. Örne­ğin, bir SDI programı MDI programa çevirmek için çok az yeni kod yazmanız ge­rekir.

Bir Doküman / Görünüm programının kullanıcı arabirimini değiştirmek sa­dece görünüm sınıfını veya sınıflarını etkiler; doküman, çerçeve veya uygulama sınıflarında bir değişikliğe gerek olmaz.

MFC AppWizard’ı Kullanmak

SDI ve MDI uygulamaları oluşturmak için MFC AppWizard’ı kullanın. Daha önce­ki bölümlerde örnek olarak kullanılan SDI programlarını oluşturmak için MFC AppWizard’ı kullandınız. Daha karışık olmasına rağmen bir MDI uygulaması oluşturmak için de MFC AppWizard’ı kullanabilirsiniz

Bir SDI uygulaması ile MDI uygulaması arasındaki temel fark, MDI uygulamasının birden fazla dokümanı ve genellikle birden fazla görünümü desteklemesi gerektiğidir. SDI uygulaması yalnızca tek bir doküman ve normalde tek bir görünüm kullanır.



ClassWizard’ı Kullanmak

Daha önceki bölümlerde iletişim kutusu sınıflarına üye değişkenler eklemek, bir projeye yeni sınıflar eklemek, pencereleri ve iletişim kutularını görüntülemek için gönderilen mesajları yönetmek amacıyla ClassWizard’ı kullandınız. ClassWizard’ı, Doküman / Görünüm mimarisinin bir parçası olarak tanımlanmış arabirimler ek­lemek için de kullanırsınız. Çoğu durumda MFC yapısının sunduğu varsayılan davranış basit programlar için yeterlidir.
Bir sonraki kısımda doküman ve görünüm sınıflarının kullandığı arabirimleri öğreneceksiniz. Ancak bu arabirimlerin hemen hemen hepsini ClassWizard’ı kulla­narak eklersiniz. Bu bölümdeki örnek için DVTest adında bir MDI projesi oluşturacaksınız.

DVTest ör­neğini oluşturmak amacıyla varsayılan bir MDI projesi oluşturmak için AppWizard’ı kullanın. AppWizard’ın önerdiği parametrelerden istediklerinizi değiştirebilirsiniz. Çünkü bu parametrelerin buradaki örneklere bir etkisi olmayacak. Bitirdiğiniz za­man DVTest programı doküman sınıfının kaydettiği bir grup ismi görüntüleyecek.

5.2.2. İşaretçiler ve Referanslar

İşaretçiler C++ programcılığında önemli bir konudur. İşaretçilerin nasıl kullanıl­dığını iyi anlamanız daha esnek ve güvenilir programlar yazabilmenize yardımcı olacaktır. C++ ve özellikle MFC işaretçilerin doğru anlaşılmasına ve kullanılması­na çok önem verir.

İşaretçi (pointer) temelde sayısal bir değişkendir. Bu sayısal değişken asıl bellekteki yerinin adresini taşır. Diğer değişkenler için geçerli olan ku­rallar işaretçiler için de geçerlidir. İşaretçilerin de isimleri eşsiz olmalıdır ve kulla­nılmadan önce tanımlanmalıdırlar.

Bir uygulamada kullanılan her nesne veya değişken bellekte bir veya birden fazla yer kaplar. Bellekteki bu vere bir adres ile ulaşılır (Bkz. Şekil 5.3).






Hello yazısı bellekte 1000 1001 1002 1003 1004 1005
1000 adresinden H e l 1 o \0
başlayarak saklanmış.



Bu şekilde Hello yazısı bellekte 1000 adresinden başlayarak saklanmış. Her karak­ter bellekte bir adres alanı kaplar. İşaretçiler bellekteki bu adreslere ulaşmayı sağ­lar. İşaretçiler verilen yönetmeyi kolaylaştırırlar çünkü başka bir değişkenin veya veri alanının adresini saklarlar. İşaretçiler C++ programlarına esneklik katarlar ve programların dinamik o­larak büyümesine olanak sağlarlar. Yürütme sırasında ayrılan bir bellek blo­ğuna bir işaretçi kullanılarak bir program, bellekten tüm yer ayırma işlemle­rini bir seferde yapan bir programdan çok daha esnek yapılabilir.

Ayrıca bir işaretçiyi saklamak geniş bir yapı veya sınıf nesnesini saklamaya göre daha kolaydır. İşaretçi yalnızca bir adres sakladığından kolaylıkla bir fonksiyona aktarılabilir. Ancak, bir fonksiyona bir nesne aktarılırsa nesnenin kurulması, kop­yalanması ve yok edilmesi gibi büyük nesneler için zahmetli olabilecek işlerin ya­pılması gerekir.

Dolaylılık ve Adres Operatörleri

Bir C++ programında adreslerle çalışırken iki operatör kullanılır: adres operatörü (&) ve dolaylılık operatörü (*). Bu operatörler daha önce gördüğünüz operatörler­den farklıdır çünkü bunlar unary operatörlerdir yani tek bir operanda sahiptirler.

Adres operatörü (&), bir değişken veya nesnenin adresini döndürür. Bu operatör sağındaki nesne ile şu şekilde ilişkilendirilir:

&myAge;

Bu satır myAge değişkeninin adresini döndürür.

Dolaylılık operatörü (*), adres operatörünün tersi gibi çalışır. Bu operatör de sağın­daki nesne ile ilişkilidir: bir adres alır ve o adreste yer alan nesnel döndürür. Ör­neğin, aşağıdaki satır myAge değişkeninin adresini belirler; sonra değişkene erişip 81 değerini atamak için dolaylılık operatörünü kullanır:

*(EtmyAge) = 81;

Referans Kullanmak

Diğer değişkenlere başvurmak için işaretçileri kullanmanın yanı sıra, C++ dili re­ferans (referance) olarak bilinen türetilmiş bir tipe sahiptir. Bir referans adres o­peratörüne çok benzeyen & referans operatörü kullanılarak bildirilir. Her iki ope­ratör de aynı sembolü kullanır; ancak bunları farklı durumlarda kullanırsınız. & sembolünün bir referans için kullanıldığı tek yer bir bildirimdir:

int myAge;
int& myRef = myAge;

Bu kod myAge değişkeni için bir referans olan myRef adında bir referans değişke­ni tanımlar. İşaretçi yerine referans kullanmanın avantajı dolaylılık operatörü ge­rekmemesidir. Ancak referans değişkeni tanımlandıktan sonra başka bir değişkene bağlanamaz. Örneğin, Kod 5.8’deki gibi bir kod genellikle yanlış anlaşılır.
aLayıNaiSyaN isimli Üye şimdilik offline konumundadır  
Digg this Post!Bookmark Post in Technorati
Alıntı ile Cevapla
Alt 04-09-08, 17:38   #4
Dokunma Yanarsın
 
aLayıNaiSyaN - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: 04-02-08
Nerden: . . .
Mesajlar: 1,981
Tecrübe Puanı: 496 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000 aLayıNaiSyaN 1000
Cevap: C++ Mesajlar ve MFC Mimarisi

Bir Değişkenin Değerini Değiştirmek İçin Referans
Kullanımı


void refFunc( )
{
int nFoo = 5;
int nBar = 10;
int& nRef = nFoo;
// nFoo’nun değerini değiştir.
nRef = nBar;
CString strMsg;
strMsg.Format(’nFoo = %d, nBar = %d”, nFoo, nBar);
AfxMessageBox(strMsg);
}

refFun fonksiyonunu bir Windows programında kullanacak olursanız

nRef = nFoo;

satırının nRef referans değişkeninin bağlantısını değiştirmediğini göreceksiniz. Bu satır, nBar değişkeninin değerini (10) nFoo değişkenine atar ve nRef referans de­ğişkeni hala nFoo değişkenine referanstır.

Referanslar en çok fonksiyonlara parametre aktarımı sırasında kullanılır. Fonksi­yon parametresi olarak bir sınıf nesnesi aktarmak hesaplama kaynakları bakımın­dan çok masraflıdır.

Parametre aktarımı için işaretçi kullanmak hatalara neden o­labilir ve fonksiyonun okunabilirliğini etkiler. Ancak, fonksiyon parametresi ola­rak referanslar kullanırsanız gereksiz kopyalama işlemlerini ortadan kaldırmış o­lursunuz ve parametreyi kopyasız aktarılmış gibi kullanabilirsiniz. Çağrılan fonksi­yonun bir referans değişkenin değerini değiştirmesine engel olmak için paramet­reyi şu şekilde const olarak tanımlayabilirsiniz:

void Print( const int& nFoo )
{
nFoo = 12; //Hata - const değiştirilmeye izin verilmiyor.
cout << “The value is” << nFoo << endl;
}

5.2.3. Doküman / Görünüm Arabirimi

Bir Doküman / Görünüm programında en yaygın olarak kullanılan arabirimler döküman ile görünüm nesneleri arasında ve Windows ile doküman ve görünüm nesneleri arasında iletişimi yönetir. Bu arabirimlerin her birinin belli bir amacı vardır. Bunların bazıları projenize dahil ettiğiniz sınıflarda daima override edilir; çoğu yalnızca gerektiğinde override edilir. Bir Doküman / Görünüm programında kullanılan üç önemli arabirim şunlardır:

· GetDocument, dokümanına bir işaretçi almak için kullanılan CView üye fonksiyonu.

· UpdateAllViews, bir doküman ile ilişkilendirilmiş görünümleri güncelle­mek için kullanılan bir CDocument üye fonksiyonu.

· OnNewDocument, dökümanın üye verilerine ilk değer vermek için kulla­nılan bir CDocument üye fonksiyonu.

Bu listenin önemli arabirimlerin yalnızca bir özel olduğunu unutmayın. Liste bir SDI veya MDI programında gerekli tüm arabirimleri içermemektedir. Ancak zevkleriniz değişebilir; Doküman / Görünüm mimarisini bir süre kullandıktan son­ra başka arabirimleri kullanmayı tercih edebilirsiniz. Doküman/Görünüm mimarisinin tanımladığı arabirimler bir uygulamayı oluşturan her MFC sınıfının birbirine göre davranış şeklini temsil eder.

Örneğin, yeni bir doküman oluşturulduğunda MFC yapısı her zaman Document::OnNewDocument fonksiyonunu çağırır. MFC yapısı ve MFC tabanlı bir programın bir parçası ola­bilecek diğer sınıflar bu fonksiyon çağrıldıktan sonra yeni dokümana ilk değer ve­rilmesini beklerler.

Belli görevleri yerine getirmek için CDocument::OnNewDocument gibi iyi tanım­lanmış arabirimler kullanmak yalnızca özel işler yapmanızın gerektiği fonksiyonla­rı değiştirmenize olanak sağlar; varsayılan davranış şeklini isterseniz MFC yapısı­nın birçok fonksiyonu ve arabirimi yönetmesini sağlayabilirsiniz.

Doküman/Görünüm mimarisi ayrıca işleri ayırmayı da kolaylaştırır. Örneğin, veri yalnızca dokümana aittir; bir görünüm doküman işaretçisini almak için GetDocument fonksiyonunu çağırır ve sonra verileri almak veya güncellemek için üye fonksiyonları çağırır.

Bir Veri Modeli Oluşturmak

Daha önce ele alınan arabirimlerin her birinin belli bir rolü vardır. Bu bölümdeki geri kalan örnekler için daha önceden oluşturulan DVTest örneğini kullanacaksınız.

DVTest örneğine geri dönün ve doküman sınıfına private veri üyesi olarak bir CArray şablon nesnesi ekleyin. Bunu yapmak için, DVTestDoc.h dosyasında yer a­lan CDVTestDoc sınıf başlığına Kod 5.9’daki kaynak kodu ekleyin. Kaynak kodu AppWizard’ın ürettiği // özellikIer açıklaması ile başlayan kısma ekleyin.

Kod 5.9. CDVTestDoc Sınıf Bildiriminde Yapılacak Değişiklikler

// özellikler
public:
CString GetName( int nIndex ) const;
int AddName( const Cstring& szName );
int GetCount( ) const;
private:
CArray<CString, CString> m_arNames;

CDVTestDoc sınıfı bir CArray üye değişkeni içerdiğinden şablon bildirimleri projeye dahil edilmelidir. StdAfx.h dosyasının alt kısmına aşağıdaki satırı ekleyin :

#include “afxtempl.h”

Bir sonraki adım CDVTestDOC sınıf arabiriminde tanımlanmış fonksiyonları gerçeklemektir. Bu fonksiyonlar dökümanda tutulan bilgilere DVTestDoc.cpp dosyasının sonuna Kod 5.10’daki kodu ekleyin.

CDVTestDoc Sınıfına Eklenen Yeni Fonksiyonlar


Cstring CDVTestDoc:etName( int nIndex ) const
{
ASSERT( nIndex < m_arNames.GetSize( ) );
return m_arNames[nIndex];
}
int CDVTestDOc::AddName( const Cstring& szName )
{
return m_arNames.Add( szName );
}
int CDVTestDOC:etCount( ) const
{
return m_arNames.GetSize( );
}

Her doküman sınıfı veri eklemek ve verilere ulaşmak için bazı erişim fonksiyonları belirtmelidir. Kod 5.10’daki üç fonksiyon tipik erişim fonksiyonlarıdır. Veriler CArray’den başka bir şablonda da saklanabilirdi. Verilen bir CArray nesnesinde sak­lamak CDVTestDoc sınıfinın kullanıcılarını ilgilendirmemesi gereken bir ayrıntıdır. Bu durum CDVTestDoc sınıfının gelecekte gerekirse değiştirilebilmesine olanak sağlar
aLayıNaiSyaN isimli Üye şimdilik offline konumundadır  
Digg this Post!Bookmark Post in Technorati
Alıntı ile Cevapla
Cevapla

  • Submit Thread to Digg Digg
  • Submit Thread to del.icio.us del.icio.us
  • Submit Thread to StumbleUpon StumbleUpon
  • Submit Thread to Google Google
  • Bookmarks

    Seçenekler
    Stil

    Yetkileriniz
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is Açık
    Smileler Açık
    [IMG] Kodları Açık
    HTML-KodlarıKapalı
    Trackbacks are Açık
    Pingbacks are Açık
    Refbacks are Açık



    Bütün Zaman Ayarları WEZ olarak düzenlenmiştir. Şu Anki Saat: 13:29 .


    Powered by vBulletin Version 3.8.7
    Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
    Search Engine Friendly URLs by vBSEO 3.5.0 RC2
    Sohbet ve Sohbet odalari sitesi

    Sohbet Chat Forum Oyunlar1