BG MVC Model View Controller eğitim serisi yayında...

Ana page > Programlama > Windows API Programlama > İlk Program

İlk Program

Bir önceki bölümde temel bir WinAPI programı oluşturmuş ve çalıştırarak ekranda bir pencere açılmasını görmüştük. Bu projenin main.c dosyası içeriği aşağıda yer almaktadır.


#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif

#include <tchar.h>
#include <windows.h>

/* Programın ana penceresi için fonksiyon bildirimi yapar. */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Sınıf adını global bir değişkene atar. */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* Program ana penceresi için handle değeri */
    MSG messages;            /* Program ana penceresine gönderilen mesajların kaydedildiği değişken */
    WNDCLASSEX wincl;        /* Program ana pencere sınıfına ait veri yapısı */

    /* Program ana pencere sınıfı veri yapısına değer atama */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* Windows tarafından çağrılan ve tüm mesaj işlemlerini yapan ana pencere fonksiyonu */
    wincl.style = CS_DBLCLKS;                 /* Çift tıklamaya işlem yapılmasını sağlayan stil değerini ekleme */
    wincl.cbSize = sizeof (WNDCLASSEX);       /* Bu değişkenine sizeof(WNDCLASSEX) değeri atanmalıdır. */

    /* Ön tanımlı ikon ve mouse imlecinin kullanılmasını sağlama */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                /* Menü tanımı yok. */
    wincl.cbClsExtra = 0;                     /* Pencere sınıfı için ektra byte tanımı yok. */
    wincl.cbWndExtra = 0;                     /* Pencere Instance değeri için ayrılacak ekstra byte sayısını gösterir. */    
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Ana pencere arka plan rengi için Windows'un ön tanımlı değerini kullanır. */

    /* Pencere sınıfını kaydeder, başarılı olmazsa program sona erer. */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* Program ana pencere sınıfı kaydedildiğinden, program ana penceresini oluşturma */
    hwnd = CreateWindowEx (
           0,                   /* Pencereye ek özellikler sağlar. */
           szClassName,         /* Sınıf adı */
           _T("Code::Blocks Template Windows App"),  /* Pencere başlığı */
           WS_OVERLAPPEDWINDOW, /* Ön tanımlı pencere */
           CW_USEDEFAULT,       /* Pencerenin sol üst köşesinin x koordinatını Windows belirler. */
           CW_USEDEFAULT,       /* Pencerenin sol üst köşesinin y koordinatını Windows belirler. */
           544,                 /* Ana pencere genişliği piksel olarak */
           375,                 /* Ana pencere yüksekliği piksel olarak */
           HWND_DESKTOP,        /* Ana pencerenin masaüstünün alt pencersi olduğunu gösterir. */
           NULL,                /* Menü yok. */
           hThisInstance,       /* Program Instance handler değeri */
           NULL                 /* Pencere oluşturma bilgisi yok. */
           );

    /* Ana pencereyi ekran da gösterir. */
    ShowWindow (hwnd, nCmdShow);

    /* Mesaj döngüsünü devre sokar. Bu döngü GetMessage() fonksiyonu 0 değeri döndürene kadar çalışmaya devam eder. */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Sanal tuş mesajlarını karakter mesajlarına çevirir. */
        TranslateMessage(&messages);
        /* Mesajları WindowProcedure() fonksiyonuna gönderir. */
        DispatchMessage(&messages);
    }

    /* Program dönüş değeri 0'dır - Bu değeri PostQuitMessage() fonksiyonu verir. */
    return messages.wParam;
}

/* Bu fonksiyon Windows'un DispatchMessage() fonksiyonu tarafından çağrılır. */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* Mesajlara gerekli işlemi yapar. */
    {
        case WM_DESTROY:
            PostQuitMessage (0);      /* WM_QUIT değerini mesaj kuyruğuna gönderir */
            break;
        default:                      /* İşlem yapılmayan mesajlar için */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Şimdi, programı oluşturan kodları sırasıyla açıklamaya çalışalım:

Global bidirimler

Program ilk çalıştığında, <tchar.h> ve <windows.h> dosyaları programa dahil edilir, mesajlara işlem yapan WindowProcedure() fonksiyonunun bildirimi yapılır ve sınıf adı global bir diziye atanır:


#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif

#include <tchar.h>
#include <windows.h>

/* Programın ana penceresi için fonksiyon bildirimi yapar. */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Sınıf adını global bir değişkene atar. */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

WinMain() fonksiyonu

Program çalışır çalışmaz WinMain() fonksiyonu devreye girer ve uygulama burada başlar. WinMain() fonksiyonu, DOS (Disk Operating Sistem) ortamında C programlama dili ile geliştirilen konsol programlarındaki main() fonksiyonu ile aynı işlemi gerçekleştirir. WinMain() fonksiyonu int bir değer geri döndürür.


int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)

