destroy window fonksiyonu
| işletim |
CreateWindow fonksiyonu
pencereyi yarattıktan sonra pencereye ilişkin bütün bilgileri dinamik olarak
tahsis ettiği içsel bir yapıda saklar. Aslında CreateWindow fonksiyonunun
vermiş olduğu bu geri dönüş değeri bu içsel yapının başlangıç adresidir.
DestroyWindow fonksiyonu pencereyi ekrandan görüntüsel olarak siler ve
CreateWindow fonksiyonu tarafından dinamik olarak oluşturulmuş olan bu içsel
yapıyı da free hale getirir. DestroyWindow fonksiyonu DefWindowProc tarafından
WM_CLOSE mesajına karşı otomatik olarak çağırılır. Tabii istenildiği zaman
programın ana penceresi kapatılmak isteniyorsa DestroyWindow programcı
tarafından çağırılmalıdır. DestroyWindow pencere görüntüsü ekrandan sildikten
sonra programcıyı haberdar etmek için WM_DESTROY mesajını gönderir.
DestroyWindow aynı zamanda pencerenin bütün alt pencerelerini de DestroyWindow
fonksiyonunu çağırarak siler. WM_DESTROY mesajı geldiğinde pencere ve alt
pencereler ekranda görünür değildir, ancak bunlara ilişkin veri yapıları hala
durmaktadır.
BOOL
DestroyWindow(HWND hWnd);
Fonksiyon silinecek pencerenin handle değerini parametre olarak alır.
WM_CREATE Mesajı
Bu mesaj CreateWindow
fonksiyonu tarafından pencerenin yaratıldığını bildirmek amacıyla gönderilir.
Pencere yaratıldığında yapılmak istenen ilk işlemler WM_CREATE mesajı işlenerek
yapılabilirler. WM_CREATE mesajı gönderildiğinde pencere henüz görünür
değildir(henüz CreateWindow fonksiyonundan çıkılmamıştır). lParam
parametresinde CREATESTRUCT isimli bir yapının adresi bulunur. Bu yapının içi
CreateWindow tarafından doldurulmuştur ve faydalı bilgiler içermektedir. Bu
yapı içerisindeki bilgilere şu biçimde erişilebilir:
case WM_CREATE:
{
CREATESTRUCT *pStruct;
pStruct = (LPCREATESTRUCT ) lParam;
.............
.............
.............
}
break;
SendMessage ve PostMessage Fonksiyonları
Mesaj kuyruğuna mesajlar
PostMessage fonksiyonuyla programcı tarafından bilinçli olarak da
bırakılabilirler. Tabii bu mesaj normal olarak kuyruğun sonuna bırakılırlar.
Mesajın kuyruğa bırakılmasıyla işlenmesi arasında belli bir zaman kaybı söz
konusu olabilir. Yani PostMessage fonksiyonu pencere fonksiyonu içerisinde
kullanıldığında programın akışı PostMessage fonksiyonundan çıkar, mesaj
kuyruğuna girilerek sıradaki mesajlar işlenir. En sonunda kuyruğa PostMessage
ile programcı tarafından bırakılan mesaj alınarak işlenir. Oysa SendMessage
fonksiyonu mesajı kuyruğa bırakmaz, doğrudan pencere fonksiyonunu çağırarak
hemen işler. Yani programın akışı SendMessage'den çıktığında mesaj işlenmiş
olur. Her iki fonksiyonun da parametrik yapısı aynıdır.
LRESULT
SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
BOOL PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
Fonksiyonların
birinci parametresi mesajın gönderileceği pencerenin handle değeridir. Yani bu
fonksiyonlar bu handle'a ilişkin pencerenin yaratılması sırasında belirtilen
pencere fonksiyonunu çağırırlar. Fonksiyonların ikinci parametresi gönderilecek
mesajın numarasıdır. Üçüncü ve dördüncü parametreler mesajın wParam ve lParam
parametreleridir. PostMessage fonksiyonunun geri dönüş değeri BOOL türündendir,
işlemin başarısını bildirir. Oysa SendMessage fonksiyonunun geri dönüş değeri
çağırılan pencere fonksiyonunun geri dönüş değeridir.
Kaynakların Program İçerisinden Kullanılması
Normal olarak kaynaklar rc
uzantılı bir text dosyası içerisine kaynak dili kullanılarak yazılırlar. Kaynak
derleyicisi tarafından derlenip res uzantılı yapılırlar ve linker tarafından PE
formatındaki exe dosyanın içindeki kaynak bölümüne yerleştirilirler. Visual C++
geliştirme sisteminde rc dosyası proje dosyasına eklenirse bu işlemler otomatik
olarak yapılır.
Her kaynağın kaynak
dilinde nasıl yazılacağı önceden belirlenmiştir ve belli bir syntax kuralı
vardır. Ancak kaynakların programcı tarafından bu biçimde yazılması, yani
kaynak dilinin öğrenilmesi çok zahmetlidir. Bunun için tüm geliştirme
sistemlerinde kaynaklar ismine kaynak editörü(resource editor) denilen bir
ortamda görsel olarak hazırlanırlar. Kaynaklar görsel olarak belirlendikten
sonra geliştirme sistemi bunun kaynak dilindeki karşılığını rc dosyası
biçiminde oluşturur. Her kaynağın bir ismi vardır. Bu isim alfabetik ya da
sayısal biçimde verilebilir. Eğer kaynak isminin ilk harfi alfabetik bir
karakterle başlıyorsa kaynak alfabetik olarak isimlendirilmiştir, sayısal bir
karakterle başlıyorsa kaynak sayısal olarak isimlendirilmiştir(Eğer bir sayı
alfabetik bir isim olarak kullanılacaksa çift tırnak içine alınmalıdır). Genel
olarak sayısal biçimde isimlendirilmiş kaynaklar ile daha hızlı işlem yapılır.
Bir kaynağı bir programın içinde kullanmak için kaynağı hazır hale getirmek
gerekir. Bu işlem sırasında kaynak exe dosyanın kaynak bölümünden alınır,
bellekte dinamik olarak yaratılan bir veri yapısının içerisine çekilir. kaynağı
hazır hale getiren fonksiyonların isimleri Loadxxxx biçimindedir. Kaynağı hazır
hale getiren Loadxxxx fonksiyonlarının iki parametresi vardır. Birincisi exe
dosyanın bellekteki yükleme adresi olan hInstance adresidir, ikincisi ise
kaynağın ismidir(Bu fonksiyonların exe dosyasının kaynak bölümüne erişebilmesi
için exe dosyasının bellekteki yükleme adresini bilmeleri gereklidir). Loadxxxx
fonksiyonlarının geri dönüş değerleri kaynağa ilişkin handle değerleridir.
Örneğin HCURSOR, HICON, HMENU biçiminde olabilir(hepsi aslında void *).
Menü Kaynağının Kaynak Dilinde Oluşturulması
Kaynak dilinde her kaynak
önce kaynak ismiyle başlar, sonra onu kaynağın türünü belirten bir anahtar
sözcük izler, sonra kaynaklara göre değişebilen parametrik bilgiler yazılır.
Bir menü menü çubuğu ve popup menülerden oluşur. Popup menünün içerisinde başka
bir popup menü bulunabilir. Bir menü popup menülerden, popup menüler de menü
elemanlarından oluşur. Kaynak derleyicileri C'nin ön işlemci komutlarını aynı
biçimde kullanabilir. Popup menülerin bir numarası yoktur ama her menü
elemanının bir numarası olmak zorundadır. Menü elemanlarının numaraları
istenildiği gibi seçilebilir(Ancak 100'den büyük olması tavsiye edilir). Ancak
her menü elemanının numarası diğerinden farklı olmalıdır.
Kaynak dilinde yazılmış
kaynaklar çeşitli sayılar kullanabilirler. Bu sayıların ayrı bir başlık
dosyasında sembolik sabit olarak tanımlanmaları önerilmektedir. Bu durumda
kaynak kullanımı için bir rc dosyası, bir de h dosyası oluşturulur. Bu rc
dosyası içerisinden h dosyası include edilir. Örneğin Visual C++ geliştirme
sisteminde bir kaynak dosyası yaratıldığında otomatik olarak resource.h dosyası
da yaratılır.
Menü Kaynağının Program İçerisinden Kullanılması
Bir menü kaynağını
programa dahil edebilmek için üç yöntem vardır:
1. WNDCLASS yapısının lpszMenuName elemanına menü kaynak ismi girilirse
menü otomatik olarak görüntülenir.
2. WNDCLASS yapısının lpszMenuName elemanı NULL olarak girilirse menü yine
de CreateWindow fonksiyonunda yaratılabilir. Bunun için önce LoadMenu fonksiyonuyla
menü kaynağı hazırlanır, sonra buradan alınan handle değeri CreateWindow
fonksiyonunun hMenu parametresi olarak verilir.
HMENU hMenu;
hMenu =
LoadMenu(hInstance, "SAMPLE_MENU");
CreateWindow(..........................,
hMenu, ......);
3. Menü CreateWindow fonksiyonundan sonra programın herhangi bir yerinde
SetMenu API fonsiyonuyla da yaratılabilir.
Alt Pencerelerle İşlemler
Alt pencereler
CreateWindow fonksiyonuyla yaratılırlar. Verilen koordinatlar üst pencerenin
çalışma alanı(client area) referans alınarak oluşturulurlar(Üst pencerelerin
referans noktası masaüstü penceresinin sol üst köşesidir). Alt pencere
yaratılırken üst pencerenin handle değerine gereksinim duyulur. Alt
pencerelerin handle değerlerinin yanısıra bir de id değerleri vardır. Alt
pencere id değerleri işaretsiz tam sayı biçimindedir ve normal olarak WORD
sınırları içerisindedir. CreateWindow fonksiyonunun dokuzuncu parametresi HMENU
türündendir. HMENU parametresi üst pencerelerde menü işlemleri için
kullanılırken, alt pencerelerde pencere id değerinin belirlenmesi amacıyla
kullanılır. Tabii bu parametrenin alt pencere id'si olarak girilmesi durumunda
tür dönüştürmesi yapılması gerekir. Örneğin (HMENU) 100, ya da sembolik olarak
(HMENU) CHILD_ID. Pencere id değeri WORD
sınırlarında sıfırdan farklı herhangi bir değer olabilir. Alt pencerelerin id
değerleri aslında tamamen programlamayı kolaylaştırmak amacıyla düşünülmüştür.
Hem handle değeri hem de id değeri her ikisi de bir pencereyi teşhis etmek
amacıyla kullanılabilir. Ancak id değerinin tam sayı türünden olması
programlamada çeşitli biçimlerde kolaylık sağlamaktadır. Zaten alt pencerenin
handle değeriyle id değerinin bir tanesinin bilinmesi durumunda diğerinin elde
edilmesini sağlayan API fonksiyonları vardır. Alt pencerelerin ve üst
pencerelerin farklı pencere fonksiyonları olabilir. Alt pencereyle üst
pencerenin pencere fonksiyonlarının farklı olabilmesi için bu iki pencerenin
farklı WNDCLASS yapılarıyla yaratılması gerekir. Çünkü pencere fonksiyonunun
belirlenmesi WNDCLASS ile yapılmaktadır. Bir program içerisinde ne kadar çok
alt pencere ve üst pencere yaratılmış olursa olsun bu pencerelere ilişkin
mesajlar programın(aslında alt işlemin(thread)) mesaj kuyruğuna
yerleştirilirler. Yani her programın(aslında alt işlemin) yalnızca bir tane
mesaj kuyruğu vardır, o programın yarattığı bütün pencerelere ilişkin mesajlar
aynı kuyruğa yerleştirilir. Programın tek bir mesaj döngüsü vardır. GetMessage
fonksiyonu tüm pencereler için gönderilmiş olan mesajları alabilmektedir. Mesaj
karşılığında hangi pencere fonksiyonunun çağırılacağı kararı DispatchMessage
fonksiyonu tarafından verilir. DispatchMessage fonksiyonu mesajın hWnd
parametresine bakarak pencerenin hangi WNDCLASS yapısıyla yaratılmış olduğunu
tespit eder ve buradan ilgili pencere fonksiyonunu bularak çağırır.
DestroyWindow fonksiyonu ile üst pencere yok edilince DestroyWindow fonksiyonu
önce alt pencereleri yok eder, daha sonra ilgili pencereyi yok eder.
Uyarı: DefWindowProc fonksiyonu WM_CLOSE mesajı işlenmemişse default olarak
DestroyWindow fonksiyonunu çağırır. Ancak WM_DESTROY için PostQuitMessage'i
çağırmaz. Eğer WM_DESTROY mesajı ile PostQuitMessage çağırılmamışsa pencere
silinir ama program sonlanmaz.
Üst ve Alt Pencereler Arası Mesaj Alış-Verişi
SendMessage ve PostMessage
fonksiyonlarıyla üst pencere alt pencereye, alt pencere de üst pencereye mesaj
gönderebilir. Aslında bu fonksiyonlarla handle değeri bilindikten sonra her
türlü pencereye mesaj gönderilebilmektedir.
Alt Pencere Nerede Yaratılmalı?
Alt pencere üst pencere
yaratıldıktan sonra herhangi bir yerde yaratılabilir. Ancak uygulamalarda bu
işlem genellikle iki biçimde yapılır:
1. Önce CreateWindow ile üst pencere yaratılır. Bu kodun aşağısında yine
CreateWindow ile alt pencere yaratılır.

0 yorum: