SİTE
İÇİ ARAMA |
|
Blogroll |
|
|
|
Windows API - Pencere Oluşturmak |
|
Gönderiliyor lütfen bekleyin... |
|
|
C ve GUI
Bu yazımızda, grafik
kullanıcı arayüzü oluşturma konusunu ele alacağız. Grafik kullanıcı arayüzü
(GUI - Graphical User Interface), pencereler, menüler, düğmeler vb araçlar yoluyla
kullanıcı ile iletişim kurmayı sağlar. Bugüne kadar C ile geliştirdiğimiz uygulamalar,
konsol program niteliği taşımaktaydı. Programı çalıştırdığımızda karşımıza komut
satırı ekranı çıkıyordu. Program gerekli bilgileri bu ekrandan alıyordu ve sonuçlar
yine bize bu ekranda sunuyordu. Profesyonel uygulamalarda, konsol programlar
oluşturmak çoğu zaman yetersiz kalacaktır. Programın verimli ve etkin bir şekilde
çalışmasının yanısıra kullanıcı ile kurulan etkileşim de oldukça önemlidir.
Son kullanıcılar da, bir konsol programı kullanmaktansa, grafik arayüze sahip
bir uygulamayı kullanmayı tercih edeceklerdir. Bu amaçla Windows sisteminin
grafik arabirimi kullanılarak yazılan programlar GUI (Graphical User Interface)
programları olarak bilinirler. Çoğu nesne yönelimli programlama dilinde grafik
arabirim kullanıcı tarafından sürükle-bırak tekniği ile tamamen görsel biçimde
oluşturulur. Bu tür programlama dillerinin IDE’lerinde genellikle bir araç çubuğunda
grafik arabirimler görsel olarak programcıya sunulur. Programcı buradan istediği
kontrolü seçerek sürükle-bırak yöntemiyle onu forma yerleştirir. Bu IDE’lerde
standart kontroller arka planda IDE tarafından kodlanır. Eğer IDE bu desteği
sağlamıyorsa formları ve kontrolleri oluşturmak için API programlama yapılır.
GUI programları
geliştirmek için işletim sistemimizin API (Application Programming Interface)
fonksiyonlarını kullanırız. (Genel olarak işletim sistemine ait fonksiyonlara
sistem fonksiyonları denilmektedir. Windows işletim sisteminde sistem fonksiyonları
API fonksiyonları olarak isimlendirilir.) İşletim sistemleri, programcılara,
pencere oluşturmak ve kullanıcıdan veri alışı sağlayan kontrolleri oluşturmak
için bir takım fonksiyonlar sunmuşlardır. Bu fonksiyonları kullanarak program
geliştirme, API programlama olarak bilinir. API programlama yapabilmek için,
sistemin sunmuş olduğu bu fonksiyonların iyi bir şekilde tanınması, ne zaman
hangi fonksiyonun çağrılması gerektiğinin bilinmesi ve kullanılan işletim sisteminin
temel özelliklerinin tanınması gereklidir. Biz bu yazı dizimizde, işletim sistemi
olarak Windows’u kullanacağız ve Windows sisteminin API fonksiyonlarını tanıyacağız.
Burada ilk yapacağımız uygulama, kodlama yolu ile bir pencere oluşturmak olacak.
Windows’un grafik sistemi kullanılarak oluşturulan programlar GUI programları
olarak bilinir. GUI programları, temel olarak bu uygulamayı kullanırlar. Kullanacağımız
API fonksiyonlarının prototip bildirimleri ve sembolik sabitlerin bildirimleri
"windows.h" başlık dosyasında yer almaktadır. Bu nedenle uygulamamıza
öncelikle bu başlık dosyasını eklemeliyiz.
Windows GUI programları,
WinMain fonksiyonu ile başlarlar. Bu fonksiyon, programla ilgili bir takım bilgileri
parametre değişkeni olarak alır. Sisteme tanıtılan pencereleri oluşturur. Pencereler
oluşturulmadan önce, pencere özelliklerinin sisteme belirtilmesi gereklidir.
Bu işleme "pencerenin register edilmesi" denir. Bu işi yapan fonksiyon
RegisterClass ya da RegisterClassEx fonksiyonlarıdır. Sisteme tanıtılan pencereler
CreateWindow ya da CreateWindowEx fonksiyonları ile oluşturulur. WinMain fonksiyonunda
bu işlemler yapıldıktan sonra pencerenin görüntülenmesini sağlayan ShowWindow
fonksiyonu çağrılır. Ana pencere görüntülendikten sonra, bir mesaj döngüsü oluşturulur.
Bu döngü, sisteme gelen mesajları dinleyerek işler. Mesajlar bir kuyruk yapısında
tutulur, sırasıyla kuyruktan alınarak programcı tarafından işlenir. Mesajlar,
başka bir fonksiyonda işlenir. Programın sonlanması için bu mesaj döngüsünden
çıkılması gereklidir. Mesaj döngüsünden çıkıldığında WinMain fonksiyonu sonlanır
ve program da biter.
DOS işletim sisteminde,
kullanıcıdan bilgi almak için kullanılan bazı fonksiyonlar vardır. Örneğin scanf,
gets, getch gibi fonksiyonlar, kullanıcının ekranda girdiği bilgileri almak
için kullanılırlar. Windows işletim sisteminde ise bu bilgiler sistemin kendisi
tarafından alınır ve mesaj olarak isimlendirilir. Kullanıcının klavyeden girdiği
bilgiler veya fare ile yaptığı hareketler Windows sistemi tarafından bir mesaj
olarak algılanır. Bu mesajlar alınma sırasıyla bir mesaj kuyruğuna yerleştirilir
ve programcı tarafından işlenmeyi bekler. Her mesaj kendisiyle ilgili birtakım
bilgilere de sahiptir. Örneğin mesajın neden oluştuğu, nereden geldiği (hangi
pencereden geldiği) gibi bilgiler mesaj yapısı içerisinde tutulur. Programcı
mesajları işlediği fonksiyon içerisinde mesajların türlerine ve anlamlarına
bakarak istediği mesajları işler ve bu mesajlar oluştuğu takdirde yapılmasını
istediği işlemleri kodlar.
Bu yazımızdaki
uygulamamızda örnek bir pencere oluşturacağız, daha sonra bu pencere üzerine
standart birtakım kontroller ekleyeceğiz. Kontrollerden gelen mesajları işleyerek
bir GUI programı yazacağız. Uygulama, Visual Studio .NET 2003 programında geliştirildi.
Visual Studio .NET’te bir GUI projesi oluşturmak için ’File’ menüsünden sırasıyla
’New - Project’ seçenekleri seçilir. Açılan pencereden sırasıyla ’Visual C++
Projects - Win32 - Win32 Project’ seçenekleri seçilir. Projenin kaydedileceği
yer ve dosya ismi belirlendikten sonra ’’ Tamam tuşuna basılır. Açılan pencerede
’Application Settings’ menüsüne geçilerek ’Application Type’ olarak ’Windows
Application’, ’Additional Options’ olarak ’Empty Project’ seçilerek ’Finish’
tuşuna basılır. Daha sonra ’Add New Item’ komutu verilerek projeye bir kaynak
kod dosyası eklenir. Artık uygulamamızı yazmaya geçebiliriz.
NOT : Microsoft
Visual C++ 6.0’da bir GUI uygulaması oluşturmak için ’File’menüsünden ’New’
komutu verildikten sonra açılan pencerede proje türü olarak ’Win32 Application’seçilir.
Daha sonra açılan pencerede ’An empty project’seçeneği seçilir. Oluşturulan
projeye kaynak kod dosyası ekledikten sonra kod yazma aşamasına geçilir.
Öncelikle GUI programımızın
çalışmaya başlayacağı WinMain fonksiyonunu oluşturalım. Fonksiyonun parametrik
yapısı Aşağıdaki yapıya uygun olmalıdır :
int WINAPI
WinMain (HINSTANCE hInstance, //Çalıştırılabilen dosyanın çalıştırılma sırasında
belleğe yüklenme adresi
                           
HINSTANCE hPrevInstance, //Çalıştırılabilen dosyanın bir önceki belleğe
yüklenme adresi
                           
LPSTR lpCmdLine, //komut satırı parametrelerini gösteren yazının başlangıç
adresi
                           
int nCmdShow) //Program çalıştırıldığında ana pencerenin hangi büyüklükte
görüntüleneceği bilgisi |
hPrevInstance parametre
değişkeni için Win32 sistemlerinde her zaman NULL değer geçilir. Win16 sistemlerinde
programın ilk defa çalıştırılması durumunda bu parametre değişkeni için yine
NULL değer geçilir, ancak programın ilk çalıştırılması değilse bu değer bir
önce çalışan programın hInstance değerini belirtir. Eğer programımızın çalıştırılması
sırasında o an sistemde çalışan başka bir kopyası olup olmadığını anlamak istiyorsak
CreateMutex sistem fonksiyonu çağrılmalıdır. Daha sonra GetLastError çağrılarak
bu fonksiyondan dönen değer kontrol edilmelidir. Eğer fonksiyon ’ERROR_ALREADY_EXISTS’
değerini döndürürse o an sistemde programımızın bir kopyasının daha çalıştığını
anlarız. nCmdShow parametre değişkeni, pencerenin nasıl görüntüneceği bilgisini
içerir. Bu parametre değişkeninin değeri şu sembolik sabitlerden birisi olabilir
:
SEMBOLİK
SABİT
|
ANLAMI
|
SW_HIDE |
Pencere
saklanır ve başka bir pencere aktif yapılır. |
SW_MINIMIZE |
Pencere
minimized durumuna getirilir ve sistemde en üst sırada yer alan pencere
aktif hale getirilir. |
SW_RESTORE |
Pencere
görüntülenir ve aktif hale getirilir. Eğer pencere minimized ya da maximized
duruma getirilirse sistem tarafından eski boyutlarına ve konumuna getirilir.
(SW_SHOWNORMAL ile aynı anlamdadır.) |
SW_SHOW |
Pencereyi
aktif hale getirir ve geçerli konum ve boyutlarda görüntüler. |
SW_SHOWMAXIMIZED |
Pencereyi
aktif hale getirir ve maximized olarak gösterir. |
SW_SHOWMINIMIZED |
Pencereyi
aktif hale getirir ve minimized olarak gösterir. |
SW_SHOWMINNOACTIVE |
Pencereyi
minimized olarak gösterir, aktif pencere aktif olarak kalır. |
SW_SHOWNA |
Pencereyi
geçerli durumunda gösterir. Aktif pencere aktif olarak kalır. |
SW_SHOWNOACTIVATE |
Pencereyi
son sahip olduğu boyutlarda ve konumda gösterir. Aktif pencere aktif olarak
kalır. |
SW_SHOWNORMAL |
Pencere
gösterilir ve aktif hale getirilir. Eğer pencere minimized veya maximized
durumuna getirilmişse sistem tarafından eski boyutlarına ve konumuna getirilir.
(SW_RESTORE ile aynı anlamdadır.) |
WinMain fonksiyonunun
geri dönüş değeri, eğer fonksiyondan WM_QUIT mesajı alınarak çıkılmışsa wParam
veri elemanının değeri olmalıdır. Eğer WinMain fonksiyonu, mesaj döngüsü içerisine
girmeden sonlanmışsa 0 değerine geri dönmelidir. WinMain fonksiyonu içerisinde
programda kullanılacak olan pencerelere ilişkin özellikler sisteme belirtilerek,
pencereler sisteme register edilirler. Pencerelerin, WinMain içerisinde yaratılıp
yaratılmayacağı programcıya kalmıştır. Yaratılan pencerelerin gösterilmesi sağlanır
ve mesaj döngüsü oluşturularak fonksiyon tamamlanır. Mesaj döngüsünden WM_QUIT
mesajı alındığında çıkılır. En temel GUI programı için WinMain fonksiyonunda
bu işlemler yapılmaktadır. Pencerelerin özelliklerini belirtmek için WNDCLASS
ismindeki yapı kullanılır. Bu yapı pencere bilgilerini belirten birtakım veri
elemanlarına sahiptir. WinMain fonksiyonumuzun içeriğini yazmadan önce bu yapıyı
ve veri elemanlarını inceleyelim :
VERİ
ELEMANI
|
ANLAMI
|
UINT
style |
Pencereye
ait genel bilgileri içerir. Bu veri elemanına geçilebilecek değerler, anlamlarını
ifade eden isimler ile isimlendirerek Windows.h başlık dosyası içerisinde
sembolik sabit olarak tanımlanmıştır. |
WNDPROC
lpfnWndProc |
Yapının
ilişkin olduğu pencerenin pencere fonksiyonunun başlangıç adresini gösteren
bir göstericidir. |
int
cbClsExtra |
Pencere
sınıfı için ayrılacak ek alanların byte cinsinden değeri |
int
cbWndExtra |
Pencere
handle alanında ayrılacak ek alanların byte cinsinden değeri |
HANDLE
hInstance |
Çalıştırılabilen
dosyanın belleğe yüklenme adresidir. Bu veri elemanına WinMain fonksiyonuna
sistem tarafından geçilen hInstance değeri aktarılır. |
HICON
hIcon |
Pencere
başlığında görüntülenen ikonu belirtir. |
HCURSOR
hCursor |
Fare
okunun şeklini belirtir. |
HBRUSH
hbrBackground |
Pencerenin
zemin rengini belirtir. |
LPCTSTR
lpszMenuName |
Pencereye
ilişkin menüyü belirtir. (Pencerenin menüsü yoksa NULL değeri atanır.) |
LPCTSTR
lpszClassName |
Pencere
yapısının sınıf ismini belirtir. |
WinMain fonksiyonunun
yazılmasıne geçmeden önce bu fonksiyonda kullanacağımız bazı API fonksiyonlarını
inceleyelim :
ATOM RegisterClass
(
    CONST WNDCLASS *lpWndClass //Pencere sınıfı göstericisi
); |
RegisterClass fonksiyonu,
bir pencere yaratılmadan önce onun sisteme tanıtılmasını (register edilmesini)
sağlar. Fonksiyon çağrılmadan önce yartılacak pencerenin özellikleri lpWndClass
parametresine geçilecek nesneye atanmalıdır. Fonksiyon başarılı olması durumunda
sorunsuz bir şekilde sisteme tanıtılan pencerenin değerine döner. Başarısız
olursa sıfır değerine döner. Bir uygulama içerisinde sisteme tanıtılan tüm pencereler,
uygulama sonlandırıldığında sistemden silinirler.
HWND CreateWindow
(
    LPCTSTR lpClassName, //Sisteme tanıtılan pencere sınıf ismi
    LPCTSTR lpWindowName, //Pencere başlığında görüntülenecek
yazı
    DWORD dwStyle, //Pencere biçimi
    int x, //Pencerenin yatay pozisyonu
    int y, //Pencerenin dikey pozisyonu
    int nWidth, //Pencere genişliği
    int nHeight, //Pencere yüksekliği
    HWND hWndParent, //Parent ya da owner pencere tutamaç değeri
    HMENU hMenu, //Menü veya child pencere tutamaç değeri
    HANDLE hInstance, //Uygulamanın çalıştırılma adresi
    LPVOID lParam //Pencere yaratılma bilgileri göstericisi
); |
CreateWindow fonksiyonu
pencere yaratmak için kullanılır. Pencereyi yaratırken pencerenin ilişkin olduğu
pencere sınıfı, başlık yazısı, biçimi, görüntüleceği konum ve boyutlar belirtilir.
Fonksiyon başarılı olursa yaratılan pencerenin tutamaç değerine döner, başarısız
olursa NULL değere döner.
BOOL ShowWindow(
    HWND hWnd, //Pencere tutamacı
    int nCmdShow //Pencerenin durumu
); |
ShowWindow fonksiyonu,
parametresinde belirtilen pencerenin görüntülenme durumunu ayarlar. nCmdShow
parametresi için yukarıdaki tabloda verilen sembolik sabirlerden birisi geçilir.
Bir uygulamada ShowWindow fonksiyonu ilk defa çağrıldığında, nCmdShow parametre
değişkeni için WinMain fonksiyonuna geçilen nCmdShow parametresinin değeri kullanılır.
Bu ilk çağrıyı izleyen ShowWindow çağrılarında ise tabloda verilen değerlerden
birisi geçilir.
BOOL UpdateWindow
(
    HWND hWnd //Pencere tutamacı
); |
UpdateWindow fonksiyonu,
parametresinde belirtilen pencerenin kapladığı alanı, pencereye WM_PAINT mesajı
göndererek günceller. (WM_PAINT mesajının gönderilmesi için pencereye ilişkin
güncelleme alanının boş olmaması gereklidir.) Fonksiyon, parametresinde belirtilen
pencereye ait pencere fonksiyonuna doğrudan WM_PAINT mesajını yollar. Fonksiyon
başarılı olması durumunda sıfır dışı bir değerle, başarısız olması durumunda
ise sıfır değeriyle geri döner.
BOOL GetMessage
(
    LPMSG lpMsg, //Mesaj yapısı göstericisi
    HWND hWnd, //Pencere tutamacı
    UINT wMsgFilterMin, //İlk mesaj
    UINT wMsgFilterMax //Son mesaj
); |
GetMessage fonksiyonu,
kendisini çağıran kanalın (thread) mesaj kuyruğundan bir mesaj alır ve bu mesajı
parametre olarak geçilen mesaj yapısı göstericisi içerisine yerleştirir. Diğer
kanallara veya uygulamalara ait mesajların alınması için kullanılamaz. Eğer
hWnd parametre değişkeni için NULL değer geçilirse kendisini çağıran kanal içerisinde
herhangi bir pencereye ilişkin olabilecek mesajı alabilir. Fonksiyonun belli
değerler arasındaki mesajları alması da sağlanabilir. Bunun için son iki parametreye
sınır değerler geçilir. Eğer fonksiyon kuyruktan WM_QUIT haricinde bir mesaj
alırsa sıfır dışı bir değere, WM_QUIT mesajını alırsa sıfır değerine geri döner.
Bir hata oluşması durumunda -1 değerine geri döner.
BOOL TranslateMessage
(
    CONST MSG *lpMsg //Mesaj yapısı göstericisi
); |
TranslateMessage
fonksiyonu, sanal tuş mesajlarını (virtual-key messages), karakter mesajlarına
(character messages) dönüştürür. Karakter mesajı, kendisini çağıran kanalın
mesaj kuyruğuna bırakılır. Fonksiyon, mesaj dönüştürülmüşse sıfır dışı bir değere,
dönüştürülmemişse sıfır değerine geri döner.
LONG DispatchMessage
(
    CONST MSG *lpMsg //Mesaj yapısı göstericisi
); |
DispatchMessage
fonksiyonu, bir mesajı pencere fonksiyonuna gönderir. Pencere fonksiyonu da
DispatchMessage fonksiyonu tarafından çağrılır. Geri dönüş değeri, pencere fonksiyonundan
geri dönen değerdir.
WinMain fonksiyonunda
kullanacağımız fonksiyonları da inceledikten sonra fonksiyonu yazmaya başlayabiliriz
:
int WINAPI
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int
nCmdShow)
{
    WNDCLASS wndClass;
    HWND hWnd;
    MSG msg;
    if (!hPrevInstance)
{
       wndClass.style = CS_HREDRAW | CS_VREDRAW;
       wndClass.lpfnWndProc = (WNDPROC)WndProc;
       wndClass.cbClsExtra = 0;
       wndClass.cbWndExtra = 0;
       wndClass.hInstance = hInstance;
       wndClass.hIcon = LoadIcon(NULL,IDI_WINLOGO);
       wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
       wndClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0,0,0));;
       wndClass.lpszMenuName = NULL;
       wndClass.lpszClassName = "gui";
       if (!RegisterClass(&wndClass))
          return 0;
    }
    hWnd = CreateWindow("gui",
                                   "Örnek Windows GUI Uygulaması",
                                   WS_OVERLAPPEDWINDOW,
                                   CW_USEDEFAULT,
                                   0,
                                   CW_USEDEFAULT,
                                   0,
                                   NULL,
                                   NULL,
                                   hInstance,
                                   NULL);
    if (!hWnd)
       return 0;
    ShowWindow(hWnd,SW_SHOW);
    UpdateWindow(hWnd);
    while (GetMessage(&msg,0,0,0))
{
       TranslateMessage(&msg);
       DispatchMessage(&msg);
    }
    return msg.wParam;
}
|
WinMain fonksiyonunda
yaptıklarımızı adım adım inceleyelim.
- Değişkenler
: Fonksiyonun başında WNDCLASS, HWND ve MSG türlerinden üç tane nesne
tanımladık. Windows sistemi oluşturulan pencerelere özel bir değer atar. Bu
değer pencere tutamacı (window handle) olarak bilinir. Sistemdeki pencerelere
bu değer ile ulaşılabilir ve pencere üzerinde işlem yapan API fonksiyonları
da bizden bu değeri isterler. Program içerisinde bu değeri tutmak için HWND
türünden bir gösterici tanımlanır. Yukarıda tanımladığımız hWnd isimli gösterici
de uygulamada oluşturacağımız pencerenin tutamaç değerini tutacaktır. WNDCLASS
türündeki nesneye, oluşturacağımız pencere ile ilgili özellikleri atayacağız.
MSG ise sistemdeki mesajları tutmak için kullanılan bir türdür. Programımızda
mesajları izleyebilmek için msg isimli yapı nesnesini tanımladık.
- wndClass
nesnesinin oluşturulması : Önce penceremizin özelliklerini wndClass nesnesine
sırasıyla atıyoruz. wndClass yapı nesnesinin lpfnWndProc isimli veri elemanına
atadığımız adres, mesajları işlemek için kullanacağımız fonksiyonun adresidir.
Bu fonksiyon, ya WinMain fonksiyonu yukarısında tanımlanmalıdır ya da prototip
bildirimi WinMain fonksiyonunun yukarısında yapılmalıdır. style veri elemanına
atadığımız ’CS_HREDRAW | CS_VREDRAW’ değeri ile pencere boyutu değiştirildiğinde
pencerenin yeniden çizilmesini sağlar. cbClsExtra ve cbWndExtra veri elemanlarına
0 değerini atadık. hInstance veri elemanına, WinMain fonksiyonuna sistem tarafından
geçilen hInstance değerini verdik. hIcon veri elemanına, LoadIcon fonksiyonuyla
standart Windows logosu ikonunu yükledik. hCursor veri elemanına LoadCursor
fonksiyonuyla ’IDC_ARROW’ olarak tanımlanmış fare okunu yükledik. hbrBackground
veri elemanına CreateSolidBrush fonksiyonuyla bir fırça tanımladık. Burada
fonksiyonun kırmızı, yeşil ve mavi değerleri için sıfır değerlerini geçtik,
dolayısıyla pencerenin fırça rengi siyah olacaktır. Yani ekranımızın içi siyaha
boyanacaktır. lpszMenuName isimli veri elemanına NULL değerini atadık. Böylece
penceremizin bir menüye sahip olmadığını belirttik. Eğer penceremiz bir menüye
sahip olacaksa bu veri elemanı için o menüyü belirten bir değer atanır. lpszClassName
isimli veri elemanına ise ’gui’ değerini atadık. Bu değer pencerenin sınıf
ismi anlamına gelmektedir. Daha sonra pencereyi yaratan fonksiyonda kullanılır.
- Pencerenin
sisteme kaydedilmesi : Pencere özelliklerimizi belirttikten sonra pencere
sınıfının sisteme kaydedilmesi gerekir. Bunun için RegisterClass fonksiyonu
kullanılır. Yukarıda da değindiğimiz gibi bir pencere, sisteme tanıtılmadan
yaratılamaz. RegisterClass fonksiyonu, pencere yaratma fonksiyonu çağrılmadan
önce mutlaka çağrılmalıdır. Eğer fonksiyon başarısız olursa programdan çıkılır.
Penceremizi sisteme tanıttıktan sonra artık yaratabiliriz.
- Sisteme kaydedilen
pencerenin yaratılması : Sisteme tanıtılan bir pencerenin yaratılması
için CreateWindow fonksiyonunu kullandık. Bu fonksiyon eğer başarılı olursa,
bize sistem tarafından pencereye atanan tutamaç değerini döndürür. Bu değeri
hWnd isimli göstericimizde saklarız. CreateWindow gonksiyonun dwStyle parametresi
için ’WS_OVERLAPPEDWINDOW’ değerini geçtik. Bu değer, penceremizin başlık
çubuğuna ve çerçevelere sahip bir pencere olduğu anlamına gelmektedir. Fonksiyonun
x isimli parametre değişkeni için geçtiğimiz ’CW_USEDEFAULT’ sembolik sabiti
sadece WS_OVERLAPPEDWINDIW pencere biçimi için kullanılabilir. x parametresi
için geçilen CW_USEDEFAULT sembolik sabitinin anlamı, pencerenin sol üst köşesi
için varsayılan pozisyonun atanacağı ve y parametre değişkeninin göz ardı
edileceğidir. nWidth isimli parametre değişkeni için de CW_USEDEFAULT sembolik
sabitini geçerek pencerenin varsayılan genişlik ve yükseklikte olmasını sağladık.
Penceremiz programın ana penceresi olduğu için ve parent veya owner nitelikte
pencerelere sahip olmadığı için hWndParent parametresi yerine NULL değerini
geçtik. Ayrıca penceremiz şimdilik bir menüye de sahip olmadığı için hMenu
parametresi için de NULL değerini geçtik. Fonksiyon çağrısından sonra hWnd
göstericisindeki değer NULL ise pencere yaratılamamış demektir ve bu durumda
programdan çıkılmalıdır.
- Pencerenin
ekranda gösterilmesi : Pencere yaratma işlemi de başarıyla gerçekleşirse
ShowWindow fonksiyonu ’SW_SHOW’ değeri ile çağrılarak pencerenin görüntülenmesi
sağlanır.
- Mesaj döngüsünün
oluşturulması : Fonksiyonun sonunda sistemdeki mesajları dinlemek için
mesaj döngüsü oluşturduk. Döngüde GetMessage fonksiyonu ile mesajları alıp,
TranslateMessage ile dönüştürdük ve ardından DispatchMessage fonksiyonunu
çağırarak mesajların pencere fonksiyonuna iletilmesini sağladık. Mesaj döngüsünden,
kuyruktan WM_QUIT mesajı alındığında çıkılacaktır. Bu da programın sonlanması
anlamına gelir. Şimdi mesajların işlenmesini gerçekleştirecek pencere fonksiyonumuzu
yazalım.
LRESULT CALLBACK
WindowProc (
    HWND hWnd, //Pencere tutamacı
    UINT uMsg, //Mesaj
    WPARAM wParam, //İlk mesaj parametresi
    LPARAM lParam //İkinci mesaj parametresi
); |
wParam ve lParam
parametreleri, mesajla ilgili özel bilgiler içerirler. Mesaj içeriklerinin anlaşılmasında,
mesaj kaynağının belirlenmesinde bu parametre değişkenleri kullanılır. Bu prototip
bildirimini WinMain fonksiyonu yukarısında yapmamız gereklidir. Çünkü WinMain
içerisinde, pencere özelliklerini tutan nesnenin lpfnWndProc isimli veri elemanı
için bu fonksiyonun adresini atamıştık. Prototipi belirttikten sonra fonksiyonun
içeriğini oluşturalım :
LRESULT CALLBACK
WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    switch (uMsg) {
       case WM_DESTROY :
             PostQuitMessage(0);
             break;
       default :
             return DefWindowProc(hWnd,uMsg,wParam,lParam);
    }
    return 0;
} |
Pencere fonksiyonu
içerisinde, fonksiyona geçilen uMsg mesaj değeri, switch ifadesine sokularak
içinde tuttuğu değere göre belli işlemler yapılır. uMsg parametresinin içeriği
bize mesajın ne mesajı olduğunu anlatır. Örneğin klavyeden bir tuşa mı basıldı,
farenin herhangi bir tuşuna mı basıldı, programdan çıkma isteği mi oluştu gibi.
Tüm bu durumlarda yapılacak özel işlemler varsa, case ifadelerinde bunlara ilişkin
kodlar oluşturulur. WM_DESTROY mesajı, bir pencere yok edildiğinde gönderilmektedir.
Bu mesaj, ilgili pencere ekrandan kaldırıldıktan sonra alınır. PostQuitMesajı,
sisteme bir kanalın sona erme isteğinde bulunduğunu belirtir. Parametre değişkeni,
uygulamanın çıkış kodu anlamına gelir. Diğer mesajların işlenmesini bu uygulamamızda
ele almayacağımız için, diğer tüm mesajlar için default ifadesinde DefWindowProc
fonksiyonunu çağırdık. Bu fonksiyon, uygulama tarafından işlenmeyecek mesajlar
için varsayılan pencere fonksiyonunu çağırmaktadır. default ifadesinde DefWindowProc
fonksiyonu çağrıldığında, uygulama içerisinde tüm mesajların programcı ya da
sistem tarafından ele alınması garanti altına alınmış olur. Uygulamamızı çalıştırdığımızda
ekranda siyah bir pencere göreceğiz :
Uygulamaya ilişkin
projeyi buradan indirebilirsiniz. (Uygulama Visual Studio .Net 2003’te hazırlanmıştır.)
Önümüzdeki yazımızda görüşmek üzere, herkese mutlu günler dilerim.
Makale:
Windows API - Pencere Oluşturmak C ve Sistem Programlama Çiğdem Çavdaroğlu
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|
|