WINAPI

windef.h dosyası içinde #define WINAPI __stdcall şeklinde tanımlanan WINAPI makrosu WinMain() fonksiyonunun __stdcall şeklinde çağrılacağını gösterir. Bu çağrı şekli derleyicinin fonksiyon argümanlarını stack'e ne şekilde koyup alacağı ve sileceği ile bir dönüş değeri alması ile ilgili kuralları belirler. __stdcall yöntemi Win32 API fonksiyonlarını çağırmak için kullanılır.

HINSTANCE hThisInstance

Program .exe dosyasının bellekteki halinin Handle (*)'ı. hInstance değeri kaynakları yükleme ve diğer işlemleri gerçekleştirmek için kullanılır.

HINSTANCE hPrevInstance

Win32 program için daima NULL bir değerdir. hPrevInstance, Win16 sistemlerde programın çalışan önceki hali için bir Handle olarak kullanılır.

LPSTR lpszArgument

Tek bir karakter dizisi halinde verilen, programın adı hariç olmak üzere, komut satırı argümanlarıdır. C programlama diline ek olarak Microsoft için tanımlanmış özel veri türlerinden bir tanesi de LPSTR verisidir. Bu veri winnt.h dosyasında typedef CHAR *LPSTR şeklinde tanımlanmıştır. Windows veri türlerine Windows veri türleri adresinden ulaşabilirsiniz.

int nCmdShow

ShowWindow() fonksiyonuna geçirilebilecek integer bir değer gösterir.

* HANDLE: winnt.h dosyasında typedef PVOID HANDLE şeklinde tanımlanmış bir değerdir.

WinMain() fonksiyonu değişken bildirimleri

WinMain() fonksiyonunun ilk üç satırında sıra ile program penceresine ait bir Handle, mesajları kaydetmek için bir yapı ve pencere sınıf değerleri bir yapı bildirimi yapılır:


HWND hwnd;               /* Program ana penceresi için handle değeri */
MSG messages;            /* Program ana penceresine gönderilen mesajların kaydedildiği değişken */
WNDCLASSEX wincl;        /* Program ana pencere sınıfına ait veri yapısı */

HWND hwnd

HWND windef.h dosyası içinde tanımlanmış olan pencere Handle değeridir.

MSG messages

MSG winuser.h dosyası içinde aşağıdaki şekilde tanımlanmış olan bir yapıdır:

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

HWND hwnd

Pencere fonksiyonu mesajı alan pencerenin Handle değeri. Bir Thread mesajı olduğunda bu eleman NULL bir değer alır.

UINT message

Sadece düşük WORD değeri kullanılan mesaj tanımlayıcısı (Yüksek WORD sistem tahsisli). UINT veri türü, windef.h dosyasında tanımlı, 0-4294967295 arasındaki tamsayıları kapsayan 32 bit genişliğinde unsigned int bir değerdir.

WPARAM wParam

message elemanına bağlı olarak mesaj hakkında ek bilgi içerir. WPARAM veri türü, windef.h dosyasında typedef UINT_PTR WPARAM şeklinde tanımlanmış bir değerdir. UINT_PTR veri türü ise, basetsd.h dosyasında typedef unsigned int UINT_PTR şeklinde tanımlanmış bir değerdir.

LPARAM lParam

message elemanına bağlı olarak mesaj hakkında ek bilgi içerir. LPARAM veri türü, windef.h dosyasında typedef LONG_PTR LPARAM şeklinde tanımlanmış bir değerdir. LONG_PTR veri türü ise, basetsd.h dosyasında typedef long LONG_PTR şeklinde tanımlanmış bir değerdir.

DWORD time

Mesajın gönderildiği zamanı gösterir. DWORD veri türü, windef.h dosyasında typedef LONG_PTR LPARAM şeklinde tanımlı 0-4294967295 arasındaki tamsayıları kapsayan 32 bit genişliğinde unsigned int bir değerdir.

POINT pt

Mesaj gönderildiği andaki kursor pozisyonunu gösterir. POINT veri türü, içinde LONG x ve LONG y olmak üzere iki long değer bulunan bir yapıdır:

