13 Temmuz 2019 Cumartesi

Windows İşletim Sisteminin Özellikleri


Windows İşletim Sisteminin Özellikleri

Windows'un Tarihi

            Windows üzerinde ilk çalışmalara 1985 yılında başlamıştır. İlk ürün Windows 1.0 idi. Windows 3.0 sürümü ile işletim sistemine benzeyen özellikler kazanmıştır. Windows'un en uzun süre pazarda kalan sürümü 3.1'dir. Windows 3.1 kadar(3.1 dahil) Windows sistemleri 16 bit mikro işlemcilerde çalışabilecek biçimdeydi. 1995'te Windows 95 piyasaya sürüldü ve bunu Windows 98 izledi. Win95/98/NT sistemleri 32 bitlik Windows sistemleridir. 32 bit Windows sistemleri birbirine çok benzer sistemleridir. Programlama bakımından bu sistemlerin hepsi yüksek düzeyde uyumludur(.obj ve .exe dosyaları da tamamen uyumludur). Windows sistemleri yalnızca Intel tabanlı mikro işlemciler için düşünülmemiş. Çeşitli risc tabanlı sistemlerde de Windows işletim sistemi kullanılabilmektedir. Windows CE, Windows sisteminin küçültülerek el bilgisayarlarına uyarlanmış biçimidir. Bu sistemin programlama biçimi diğer Windows sistemleriyle uyumludur.

Windows Sisteminin Temel Özellikleri

1. Windows grafik tabanlı bir işletim sistemidir.

            Windows grafik mode'da çalışan bir sistemdir. Oysa DOS ve UNIX temelde text mode'da çalışır. Ancak bu işletim sistemlerinin de kullanımını kolaylaştırmak için grafik arabirimleri vardır. Ancak yalnızca Windows'da grafik mode'da program yazmak zorunlu değildir. Bir Windows programı Windows'un grafik özelliğini kullanabilir. Bu tür programlara GUI(graphical user interface) programlar denir. Zaten Windows programı denilince bu tür programlar anlaşılır. Bazı Windows programları text mod'da çalışabilir. Böyle programlara console programları denir. Console programları için özel bir bilgiye gereksinim yoktur. Programlar DOS ve UNIX'te olduğu gibi organize edilir.

2. Windows aygıt bağımsız grafik özelliğine sahiptir.

            Windows'da oluşturulan grafiksel görüntüler ekran kartına, ekran moduna ve monitör tipine bağlı değildir. Yeni bir grafik kartı takıldığında önceki kart için yazılmış program aynı biçimde çalışır. Yani bu değişimlerden programlama sistemi etkilenmez.

3. Windows çok işlemli bir işletim sistemidir.

            Windows aynı anda birden fazla programın bir arada çalıştırılabildiği çok işlemli(multi processing) bir işletim sistemidir. Çok işlemli çalışma zaman paylaşımlı bir biçimde yapılır. Yani her program bir süre çalıştırılarak bırakılır. Programların çalıştırılıp bırakılma işlemleri belli bir algoritma ile yürütülür. Bu algoritmaya çizelgeleme algoritması denir. Windows sistemleri döngüsel çizelgeleme(round robind scheduling) sistemi kullanır. Programların çalıştırılıp bırakılma süresine quanta denir. Windows sistemleri 20 ms'lik quanta sistemi kullanır. Bir programın bırakılarak diğer bir programın çalıştırılması işlemine görevler arası geçiş(task switch) denir. Ancak programlar çoğu zaman dışsal bir takım olayları beklerler(klavyeden bir tuşun basılmasını, porttan bir bilgi gelmesini, dosyadan veri okunması vs..). O zaman işletim sistemi ilgili programı çizelge dışı bırakır. Bu işleme programın bloke edilmesi denir. Bu dışsal olaylar gerçekleştiğinde işletim sistemi programı tekrar çizelgeye yeniden dahil eder. Ancak Windows işletim sisteminde olduğu gibi bazı sistemler öncelikli döngüsel çizelgeleme kullanabilirler. Her programın 0-31 arasında bir öncelik derecesi vardır. Sistem en yüksek öncelikteki programlar arasında çizelgeleme yapar. Ancak onlar bittikten sonra diğerleriyle uğraşılır.


Düşük öncelikli programlar yine de çalışır. Çünkü yüksek öncelikli programların hepsinin bloke olma olasılığı vardır. Tabii isterse programcı yazılım yoluyla da bloke olabilir. Windows'da bir programın minimize edilmesi bloke edilmesi anlamına gelmez.

4. Windows "preemtive" bir işletim sistemidir.

            Preemtive sistemlerde işletim sistemi görevler arası geçiş işlemiyle bir programı çalıştırır, quanta süresi bittiğinde kontrolü tekrar ele geçirerek başka bir programı çalıştırır. Oysa preemtive olmayan sistemlerde bir program çalıştırıldığında görevler arası geçişin oluşması için programcının kontrolü işletim sistemine geri vermesi gerekir. Eğer vermezse tüm sistem olumsuz yönde etkilenir ve hatta kilitlenebilir. Windows 3.x sistemleri preemtive değildir. Ancak Windows 95/98/NT sistemleri preemtive'dir.

5. Windows alt işlemli çalışmanın mümkün olduğu bir sistemdir.

            Alt işlem(thread) bir programın bağımsız olarak çizelgelemeye giren bir parçasına denir. C'de herhangi bir fonksiyon alt işlem olarak tanımlanabilir.Ancak bu fonksiyonun alt işlem olarak sisteme tanıtılması gerekir. Her program en azından bir alt işlem içerir, bu da programın kendisidir. Alt işlemler programın çalışma zamanı sırasında oluşturulur. Yani C programı main'den çalışmaya başladığında tek alt işleme sahiptir. Sonra programın akışı CreateThread fonksiyonuna gelir ve bir fonksiyon yeni bir alt işlem olarak devreye girer. Aslında bütün çizelgeleme alt işlem düzeyinde yapılır. Örneğin 3 proses söz konusu olsun, p1, p2, p3 adlı üç program çalışıyor olsun.


Çok işlemli çalışma pek çok algoritmanın gerçekleştirilmesini kolaylaştırmaktadır. Birden fala cpu'nun bulunduğu makinalarda hız ciddi biçimde artar. Aynı programın alt işlemleri arasındaki task switch zamanı farklı programların alt işlemleri arasındaki task switch zamanından daha azdır.