typedef struct tagPOINT {
  LONG x;
  LONG y;
} POINT;

WNDCLASSEX wincl

winuser.h dosyası içinde aşağıdaki şekilde tanımlanmış olan bir yapıdır:

typedef struct _WNDCLASSEXA {
	UINT cbSize;
	UINT style;
	WNDPROC lpfnWndProc;
	int cbClsExtra;
	int cbWndExtra;
	HINSTANCE hInstance;
	HICON hIcon;
	HCURSOR hCursor;
	HBRUSH hbrBackground;
	LPCSTR lpszMenuName;
	LPCSTR lpszClassName;
	HICON hIconSm;
} WNDCLASSEXA;

typedef WNDCLASSEXA WNDCLASSEX;

Pencere sınıf yapısına değer atama ve sınıf yapısının kaydedilmesi

WinMain() fonksiyonunda bildirimler yapıldıktan sonra, oluşturacağımız program penceresinin özelliklerini belirleyen pencere yapısı değerleri verilir ve pencere yapı sınıfının kaydı yapılır. Eğer kayıt işleminde herhangi bir hata meydana gelirse program sona erer:


/* Program ana pencere sınıfı veri yapısına değer atama */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;      /* Windows tarafından çağrılan ve tüm mesaj işlemlerini yapan ana pencere fonksiyonu */
wincl.style = CS_DBLCLKS;                 /* Çift tıklamaya işlem yapılmasını sağlayan stil değerini ekleme */
wincl.cbSize = sizeof (WNDCLASSEX);       /* Bu değişkenine sizeof(WNDCLASSEX) değeri atanmalıdır. */

/* Ön tanımlı ikon ve mouse imlecinin kullanılmasını sağlama */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;                /* Menü tanımı yok. */
wincl.cbClsExtra = 0;                     /* Pencere sınıfı için ektra byte tanımı yok. */
wincl.cbWndExtra = 0;                     /* Pencere Instance değeri için ayrılacak ekstra byte sayısını gösterir. */    
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Ana pencere arka plan rengi için Windows'un ön tanımlı değerini kullanır. */

/* Pencere sınıfını kaydeder, başarılı olmazsa program sona erer. */
if (!RegisterClassEx (&wincl))
	return 0;

UINT cbSize

Yapının byte olarak değerini gösterir. sizeof (WNDCLASSEX) ile değer atanır.

UINT style

Sınıf tipleri pencere sınıfı için ek özellikler sağlar. İki veya daha fazla sınıf tipi OR (|) bit işlemcisi ile birlikte tanımlanabilir. CS_ ifadesi ile başlayan sınıf tipi makroları winuser.h dosyası içinde tanımlanmıştır.

WNDPROC lpfnWndProc

Program pencere fonksiyonunu gösteren bir işaretçidir.

int cbClsExtra

Pencere sınıfından sonra tahsis edilecek ekstra byte miktarını gösterir. Sistem ayrılan byte'lara ilk değer olarak sıfır değeri verir.

int cbWndExtra

Pencere instance sonrası tahsis edilecek ekstra byte miktarını gösterir. Sistem ayrılan byte'lara ilk değer olarak sıfır değeri verir. Eğer bir uygulama kaynak dosya içinde CLASS direktifi kullanarak oluşturduğu bir diyalog kutusunu kaydetmek için WNDCLASSEX kullanırsa, bu elemana DLGWINDOWEXTRA değerini vermelidir.

HINSTANCE hInstance

Program .exe dosyasının bellekteki kopyasını gösteren bir Handle değerdir. Bu değer WinMain() fonksiyonuna geçirilen ilk argümandır. HINSTANCE veri türü, windef.h dosyasında typedef HANDLE HINSTANCE şeklinde tanımlanmış bir değerdir.

HICON hIcon

Program ikonunu gösteren bir Handle değerdir. Bu elemana NULL bir değer atandığında, sistem aktif ikonu atar. HICON veri türü, windef.h dosyasında typedef HANDLE HICON şeklinde tanımlanmış bir değerdir.

HCURSOR hCursor

Program kursor'ını gösten bir Handle değerdir. Bu elemana NULL bir değer atandığında, uygulama, fare uygulama penceresi içine girdiğinde kursor şeklini belirlemlidir. HCURSOR veri türü, windef.h dosyasında typedef HICON HCURSOR şeklinde tanımlanmış bir değerdir.

HBRUSH hbrBackground