Çok işlemliliğin avantajları:
- Çok alt işlemden oluşan programlarda dışsal bir olay gerçekleştiğinde programın tamamı bloke olmaz, yalnızca bir alt işlem bloke olur. Bir döngü içerisinde bir olayın gerçekleşmesi ile ilgili işlemler yapan kodlar daha kolay tasarlanırlar.

6. Windows Intel sistemlerinde 4 Gb bellek kullanabilir.

            DOS işletim sistemi ancak 1 Mb belleği kontrol edebilir. Üstelik bu 1 MB belleğin yalnızca 640 Kb'lik bölümünü programlar için kullanabilir. Oysa programlar ayrıntılı özelliklere sahip oldukça bellek gereksinimi de artar. Bir Windows exe programı istenildiği kadar uzun olabilir.

7. Windows sanal bellek kullanan bir işletim sistemidir.

            Sanal belek(virtual memory) programın belli bir kısmının RAM'e yüklenerek disk ile yer değiştirmeli olarak çalıştırılması için kullanılır. Programın belirli bir bölümü RAM'e yüklenerek çalışmaya başlar, program kod ya da data bakımından RAM'de olmayan kısma erişmek istediğinde işletim sistemi programın RAM'deki bir bölümünü disk'e  diskteki bölümünü RAM'e çekerek kesiksiz çalışmayı sağlar. Bütün sanal bellek kontrolü; örneğin programın neresinin diskte tutulup tutulmayacağı gibi işlemler işletim sisteminin kontrolü altındadır. Programcının sanal bellek kullanımı üzerindeki kontrolü son derece azdır. Bütün bu işlemler işletim sistemi tarafından otomatik olarak gerçekleştirilir.
            Sanal bellek kullanımı hem mikro işlemcinin hem de işletim sisteminin ortaklaşa sağladığı bir işlemdir. Intel işlemcileri 80286 ile birlikte segment tabanlı sanal bellek, 80386 ile birlikte sayfa tabanlı sanal bellek kullanımına uygun tasarlanmıştır. Yani Windows altında toplam bellek RAM + boş disk alanı kadardır. Programın disk ile RAM arasında taşınmasına yer değiştirme(swap) denir. Program uzun RAM azsa fazla sayıda yer değiştirme olur, program da yavaş çalışır. Fiyat/Performans bakımından optimum RAM Windows 3.1 için 16Mb, 32 bit Windows sistemleri için 64 Mb civarındadır. Dinamik bellek fonksiyonlarıyla heap üzerinde yapılan tahsisatlar da sanal bellek kullanılarak gerçekleştirilir. Örneğin Excel büyük bir tabloyu yükleyebilmek için malloc fonksiyonu ile 200 Mb bellek isteyebilir, sistem bunu RAM'de bulamazsa disk üzerinde yer değiştirme dosyası üzerinde tahsis eder. Bu alan kullanılmak istendiğinde işletim sistemi otomatik olarak yer değiştirme yapar.

8. Win32 sistemlerinde her program sanki belleği tek başına kullanıyormuş gibi çalışır.

            Win32'de görevler arası geçiş sırasında bir program bellekten tamamen atılır, diğeri belleğe tamamen yüklenir. Yani bir program çalışırken diğer programlar bellekte değildir ve onlara erişilemez. Tipik bir Windows'daki bellek yönetimi düşük seviyeli 2Gb'lık sana bellek programlar için, yüksek anlamlı 2GB'lık sanal bellek ise işletim sistemi içindir.



Çalışma sırası programa geldiğinde sanal bellek desteğiyle program 2Gb'lık alana yüklenir. Win32'de bütün göstericiler 4 byte uzunluğundadır ve bütün belleği görebilir. Örneğin iki farklı programda malloc fonksiyonu aynı adresi vermiş olabilir, ancak bu iki program tamamen izole çalıştığına göre iki adresin birbirleriyle hiç ilişkisi yoktur. Yani Windows'da bir adres söz konusu olduğu zaman o adresin hangi programa ilişkin olduğunu da bilmek gerekir. Yüksek anlamlı 2 Gb'lık alan görevler arası geçişten etkilenmez.

9. Windows dosya formatları.

            İlk obj formatı 1978'deki Intel OMF(dos) formatıdır. Win32 sistemleriyle beraber COFF formatına geçilmiştir.
            İlk exe formatı DOS'ta MZ(Mark Zibikowski) formatı olarak, Windos 3.x ile beraber NE(new executable) formatı kullanılmaya başlanmıştır. Win32 sistemleriyle beraber PE(portable executable) formatı kullanılmaya başlanmıştır. PE formatı mikro işlemciden ve işletim sisteminden bağımsız bir format olma iddiasındadır.

10. Kaynak kullanımı.

            Bir Windows programındaki bitmap, dialog penceresi, menu, icon, string gibi görsel elemanlara kaynak(resource) denir. Kaynaklar ya doğrudan kaynak dili kullanılarak yazılırlar ya da görsel olarak kaynak editörlerinde oluşturulurlar. Tabii kaynak editörü bu görsel belirlemelerden kaynak kodunu oluşturur. Kaynak dilinde yazılmış kaynak programının uzantısı rc'dir. Bu program ismine kaynak derleyicisi denilen özel bir derleyicide derlenir ve kaynak verisi res uzantılı bir dosya halinde oluşturlur. Bu res dosyası linker tarafından PE formatının kaynak bölümü denilen bir bölümüne yerleştirilir(resource binding). Rc dosyası derlenirken gerekli bütün grafik dosyalar bulundurulmalıdır. Ancak derlendikten sonra bu dosyaların içerisindeki veriler res dosyasına aktarılır, yani rs dosyası bütün grafik bilgilerini içerir. Bu res dosyası PE formatına yazıldıktan sonra grafik dosyalarına, rc dosyasına, res dosyasına programın çalışması için gereksinim kalmaz. PE formartının kaynak bölümü tamamen dokümante edilmiştir. Bu kaynak bölümünde değişiklik yapılmasına izin veren kaynak editörleri vardır. Kaynak kullanımından amaç bir programda hiç onu derleyip link etmeden görsel değişiklikleri kaynak editörü kullanarak yapabilmektir(res dosyası üzerinde doğrudan değişiklik yapılması uygun değildir. Bu kaynak kısmı PE formatından çıkartyılabilir ve yeni bir kaynak kodu oraya yerleştirilebilir.).

11. Windows sisteminde dinamik kütüphaneler yoğun olarak kullanılır.

            Kütüphane dosyaları lib ve dll uzantılı olmak üzere ikiye ayrılır. Lib dosyası içerisinden bir fonksiyon çağırılmış olduğunda linker fonksiyonların kodlarını alarak exe dosyasının içerisine yazar. Yani dosyayı çalıştırmak için lib dosyasına ihtiyaç olmaz. Oysa dll içerisindeki bir fonksiyon çağırıldığında linker yalnızca fonksiyonun hangi dll içerisinde olduğunu PE formatının import bölümüne yazar. Program çalıştırılacağı zaman Windows, PE formatının import bölümünü okur, bu programın hangi dll dosyalarını kullandığını tespit eder, programla birlikte bu dll dosyaslarını da yükler. Bu durumda dinamik kütüphane kullanan bir program ancak bu dinamik kütüphanelerle birlikte taşınarak çalıştırılabilir. Dll dosyaları tamamen PE formatındadır. Yani bir exe dosya da bir dll'miş gibi kullanılabilir.

12. Windows sistemleri UNICODE tablosunu desteklemektedir.

            Bir yazı ASCII tablosunda her karakteri 1 byte olacak biçimde temsil edilir. Bu durumda 256 değişik karakter bulunabilir. Oysa UNICODE tablosunda her karakter 2 byte ile belirtilir. Dünyada kullanılan bütün semboller bu tabloya yerleştirlimiştir. Bir yazının başlangıç adresini parametre olarak alan Windows API fonsiyonlarından 2 tane vardır. Bir tanesi yazıyı ASCII tablosuna bakarak yorumler, diğeri UNICODE tablosuna bakarak yorumlar. Eğer UNICODE sistemi kullanılırsa programdaki yazılar dilden bağımsız hale getirilir.

Macar Notasyonu

            Macar notasyonu Microsoft çalışanlarından Charles Simoney tarafından geliştirilmiştir. Macar notasyonu değişkenlere isim verme ile ilgili belirlemelerden oluşur. Amaç bir değişkene bakıldığında onun türünün ve hangi amaçla kullanıldığının tespit edilmesidir.

Özellikleri:

- Değişken isimleri değişkenin türünü anlatan küçük harf ön eklerle başlar, daha sonra her sözcüğün ilk harfi büyük harfle başlar.

Önek

Anlamı
l
long
w
WORD (işaretsiz iki byte)
dw
DWORD (işaretsiz dört byte)
d
double
c
char
p
gösterici
pl
long gösterici
pv
void gösterici
psz
sonu NULL ile biten yazıya ilişkin char göstericisi
f
flag(aynı zamanda float)
b
bool
lp
uzak gösterici
u
unsigned int


int türü çok fazla kullanıldığı için ön ek almaz. Ancak küçük harfle başlatılır, sonraki sözcüğün ilk harfi büyük harfle başlatılır(totalCost gibi).

- Macar notasyonunda alt tire kullanılmaz. Fonksiyon isimlerinin her sözcüğünün ilk harfi büyük yazılır(CreateWindow gibi). Fonksiyon isimleri önce eylemle başlar nesneyle devam eder.

- Değişken isimleri uzun olma eğilimindedir.

            Macar notasyonu Windows işletim sisteminin programlamaya ilişkin dokümantasyonlarında Microsoft tarafından yoğun bir biçimde kullanılmaktadır. Windows programlamada Macar notasyonunun kullanılması gelenek haline gelmiştir.

- Yapı türünden değişkenlere ön ek getirilmez. İlk sözcük küçük harf sonraki bütün sözcüklerin ilk harfleri büyük harfle yazılır.

Windows.h Dosyası

            Windows programlamasında windows.h isimli başlık dosyası ön işlemci ve derleyici için include edilmelidir. Bu dosyanın içerisinde API fonksiyonlarının prototipleri, sembolik sabitler, typedef isimleri, yapı bildirimleri vs gibi bildirimler vardır. Bu dosya ön işlemci tarafından açıldığında çok büyük bir kod derleme işlemine sokulur.

API(Application Programming Interface) Fonksiyonları

            Bir işletim sisteminin çalışırken kendisinin kullandığı, programcının da dışarıdan çağırabileceği fonksiyonları vardır. Bunlara sistem fonksiyonları denir. Sistem fonksiyonlarına unix'te System Call, Windows'da ise API denilmektedir. Sistem fonksiyonları işletim sistemiyle birlikte belleğe yüklenirler. API fonksiyonları bütün programlama dillerinde ve geliştirme ortamlarında işlemleri yapabilmek için derleyici sistemleri tarafından çağırılır. Örneğin Visual Basic'te programcı API kavramını bilmese de aslında derleyici sistemi bütün işlemlerini sistem fonksiyonlarını çağırarak gerçekleştirir. Windows API fonksiyonları dll dosyaları içerisindedir ve sistemle beraber otomatik olarak yüklenirler. API fonksiyonları üç gruba ayrılır:

1. Kernel API'ler: Kernel32.dll içerisindedir. Sistemin aşağı seviyeli çalışmalarıyla ilgili sistem fonksiyonları bulunur.
2. User API'ler: User32.dll içerisindedir. Programcının doğrudan üzerinde çalıştığı konularla ilgili olan sistem fonksiyonlarıdır. Örneğin pencere işlemleri için gereken API'ler, kontrollere ilişkin API'ler vs.
3. Graphics API'ler: Gdi32.dll içerisindedir. Bütün grafik çizimlerine ilişkin sistem fonksiyonlarını içerir.

Bir Windows Programının Derlenerek Çalıştırılması

            Bir Windows programının exe uzantılı hale getirilebilmesi için birkaç aşama gereklidir. Önce uzantısı c olan dosyalar derleyici tarafından derlenerek obj dosyalar dönüştürülür, sonra uzantısı rc olan kaynak dosyaları kaynak derleyicisi tarafından derlenerek res uzantılı hale getirilir, en sonunda linker tarafından obj ve res dosyaları link edilerek exe uzantılı dosya elde edilir.

c dosyaları
rc dosyaları
Derleyici
Kaynak derleyicisi
obj dosyaları
res dosyaları
linker
exe (PE format)


Aslında linker programı exe dosyasının içerisine res dosyasını yeleştirebilecek biçimde yazılmıştır. Yani işlemler şöyle de yürütülebilir: Önce yalnızca obj'larla exe elde edilir, daha sonra res dosyası tekrar linker kullanılarak exe içerisine yerleştirilir(resource binding). Burada açıklanan işlemler komut satırından manual olarak yapılabilir. Ancak derleyici sistemleri proje dosyası kullanımıyla bu işlemleri kolaylaştırmaktadır. Bu çalışma biçimine göre önce bir proje dosyası açılır, sonra bu dosya içerisine c ve rc dosyaları yerleştirilir. Program çalıştırılacağı zaman derleyici sistemi önce c dosyalarını c derleyicisiyle, rc dosyalarını ise kaynak derleyicisi ile derler ve hep birlikte link eder.

Windows.h İçerisindeki typedef İsimleri

            Windows programlamasında taşınabilirlik sağlamak amacıyla tür belirten anahtar sözcükler yerine typedef isimleri yoğun olarak kullanılır. Bu tür tanımlamalarının başlıcaları şunlardır:

typedef unsigned char BYTE

typedef unsigned short int WORD

typedef unsigned long int DWORD

typedef int BOOL
            /*Örneğin BOOL bir fonksiyonun başarılı ya da başarısız olduğu bilgisi için kullanılabilir. BOOL demek aslında int demektir ancak okunabilirliği arttırır. Aynı zamanda BOOL türüne eşlik eden iki makro vardır. TRUE ve FALSE. #define FALSE 0 #define TRUE 1*/
typedef unsigned int UINT
            /*Aslında Win32'de UINT ile DWORD arasında işlevsel bir fark yoktur. Çünkü int türüyle long türü aynı uzunluktadır.*/
typedef int INT

typedef float FLOAT


/*
DOS ve Win3.1 sistemlerinde yakın ve uzak gösterici kavramları vardır. Dolayısıyla near ve far anahtar sözcükleri geçerli bir biçimde kullanılır. Oysa 32 bit Windows sistemlerinde yakın ve uzak gösterici diye kavramlar yoktur. Bütün göstericiler 4 byte uzunluğundadır. Win32'de near ve far anahtar sözcükleri tanımlı değildir, kullanılması error oluşturur. Ancak Win3.1 sistemleriyle uyumu korumak için near ve far anahtar sözcükleri windows.h içerisindeki
#define far
#define near
satırlarıyla silinirler. Yani biz near ya da far anahtar sözcüklerini kullansak bile windows.h dosyası include edildiği için bu sözcükler koddan çıkartılır. Böylece error oluşmaz. Bu iki satır Win3.1 programlarının Win32'de hiç değişiklik yapılmadan kullanılabilmesini sağlamak için konulmuştur. Göstericilere ilişkin typedef tanımlamaları Win3.1'de oluşturulmuştur. Dolayısıyla yakın ve uzak gösterililer için farklı isimler uydurulmuştur.
*/
typedef char far *LPSTR;

typedef char *PSTR;
/*far anahtar sözcüğü silindiği için LPSTR ile PSTR aynı türdür, karakter türünden gösterici anlamına gelir. Ancak hala Win3.1'den alışkanlıkla LP ön ekli typedef isimleri daha fazla kullanılmaktadır.*/
typedef unsigned short int *PWORD, *LPWORD;

typedef int * PBOOL;

typedef unsigned int *LPUINT, *PUINT;

typedef const char *LPCSTR, *PCSTR;

typedef unsigned int WPARAM;

typedef long int LPARAM;
/*Win3.1'de WPARAM 2 byte LPARAM ise 4 byte uzunluğunda işaretsiz tam sayı biçimindeydi. Win32'de aralarında fark yoktur.*/
#define CONST const
/*CONST yerine const yerleştirilir.*/
typedef void *PVOID, *LPVOID;


Handle Türleri

            İsmine handle denilen ve ilk harfi 'H' ile başlayan bütün tür isimleri gerçekte void türünden gösterici anlamındadır.
HWND
WICON
HCURSOR
Macar notasyonunda bu türde değişken tanımlanırken değişken isminin önüne 'h' getirilir. Örneğin: HWND hwnd; /*veya void *hwnd;*/

Bir Windows Programının Organizasyonu

            Bir Windows programı DOS ve UNIX'te olduğu gibi main fonksiyonundan değil, WinMain fonksiyonundan çalışmaya başlar. WinMain fonksiyonunun parametreleri main fonksiyonundan farklıdır ve işletim sistemi tarafından geçirilir. WinMain fonksiyonunun geri dönüş değeri int olmak zorundadır.
            Fonksiyonun geri dönüş değerinin soluna yazılan anahtar sözcüğe fonksiyonun çağırma biçimi(calling convention) denir. Bu çağırma biçimleri pascal, cdecl veya stdcall olabilir. Microsoft firması bu anahtar sözcükleri _pascal, _cdecl, _stdcall olarak tanımlamıştır. Ancak daha sonra ANSI uyuşumu sağlamak için çift alt tireli şekillerini standartlaştırmıştır. Bugün bütün derleyiciler üç biçimi de desteklemektedir. Bu anahtar sözcüklerden hiçbiri yazılmazsa C'deki fonksiyonlar için __cdecl yazılmış kabul edilir. C++'taki sınıfa ilişkin üye fonksiyonlar için varsayılan durum __stdcall biçimindedir. Windows.h içerisinde #define WINAPI __stdcall tanımlaması vardır.  WinMain fonksiyonunun çağırılma biçimi __stdcall olmak zorundadır. WINAPI zaten bu demektir(Eğer burada WINAPI ya da __stdcall yazmazsak default olarak __cdecl anlaşılır, bu da programın hatalı çalışmasına yol açar).

WinMain Fonksiyonunun Parametreleri

            Bu parametreler işletim sistemi tarafından geçirilir.

- HINSTANCE hInstance
            Buraya geçirilen değer exe dosyanın çalıştırılma sırasında belleğe yüklenme adresidir. Programın yüklenme adresi aslında PE formatının içerisine yazılmaktadır. Yükleme adresi derleyici seçeneklerinden çeşitli biçimlerde değiştirilebilir. Ancak değiştirilmesi için ciddi bir neden yoktur. Win9x sistemlerinde bu yükleme adresi default olarak 0x400000(4 Mb), WinNT sistemlerinde 0x100000(1Mb) biçimindedir. Yani farklı programların hInstance değerleri farklı olabilir.
            16 bit Windows'da hInstance değeri programın yüklenme adresi değil programın module database adresidir. Yani 16 bit Windows'da her programın hInstance değeri birbirinden farklıdır. hInstance değeri pekçok API fonksiyonuna parametre olarak geçirilmektedir. Örneğin kaynak(resource) üzerinde işlem yapan bir API fonksiyonu bu değeri parametre olarak ister, aslında fonksiyon bu değerden faydalanarak PE formatının yüklenme adresini alır. PE formatı içerisinde kaynak bölümünün nerede başladığı bilgisi vardır. Fonksiyon kaynak bilgilerine bu biçimde erişir. hInstance değeri WinMain içerisinde global bir değişkene atanırsa her fonksiyon içerisinden kullanılabilir.