Program pencere rengini belirleyen fırça rengini gösteren bir Handle değerdir. HBRUSH veri türü, windef.h dosyasında typedef HANDLE HBRUSH şeklinde tanımlanmış bir değerdir.

LPCTSTR lpszMenuName

Program ile kullanılacak kaynak dosyasında yer alan menü adını gösterir. LPCTSTR veri türü, winnt.h dosyasında typedef LPCSTR LPCTSTR şeklinde tanımlanmış bir değerdir. LPCSTR veri türü ise, winnt.h dosyasında typedef CONST CHAR *LPCSTR şeklinde tanımlanmış bir değerdir.

LPCTSTR lpszClassName

Program sınıf adını gösterir.

HICON hIconSm

Program için kullanılan küçük ikonu gösteren bir Handle değerdir.

Pencere yapısının değerleri atandıktan sonra, CreateWindowEx() fonksiyonu ile penceremizi oluşturmak için öncelikle RegisterClassEx() fonksiyonunu kullanarak pencere yapısını kaydetmemiz gerekir. Eğer bu fonksiyon bir hata verirse, program sıfır değeri geri vererek çalışmasını sona erdirir.

Program penceresinin oluşturulması ve ekranda gösterilmesi

WinMain() fonksiyonunda bildirimler yapıldıktan sonra, pencere yapısı değerleri verilir ve pencere yapı sınıfının kaydı yapılır. Eğer kayıt işleminde herhangi bir hata meydana gelirse program sona erer:


/* Program ana pencere sınıfı kaydedildiğinden, program ana penceresini oluşturma */
hwnd = CreateWindowEx (
	   0,                   /* Pencereye ek özellikler sağlar. */
	   szClassName,         /* Sınıf adı */
	   _T("Code::Blocks Template Windows App"),  /* Pencere başlığı */
	   WS_OVERLAPPEDWINDOW, /* Ön tanımlı pencere */
	   CW_USEDEFAULT,       /* Pencerenin sol üst köşesinin x koordinatını Windows belirler. */
	   CW_USEDEFAULT,       /* Pencerenin sol üst köşesinin y koordinatını Windows belirler. */
	   544,                 /* Ana pencere genişliği piksel olarak */
	   375,                 /* Ana pencere yüksekliği piksel olarak */
	   HWND_DESKTOP,        /* Ana pencerenin masaüstünün alt pencersi olduğunu gösterir. */
	   NULL,                /* Menü yok. */
	   hThisInstance,       /* Program Instance handler değeri */
	   NULL                 /* Pencere oluşturma bilgisi yok. */
	   );

/* Ana pencereyi ekran da gösterir. */
ShowWindow (hwnd, nCmdShow);

HWND WINAPI CreateWindowEx(
   DWORD dwExStyle,
   LPCTSTR lpClassName,
   LPCTSTR lpWindowName,
   DWORD dwStyle,
   int x,
   int y,
   int nWidth,
   int nHeight,
   HWND hWndParent,
   HMENU hMenu,
   HINSTANCE hInstance,
   LPVOID lpParam
);

DWORD dwExStyle

Oluşturulacak pencere için tanımlanan ek özellikleri belirler. WS_EX_ ifadesi ile başlayan makrolar winuser.h dosyası içinde tanımlanmıştır.

LPCTSTR lpClassName

RegisterClassEx() fonksiyonu ile kaydedilen pencere yapı adını gösterir.

LPCTSTR lpWindowName

Program penceresi başlık çubuğunda yer alan başlığı gösterir.

DWORD dwStyle

Oluşturulacak pencerenin özellikleri belirler. WS_ ifadesi ile başlayan makrolar winuser.h dosyası içinde tanımlanmış olup bu değerleri birleştirerek kullanabilirsiniz. Ayrıca, lpClassName elemanının alacağı değerlere bağlı olarak yine aynı dosya içinde yer alan farklı makrolar da kullanabilirsiniz.

int x

Program penceresinin ilk yatay konumunu belirler. Bir başlık çubuğu, pencere menüsü, boyutlandırma sınır çizgisi, küçültme ve büyütme butonları içeren bir program penceresi (WS_OVERLAPPEDWINDOW) veya pop-up bir pencere için ekran üzerinde pencerenin sol üst köşesinin x koordinatını belirler. Eğer pencere bir alt (child) pencere ise, ana pencerenin sol üst köşesine göre alt pencerenin sol üst köşesinin x koordinatını belirler. Eğer x CW_USEDEFAULT değerine ayarlanırsa, pencerenin sol üst köşesi için sistemin mevcut konum değerini alır ve y parametresini dikkate almaz. CW_USEDEFAULT değeri sadece WS_OVERLAPPEDWINDOW pencere için geçerlidir. pop-up veya alt pencereler için, x ve y parametreleri sıfır değerine ayarlanır.