- HINSTANCE hPrevInstance
            Bu değer 32 bit Windows sistemlerinde her zaman NULL olarak geçirilir. 16 bit Windows'da hPrevInstance programın kopyası birden fazla çalıştırılıyorsa önceki kopyasının hInstance değeri olarak geçirilir. Tabii program ilk kez çalıştırıldığında hPrevInstance 0 olacaktır. 16 bit Windows'da bir programın birden fazla çalıştırılması istenmiyorsa aşağıdaki gibi bir işlem yapılabilir.

if (hPrevInstance)
    return 0;

            Bazı işlemlerin yalnızca programın ilk çalıştırılmasında yapılması isteniyorsa:

if (!hPrevInstance) {
...........
........
........
........
}

32 bit Windows sistemlerinde hPrevINstance her zaman NULL olduğuna göre programın ilk kez çalıştırılıp çalıştırılmadığı bu yöntemle anlaşılamaz(Bu işlem için mutex nesneleri kullanılmalıdır).

- LPSTR lpszCmdParam
            Komut satırı argümanlarını gösteren yazının başlangıç adresini belirtir. Komut satırı argümanları tek yazı olarak tutulur.

- int nCmdShow
            Programın ana penceresinin program çalıştırıldığında hangi büyüklükte ilk kez görüntüleneceğini belirtir. Bu parametre 3 seçenek alabilir. Bunlar:

SW_MAXIMIZE
SW_MINIMIZE
SW_RESTORE

            Bir Windows programı hiçbir pencere olmadan da çalışabilir. Ancak tabi istenen bu değildir.

Programın Ana Penceresinin Yaratılması

            Programa ilişkin bütün pencerelerin yaratılması CreateWindow API fonksiyonu ile yapılmaktadır. Bu fonksiyonun birinci parametresi WNDCLASS türünden bir yapı değişkeninin adresini alır. Bu durumda önce WNDCLASS türünden bir yapı değişkeni tanımlanıp içinin doldurulması gerekir. CreateWindow bu yapının içerisindeki bilgileri kullanmaktadır.

WNDCLASS Yapısı

            WNDCLASS yapısı bir pencerenin temel özelliklerini barındıran bir yapıdır.

WNDCLASS Yapsının Elemanları

- UINT style
            Pencerenin genel türüyle ilgili bilgileri içerir. Bu eleman aslında her biti bir özellik olarak ele alınacak biçimde düşünülmüştür. Bu elemana genellikle CS_HREDRAW | CS_VREDAW değeri girilir(Windows.h içerisinde birçok sembolik sabit vardır. Bu sembolik sabitlerin hangi amaçla kullanıldığının kolay anlaşılabilmesi için isimlendirilmeleri de okunabilir bir biçimde yapılmıştır. Bir sembolik sabitin isimlendirilmesi genel olarak XX_ISIM biçimindedir. Burada XX sembolik sabitin hangi konuyla ilgili olduğunu anlatan bir ön ektir).

- WNDPROC lpfnWndProc
            Pencere fonksiyonunun başlangıç adresini tutan göstericidir.

- int cbClsExtra
  int cbWndExtra
            Pencere biçimine ilişkin yapı için ayrılacak ekstra alanların byte cinsinden değeridir. Ekstra alana nadiren gereksinim duyulur, genelde değeri sıfırdır.

- HANDLE hInstance
            Bu elemana WinMain fonksiyonuna geçirilen hInstance değeri geçirilmelidir.


- HICON hIcon
            Program minimize edildiğinde gösterilecek icon görüntüsünü belirlemek için kullanılır. Genellikle bu elemana Windows'un önceden tanımlanmış standart icon'larından biri yerleştirilir. İskelet programda bu elemana LoadIcon API fonksiyonu çağırılarak değer atanmıştır.
LoadIcon(NULL, IDI_QUESTION);

- HCURSOR hCursor
            Windows programlamasında cursor mouse'un hareket ettirildiğindeki gösterici şekili olarak kullanılır. Mouse oku bir pencerenin sınırları içerisinde gezdirildiğinde istenilen bir şekle dönüştürülebilir. Bu eleman bu şeklin belirlenmesinde kullanılır. İskelet Windows programında bu elemana LoadCursor API fonksiyonunun geri dönüş değeri atanmıştır.
LoadCursor(NULL, IDC_ARROW);
            Burada belirlenen mouse şekli ok biçimindedir.

- HBRUSH hbrBackground
            Bu eleman pencerenin zemin rengini belirlemekte kullanılır. Bu elemana iskelet Windows programında GetStockObject fonksiyonuyla elde edilen değer atanmıştır.
GetStockObject(WHITE_BRUSH);

- LPCTSTR lpszMenuName
            Program menuye sahip olabilir ya da olmayabilir. Eğer olacaksa buraya menu kaynağının ismi girilmelidir.