int y

Program penceresinin ilk dikey konumunu belirler. Bir başlık çubuğu, pencere menüsü, boyutlandırma sınır çizgisi, küçültme ve büyütme butonları içeren bir program penceresi (WS_OVERLAPPEDWINDOW) veya pop-up bir pencere için ekran üzerinde pencerenin sol üst köşesinin y koordinatını belirler. Eğer pencere bir alt (child) pencere ise, ana pencerenin sol üst köşesine göre alt pencerenin sol üst köşesinin y koordinatını belirler. Eğer WS_OVERLAPPEDWINDOW pencere WS_VISIBLE özelliği ile ayarlanırsa ve x CW_USEDEFAULT değerine ayarlanırsa, pencerenin ne şekilde görüntüleneceğini y parametresi belirler. Eğer y CW_USEDEFAULT değerine ayarlanırsa, pencere oluşturulduktan sonra, pencere yöneticisi ShowWindow() fonksiyonunu SW_SHOW değeri ile çağırır. Eğer y parametresi farklı bir değer alırsa, pencere yöneticisi ShowWindow() fonksiyonunu nCmdShow parametre değerine göre çağırır.

int nWidth

Program penceresinin genişliğini belirler. WS_OVERLAPPEDWINDOW pencereler için bir genişlik veya CW_USEDEFAULT değeri içerir. ekran üzerinde pencerenin sol üst köşesinin x koordinatını belirler. Eğer pencere bir alt (child) pencere ise, ana pencerenin sol üst köşesine göre alt pencerenin sol üst köşesinin x koordinatını belirler. Eğer x CW_USEDEFAULT değerine ayarlanırsa, pencerenin sol üst köşesi için sistemin mevcut konum değerini alır ve y parametresini dikkate almaz. CW_USEDEFAULT değeri sadece WS_OVERLAPPEDWINDOW pencere için geçerlidir. pop-up veya alt pencereler için, nWidth ve nHeight parametreleri sıfır değerine ayarlanır.

int nHeight

Program penceresinin yüksekliğini belirler. Eğer nWidth parametresi CW_USEDEFAULT değerine ayarlanırsa, sistem nHeight parametresini dikkate almaz.

HWND hWndParent

Oluşturulan program penceresinin ana penceresinin Handle değerini gösterir.

HMENU hMenu

Program ile kullanılacak menüyü tanımlar. HMENU veri türü, windef.h dosyasında typedef HANDLE HMENU şeklinde tanımlanmış bir değerdir.

HINSTANCE hInstance

Pencere ile ilgili programın bellekteki kopyasının Handle değeridir.

LPVOID lpParam

WM_CREATE mesajının lParam parametresi ile temsil edilen CREATESTRUCT yapısı (lpCreateParams member) ile pencereye geçirilen değeri gösteren bir işaretçidir. Ek veriye gerek duyulmadığında NULL bir değer içerir.

typedef struct tagCREATESTRUCT {
  LPVOID    lpCreateParams;
  HINSTANCE hInstance;
  HMENU     hMenu;
  HWND      hwndParent;
  int       cy;
  int       cx;
  int       y;
  int       x;
  LONG      style;
  LPCTSTR   lpszName;
  LPCTSTR   lpszClass;
  DWORD     dwExStyle;
} CREATESTRUCT;

Penceremizi CreateWindowEx() fonksiyonu ile oluşturduktan sonra ShowWindow() fonksiyonu ile ekranda gösteririz. ShowWindow() fonksiyonu hwnd Handle değerini CreateWindowEx() fonksiyonunun geri verdiği değerden, nCmdShow değerini ise WinMain() fonksiyonunun son parametresinden alır.

Program ana döngüsünün çalışması

Artık programın ana bölümünü oluşturan ve program kapatılmadığı sürece çalışmasına devam eden while döngüsü devreye girer:


/* Mesaj döngüsünü devre sokar. Bu döngü GetMessage() fonksiyonu 0 değeri döndürene kadar çalışmaya devam eder. */
while (GetMessage (&messages, NULL, 0, 0))
{
	/* Sanal tuş mesajlarını karakter mesajlarına çevirir. */
	TranslateMessage(&messages);
	/* Mesajları WindowProcedure() fonksiyonuna gönderir. */
	DispatchMessage(&messages);
}