- LPCTSTR lpszClassName
            Her WNDCLASS yapısının bir ismi vardır. Bu isim CreateWindows fonksiyonuna parametre olarak geçirilir. Yani aslında CreateWindow fonksiyonu bu isimden hareketle bu yapının içerisindeki bilgileri elde eder.
            WNDCLASS yapısının içi doldurulduktan sonra bu yapının sisteme tanıtılması gerekir. Bu tanıtma işlemi RegisterClass API fonksiyonu ile yapılır. Bu API fonksiyonu WNDCLASS türünden bir yapı değişkeninin adresini parametre olarak alır. WNDCLASS yapısının sisteme tanıtılması işlemi 32 bit Windows sistemlerinde programın her kopyası için yapılmak zorundadır. Ancak 16 bit Windows sistemlerinde bu işlem yalnızca ilk kopya için yapılmalıdır. Bunu yapan kod 16 bit Windows sistemleriyle uyumu korumak için if (!hPrevInstance) { }kod bloğunun içinde yapılır. RegisterClass fonksiyonu WNDCLASS yapısına ilişkin bu bilgileri sistem bölgesine kopyalar. Herhangi bir API fonkiyonu isterse bu bilgilere ulaşabilir(Win32'de program sonlandırıldığında o programın sisteme tanıttığı bütün WNDCLASS bilgileri sistemden boşaltılır).

Programın Ana Penceresinin Yaratılması

            Pencerenin yaratılması CreateWindow API fonksiyonu ile yapılır.

CreateWindow Fonksiyonunun Parametreleri

- LPCTSTR lpszClassName
            Bu parametre daha önce sisteme tanıtılmış olan WNDCLASS yapısının ismini verir. Bu ismi alan CreateWindow sistem alanına ulaşarak sisteme tanıtılmış olan bütün yapılar arasından uygun olanı alır.

- LPCTSTR lpszWindowName
            Pencerenin başlık yazısını belirlemek için kullanılır.

- DWORD dwStyle
             Pencerenin görüntü biçimini belirlemekte kullanılır. Bu değişken 32 bitten oluşmaktadır. Her bit bir özelliğin olduğunu ya da olmadığını belirlemekte kullanılır. Pencere biçimlerine ilişkin windows.h içerisinde tanımlanmış WS_ ile başlayan bir grup sembolik sabit vardır. Bu sembolik sabitlerin yalnızca bir biti 1 diğer bitleri 0'dır. Bu sembolik sabitler bit OR işlemine sokularak çeşitli özelliklerin birlikte sağlanması için kullanılabilirler.

Başlıca Pencere Biçimleri

- WS_VISIBLE
            Yaratılır yaratılmaz pencerenenin görüntülenmesini sağlar.
- WS_BORDER
            Penerenin sınır çizgilerinin görünmesini sağlar.
- WS_CAPTION
            Başlık kısmının olmasını sağlar.
- WS_SYSMENU
            Sistem menüsünün görüntülenmesini sağlar.
- WS_OVERLAPPED
            Pencerenin başlık kısmı ve sınır çizgilerinin olmasını sağlar.
- WS_OVERLAPPEDWINDOW
            Windows.h içerisindeki bir sembolik sabit biçimindedir. WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX.
İskelet programda pencere biçimi olarak WS_OVERLAPPEDWINDOW olarak seçilmiştir. En sık kullanılan pencere biçimi budur.

- int x
  int y
  int nWidth
  int nHeight
            Pencerenin ekrandaki ilk araboyut(restore) koordinatlarıdır. x, y sol üst köşenin koordinatlarıdır. nWidth, nHeight yatay ve düşey uzunluklarıdır. İskelet programda bu değerler,
CW_USEDEFAULT
0
CW_USEDEFAULT
0
olarak girilmiştir. Pencerenin ilk görüntüsü masaüstünü ortalayacak biçimde yerleştirilir.

- HWND hWndParent
            Pencereler üst pencere(parent window) ve alt pencere(child window) olmak üzere iki kısma ayrılır. Üst pencereler masa üstünde herhangi bir yere hareket ettirilebilirler. Oysa alt pencereler üst pencerelerin sınırları dışarısına çıkartılamaz. Alt pencerenin de alt penceresi olabilir(Aslında üst pencere masa üstünün alt penceresiymiş gibi de düşünülebilir). Aslında Windows'un push button, radio button, check box gibi görsel elemanları birer alt pencerdir. Bu tür özel alt pencerelere control denir. CreateWindow fonksiyonunun geri dönüş değeri HWND türündendir. Bu değere pencerenin handle değeri denir. Bir pencere yaratıldığında pencerenin bütün bilgileri sistem içerisinde gizli bir bölgeye aktarılır. Fonksiyon aslında bu bilginin aktarıldığı bölgenin başlangıç adresini verir. Pencereyle ilgili işlem yapan bütün API fonksiyonları bu handle değerini parametre olarak alırlar. Handle değerini alan API fonksiyonları ilgili pencerenin bütün bilgilerine erişebilir. Yani handle değeri hangi pencereyle ilgili işlem yapılacağını belirlemekte kullanılır. CreateWindow fonksiyonu hem üst pencere hem de alt pencere yaratılmasında kullanılmaktadır. Eğer üst pencere yaratılacaksa hWndParent parametresi NULL olarak, alt pencere yaratılacaksa hangi üst pencerenin alt penceresi olduğunu belirtmek için üst pencerenin handle değeri olarak girilmesi gerekir. İskelet programda üst pencere yaratılması söz konusu olduğu için NULL değeri girilmiştir.

- HMENU hMenu
            Pencere menüye sahip olabilir. Eğer bu menü WNDCLASS yapısı içerisinde belirlenmemişse burada belirlenebilir. İskelet programda menü olmadığı için bu parametre NULL olarak girilmiştir.

- HANDLE hInstance
            WinMain fonksiyonundan alınan hInstance değeri bu parametreye girilmelidir.

- LPVOID lpParam
            Pencere yaratıldığında ek bir veri alanı oluşturmak istenebilir. Bu parametre bu alanın başlangıç adresini tutar. İskelet programda NULL olarak girilmiştir. Bu değer böyle bir alanın kullanılmayacağını belirtir.

CreateWindow Fonksiyonunun Geri Dönüş Değeri

            Fonksiyonun geri dönüş değeri pencere başarılı bir biçimde yaratılmışsa pencerenin handle değeridir, başarısızlık durumunda fonksiyon NULL değeri ile geri döner. İskelet programda yaratılma işleminin başarısı kontrol edilmemiştir. Aslında bu işlemin başarısının kontrol edilmesi tavsiye edilir. Pencerenin yaratıldığında görüntülenip görüntülenmeyeceği pencere biçimindeki WS_VISIBLE parametresine bağlıdır. İskelet programda yaratılır yaratılmaz görüntülenmemektedir.


Yaratılmış Pencerenin Görüntülenmesi

            Bir pencere WS_VISIBLE pencere biçimiyle yaratılmışsa yaratılır yaratılmaz zaten görüntülenir. Ancak değilse ShowWindow API fonksiyonu ile görüntülenir.

BOOL ShowWindow(HWND hWnd, int nExitCode);

            Fonksiyonun birinci parametresi görüntülenecek pencerenin handle değeri, ikinci parametresi ise görüntülenme biçimidir. Görüntülenme biçimi SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE olabilir.
(Bir fonksiyonun geri dönüş değeri BOOL ise başarı bilgisinin verildiği anlaşılır. BOOL değer mantıksal olarak 0 ya da 0 dışı bir değer olarak değerlendirilir. Örneğin ShowWindow başarılı ise 1'e değil 0 dışı herhangi bir değere geri dönmektedir.)
            Ana pencere yaratıldıktan sonra içsel görüntünün güncelleştirilmesi için WM_PAINT mesajı gerekebilir. Bunu sağlamak için UpdateWindow API fonksiyonu çağırılır.

İskelet Programın Aşamaları

            Pencereli bir Windows programı tipik olarak 3 aşamadan geçilerek oluşturulur.

1. WNDCLASS yapısının içi doldurularak sisteme tanıtılması aşaması,
2. Pencerenin yaratılarak görüntülenmesi aşaması,
3. Mesaj dögüsünün oluşturulması ve pencere fonksiyonunun tasarımı.

Mesaj Kavramı

            DOS işletim sisteminde klavye ve mouse bilgileri programcının koda yerleştirdiği fonksiyonlar yardımıyla elde edilir. Örneğin getchar() fonksiyonu klavyeden bir tuşa basılana kadar bekler, basılan tuşun bilgisini alarak işlemini sonlandırır. Oysa Windows sistemlerinde klavye ve mouse gibi giriş bilgileri programcının çağırdığı bir fonksiyonla değil, Windows sistemlerinin kendisi tarafından ilk elden alınır. Windows sistemlerinde sistem tarafından tespit edilen girdi bilgilerine mesaj denir. Her girdi bilgisinin yani mesajın hangi nedenden dolayı oluştuğunu açıklayan bir türü vardır. Örneğin mesaj klavyede bir tuşa basılmasından dolayı oluşmuş olabilir ya da mouse ile tek tıklama ya da çift tıklama sonucunda oluşmuş olabilir. Windows oluşan bu mesajı MSG yapısı biçiminde ifade ederek programın mesaj kuyruğuna yerleştirir. Her programın(32 bit Windows sistemlerinde aslında her alt işlemin) bir mesaj kuruğu vardır. Mesaj kuyruğu aslında MSG türünden bir yapı dizisi biçimindedir. MSG yapısı şöyledir:

typedef struct tagMSG {     // msg 
    HWND   hwnd;      
    UINT   message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD  time;
    POINT  pt;
} MSG;


MSG Yapısının Elamanları

- HWND hWnd
                Her pencerenin bir mesaj kuyruğu yoktur. Her programın bir mesaj kuyruğu vardır. Yani bir program 10 tane pencere yaratmış olsa bile bu pencerelerin herhangi birisinde oluşan girdi işlemi aynı kuyruğa yazılacaktır. Yapının bu elemanı programın hangi penceresine ilişkin bir mesaj oluştuğunu belirtir.

- UINT message
                Bu eleman mesajın hangi sebepten kuyruğa yazıldığını anlatan bir sayı içerir. Bir mesaj yüzlerce sebepten dolayı kuyruğa yazılabilir. Ancak mesajın nedenleri sayısal düzeyde konuşulmaz. Windows.h içerisinde tüm bu sayılar WM_ ile başlayan sembolik sabitlerle tanımlanmıştır. Yani örneğin 108 numaralı mesaj yerine WM_XXXXX mesajı biçiminde durum ifade edilir.

- WPARAM wParam
   LPARAM lParam
                WPARAM aslında unsigned int türüdür. Unsigned int türü 16 bit Windows sistemlerinde 2 byte uzunluğundaydı. Ancak 32 bit Windows sistemlerinde 4 byte'lık bir bilgidir. Burada W ön eki 16 bit Windows sistemleri kullanılırken isimlendirilmiştir. 32 bit sistemlere geçildiğinde bu isimlendirmenin kullanılmasına devam edilmiştir. LPARAM unsigned long türüdür ve her iki sistemde de 4 byte uzunluğundadır. Bu elemanlara mesaja bağlı olan ek bilgiler yerleştirilir. Örneğin WM_CHAR mesajında wParam basılan tuşun ASCII sıra numarasını içerirken WM_LBUTTONDOWN mesajında basılan noktanın koordinat bilgisini içermektedir. Her mesaj için bu elemanlara hangi bilgilerin yerleştirildiği ayrıca öğrenilmelidir.

- DWORD time
                Mesajın gönderildiği zaman bilgisidir.

- POINT pt
                Bu eleman bazı mesajlarda ekrana ilişkin koordinat bilgisini tutmak amacıyla kullanılır.

Mesaj Döngüsü

                Mesajlar sistem tarafından kuyruğa yazılır, ancak bu mesajların alınarak işlenmesi programcı tarafından yapılır. Programcı mesajları alarak önce bu mesajları anlamlandırır, daha sonra uygun işlemleri yapacak kodları çalıştırır. Programa ilişkin pencere kapatılıp program sonlandırılacağı zaman bu işlem de Windows tarafından WM_QUIT mesajı olarak kuyruğa yazılır. Yani bir döngü içerisinde mesajların sürekli alınarak işlenmesi WM_QUIT mesajı görüldüğünde de döngü sonlandırılarak programın bitirilmesi gerekir.

GetMessage Fonksiyonu

                GetMessage kuyrukta bulunan ilk mesajı alır ve bu mesajı kuyruktan siler. Fonksiyonun prototipi:


BOOL GetMessage(
                     LPMSG lpMsg,
                     HWND hWnd,
                     UINT wMsgFilterMin,
                     UINT wMsgFilterMax
);

                Fonksiyonun birinci paranmertesi MSG türünden bir göstericidir. Bu parametreye MSG türünden bir yapının adresi geçirilmelidir. GetMessage kuyrukta sırada bulunan mesajı alarak bu yapının içerisine yerleştirir. İkinci parametre programa ilişkin hangi pencerenin mesajlarının alınacağını belirtir. Yani GetMessage ile özellikle bir pencereye ilişkin mesajlar alınabilir. Bu parametre NULL girilirse bütün pencerelere ilişkin mesajlar alınır. Fonksiyonun üçüncü ve dördüncü parametreleri hangi aralıktaki mesajların kuyruktan alınacağını belirtir. Örneğin bu parametrelere 100 ve 120 girilirse yalnızca bu aralıkta numaralara sahip olan mesajlar alınır. Eğer bu iki parametreye 0 girilirse tüm mesajların alınacağı anlamına gelir. İskelet programda tüm mesajlar alınmaktadır. Fonksiyon eğer WM_QUIT mesajını aldıysa 0 değerine, WM_QUIT dışındaki bir mesajı aldıysa 0 dışı herhangi bir değere geri döner. GetMessage eğer kuyrukta mesaj yoksa programın çizelgeleme dışı bırakılıp bloke edilmesine yol açar. Yani programcı bakış açısıyla programın akışı GetMessage içerisinde beklemektedir. Kuyruktan sürekli olarak mesajı alan WM_QUIT görünce işlemi sonlandıran bir döngü şöyle kurulabilir:

while (GetMessage(&msg, NULL, 0, 0)) {
...........
..........
.........
}

                Mesaj döngüsünden çıkıldığında WinMain fonksiyonu da biter, bu fonkiyon bitince de program biter. GetMessage fonksiyonu ile mesaj alındıktan sonra anlamlandırılıp işlenmelidir, ancak prensip olarak mesajın mümkün olduğu kadar çabuk bir biçimde işlenmesi istenir. Eğer mesajın işlenmesi uzun sürerse GetMessage bir sonraki mesajı kuyruktan alamaz. Böylece programda herhangi bir ilerleme söz konusu olamaz. Ancak yine de mesajın işlenmesini geciktirecek ciddi sebepler olabilir. O zaman programın akışının devam etmesi nasıl sağlanacaktır? İşte alt işlemli programlama sistemi(multi-threading) bu tür problemlere çözüm bulmaktadır.

Mesajların İşlenmesi ve Pencere Fonksiyonu

                Mesajların işlenmesi ismine pencere fonksiyonu denilen bir fonksiyon tarafından yapılır. Kuyruktan mesaj alındığında DispatchMessage API fonksiyonu çağırılır. DispatchMessage fonksiyonuna parametre olarak kuyruktan alınan mesajın bulunduğu değişkenin adresi geçirilmektedir. DispatchMessage mesajın hWnd elamanına bakarak mesajın hangi pencereye ilişkin olduğunu anlar. O pencere ilişkin pencere fonksiyonunu çağırır. Bir pencere yapısının parametrik yapısı şöyle olmak zorundadır:





LRESULT CALLBACK WndProc(
                     HWND hWnd,
                     UINT message
                     WPARAM wParam
                     LPARAM lParam
);

                Fonksiyonun geri dönüş değeri LRESULT yani long olmak zorundadır. Çağırma biçimi __stdcall olmak zorundadır. Zaten CALLBACK sembolik sabiti __stdcall anlamına gelmektedir. DispatchMessage fonksiyonu mesajı alıp mesaj içerisindeki hWnd, message, wParam, lParam elemanlarını ayrıştırarak bu elemanları pencere fonksiyonunun parametresi yapmak suretiyle pencere fonksiyonunu çağırır. Yani programın akışı pencere fonksiyonumuzdan çıktığında akış DispatchMessage içerisinden devam eder.
                Mesaj döngüsünün içerisinde TranslateMessage API fonksiyonu da çağırılmaktadır. Bu fonksiyonun mesaj işlenme mekanizmasıyla ciddi bir bağlantısı yoktur. ASCII tuşlarına basıldığında WM_CHAR mesajının oluşumunu sağlar.

Pencere Fonksiyonunun Tasarımı

            Bunun için önce mesajın ne mesajı olduğunun tespit edilmesi gerekir. Bu işlem bir switch deyimiyle yapılabilir. Daha sonra mesaj parametreleri yorumlanarak case ifadeleri işlenir.

Windows Programının Sonlandırılması

            Bir Windows programı programın akışı mesaj döngüsünden çıkıp WinMain fonksiyonunun bitmesiyle sonlanır. Program akışının mesaj döngüsünden çıkması GetMessage fonksiyonunun 0 ile geri dönmesiyle sağlanır. GetMessage fonksiyonu WM_QUIT mesajını gördüğünde 0'a geri döner.

DefWindowProc API Fonksiyonu

            Bir programın en basit işlemleri yapacak biçimde sağlıklı çalışabilmesi için bir takım kritik mesajların işlenmesi gerekir. Oysa bunların işlenmesi ve bu mesajlara karşılık default bazı işlemleri yapılması uzun bir işlem yükü gerektirir. İşte DefWindowProc fonksiyonu bir mesaj için default kritik işlemleri yapabilen bir fonksiyondur. Yani pencere fonksiyonu içerisinde mesajlar işlenir, işlenmeyen mesajlar bu API fonksiyon çağırılarak işletilir. O halde en basit bir pencere fonksiyonu şöyle tasarlanabilir:

LRESULT CALLBACK WindowProc(HWND hWnd, UINT, message, WPARAM wParam, LPARAM lParam)
{
                return DefWindowProc(hWnd, message, wParam, lParam);
}              /*Tüm mesajlar default olarak işlenecektir*/

            DefWindowProc fonksiyonunun gelen mesajlara karşı hangi kritik işlemleri yaptığı bazı tür işlemlerde programcı tarafından bilinmek zorundadır.
            İşlenen mesajlar için DefWindowProc fonksiyonu çağırılmamalıdır. O halde bu fonksiyon tipik olarak switch'in default kısmına yerleştirilmelidir.

Pencere Fonksiyonunun Geri Dönüş Değeri

            Pencere fonksiyonunun geri dönüş değeri DispatchMessage fonksiyonu tarafından yorumlanır. Fonksiyonun geri dönüş değeri mesajdan mesaja değişir. Yani hangi mesaj geldiğinde neyle geri dönüleceği önceden bilinmek zorundadır. Ancak aksi söylenmediği sürece pencere fonksiyonu eğer mesajı işlemişse 0 ile geri dönmelidir. İşlememişse DefWindowProc fonksiyonunun geri dönüş değeriyle geri dönmelidir.

LRESULT CALLBACK WindowProc(HWND hWnd, UINT, message, WPARAM wParam, LPARAM lParam);
{
                switch(message) {
                               case .......... :
                                               ........
                                               ........
                                               break;
                               case .......... :
                                               ........
                                               ........
                                               break;
                               default:
                                               return DefWindowProc(hWnd, message, wParam, lParam);
                }
                return 0;
}

Pencerenin Kapatılması Sırasında Gerçekleşen İşlemler

            Bir pencereye kapatmak için klik yapıldığında ya da klavye ile Alt+F4 tuşlarına basıldığında Windows yalnızca mesaj kuyruğuna WM_CLOSE mesajını bırakır. Bu mesaja karşılık DefWindowProc DestroyWindow API fonksiyonunu çağırmaktadır. Bu API fonksiyonu pencereyi kapar ve mesaj kuyruğuna WM_DESTROY mesajını koyar. WM_DESTROY mesajı genellikle programcı tarafından işlenir. Programcı bu mesaj karşılığında PostQuitMessage API fonksiyonunu çağırmalıdır(zaten DefWindowProc fonksiyonu da default olarak PostQuitMessage fonksiyonunu çağırır), bu fonksiyon yalnızca kuyruğa WM_QUIT mesajını yerleştirir. GetMessage fonksiyonu da bu mesajı alarak 0 ile geri döner ve WinMain sonlanır.

Hiç yorum yok:

Yorum Gönderme