/* Program dönüş değeri 0'dır - Bu değeri PostQuitMessage() fonksiyonu verir. */
return messages.wParam;

Program artık kullanıcının fareye tıklamak, hareket ettirmek, klavyeden giriş yapmak ve benzeri herhangi bir işlem yapmasını beklemektedir. Bu işlemlerden herhangi biri yapıldığında sistem tarafından bu işleme karşılık gelen bir mesaj oluşturulur ve programın mesaj kuyruğuna eklenir. Bu durumda while döngüsü ile sürekli olarak çalışmasına devam etmekte olan GetMessage() fonksiyonu kuyrukta bekleyen ilk mesajı kuyruktan alır ve işlem yapmak üzere programa dahil eder. Eğer herhangi bir mesaj yoksa, mesaj gelene kadar bekler.

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

LPMSG lpMsg

Mesaj kuyruğundan mesaj bilgisini alan MSG yapısını gösteren bir işaretçidir.

HWND hWnd

Mesajları alınacak pencerenin Handle değeri gösterir. Eğer NULL bir değer alırsa, GetMessage() fonksiyonu hem pencere hem de Thread mesajlarını alır.

UINT wMsgFilterMin

Alınacak en düşük değere sahip mesajın int değerini gösterir. Alınacak mesajları sınırlamak için kullanılır. İlk klavye mesajı için WM_KEYFIRST (0x0100), ilk fare mesajı için WM_MOUSEFIRST (0x0200), sadece WM_INPUT mesajlarını almak için WM_INPUT değerini kullanın. wMsgFilterMin ve wMsgFilterMax parametrelerinin her ikisi birden sıfır değeri alırsa, GetMessage() fonksiyonu filtreleme yapmadan tüm mesajları alır.

UINT wMsgFilterMax

Alınacak en yüksek değere sahip mesajın int değerini gösterir. Alınacak mesajları sınırlamak için kullanılır. Son klavye mesajı için WM_KEYLAST, son fare mesajı için WM_MOUSELAST, sadece WM_INPUT mesajlarını almak için WM_INPUT değerini kullanın. wMsgFilterMin ve wMsgFilterMax parametrelerinin her ikisi birden sıfır değeri alırsa, GetMessage() fonksiyonu filtreleme yapmadan tüm mesajları alır.

Geri dönüş değeri

Eğer GetMessage() fonksiyonu WM_QUIT başka bir mesaj aldığında sıfırdan farklı bir değer geri verir.

Eğer fonksiyon WM_QUIT mesajı alırsa, sıfır değeri geri verir.

Eğer bir hata meydana gelirse, geri verilen değer -1 sayısıdır. Eğer hWnd geçersiz bir pencere Handle'ı veya lpMsg geçersiz bir işaretçi olursa fonksiyon hata verir.

TranslateMessage() sanal tuş mesajlarını karakter mesajlarına çevirir. DispatchMessage() mesajları WindowProcedure() fonksiyonuna gönderir.

Herhangi bir nedenle while döngüsünden çıkılırsa, messages.wParam değeri geri döndürülerek program sona erer.

Program ana pencere mesaj işlem fonksiyonu

while döngüsünde GetMessage() fonksiyonu ile alınan mesajlar işlem görmek üzere DispatchMessage() fonksiyonu ile aşağıda gösterilen WindowProcedure() fonksiyonuna gönderilir:


/* Bu fonksiyon Windows'un DispatchMessage() fonksiyonu tarafından çağrılır. */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* Mesajlara gerekli işlemi yapar. */
    {
        case WM_DESTROY:
            PostQuitMessage (0);      /* WM_QUIT değerini mesaj kuyruğuna gönderir */
            break;
        default:                      /* İşlem yapılmayan mesajlar için */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

WindowProcedure() fonksiyonu her mesaj için çağrılır. Herhangi bir mesaja işlem yapılmadığında DefWindowProc() fonksiyonu çağrılır.

WM_DESTROY mesajı geldiğinde PostQuitMessage() fonksiyonu çağrılır. PostQuitMessage() fonksiyonu WM_QUIT mesajını mesaj kuyruğuna gönderir. Bu mesaj GetMessage() foksiyonunun FALSE bir değer geri vermesini sağladığından, while döngüsünün ve programın çalışması sona erer.