klavye öğrenmek

2 Temmuz 2013 Salı Unknown 0 yorum

Scroll Bar Kontrolünin Kullanımı

klavye

            Yapılacak ilk iş SetScrollRange fonksiyonuyla scroll bar için mantıksal bir skala belirlemektir. Bu işlem örneğin WM_CREATE mesajı içerisinde yapılabilir. Prototip:


            Fonksiyonun birinci paremetresi hangi pencereye ilişkin scroll bar işlemi uygulanacağıdır. Eğer gömülü scroll bar söz konusuysa ana pencerenin handle'ı geçirilmelidir. İkinci parametre üç değer alabilir: Eğer kontrole ilişkin ayarlama yapılıyorsa SB_CTL, pencereye gömülü scroll bar ayarlamaları için SB_VERT ya da SB_HORZ kullanılmalıdır. Üçünü ve dördüncü parametreleri skala aralığını belirtir. Beşinci parametre kontrol üzerindeki görüntünün güncellenmesiyle ilgilidir. Skala belirlendikten sonra WM_HSCROLL ya da WM_VSCROLL mesajları işlenir. Mesaj içerisinde mesajın geliş sebebi bir switch ile soruşturulmalıdır.


            Bu switch içerisinde şu belirlemeler yapılmalıdır:

- Scroll bar ok'larına click yapıldığında ne kadar bir öteleme yapılacak,
- Ara bölgelere click yapıldığında ne kadar öteleme yapılacak,

            Bu belirlemelerden sonra switch deyiminin dışında SetScrollPos API fonksiyonuyla düğme yeni yerine yerleştirilmelidir. Prototipi:

Klavye Mesajları


            Klavyede bir tuşa basıldığında WM_KEYDOWN çekildiğinde de WM_KEYUP mesajları Windows tarafından gönderilir. Klavye mesajları girdi odağına(input focus) sahip olan pencereye gönderilmektedir. Bir t anında üzerinde mavi bant olan pencereye aktif pencere denir. Yalnızca hWndParent olarak NULL girilmiş olan pencereler aktif olabilir. Yani yalnızca top level pencereler aktif olabilir. Mouse ile bir üst pencerenin içindeki alt pencereye click yapıldığında alt pencerenin en üst penceresi otomatik olarak aktif pencere yapılır. Girdi odağı(input focus) klavye mesajlarının gönderileceği penceredir. Girdi odağı bir alt pencereye verilebilir. Özetle bir üst pencerenin içerisinde bir alt pencere varsa ve alt pencerenin üzerine click yapılmışsa girdi odağını alan pencere alt pencere olur ama o pencerenin en üst penceresi aktif pencere yapılır. Girdi odağını herhangi bir pencereye verebilmek için SetFocus API fonksiyonu kullanılır. Prototipi:


Fonksiyonun parametresi girdi odağının verileceği pencerenin handle'ıdır. Fonksiyonun geri dönüş değeri girdi odağına sahip olan eski pencerenin handle'ıdır.
            Girdi odağı bir alt pencereye verilirse o pencerenin en üs penceresi otomatik olarak aktif pencere olur. Girdi odağının hangi pencerede olduğu GetFocus API fonksiyonuyla alınabilir. Prototipi:



Fonksiyon girdi odağına sahip olan pencerenin handle'ıyla geri döner.

Sanal Karakter Kodları(Virtual Key Codes)

            Klavyedeki özel tuşların ASCII kodları 0'dır. Bu tuşlar birbirlerinden scan code'larıyla ayrılabilir. Scan code'ları ise genel olarak donanıma bağlı bir biçimde belirlenmektedir. Windows sistemlerinde değişik donanıma sahip klavyeler bağlanabilir. Bu klavyeler üzerindeki özel tuşların scan code'ları birbirlerinden farklı olabilir. Örneğin 101/102 tuşlu IBM klavyelerinde F1 tuşunun extended scan code'u 0x3B'dir. Windows sisteminin pek çok değişik donanımlarda çalışabileceği varsayılmıştır. Eğer özel tuşların scan code'ları doğrudan program içerisinde kullanılsa önemli bir taşınabilirlik problemi çıkar. Örneğin:


Burada ch ile F1 tuşu karşılaştırılmaya çalışılmıştır. Çünkü F1 tuşunun extended scan code'u 0x3B'dir. Ancak bu program farklı bir donanımda çalıştırılmak istendiğinde o donanımdaki F1 tuşunun scan code'u 0x3B olmayabilir. Bunun çözümü için sanal karakter kodları tasarlanmıştır. Basılan tuşun bilgisi klavye sürücüsü tarafından standart sanal karakter kodlarına dönüştürülmektedir. Program içerisinde programcı donanım ne olursa olsun hep sanal karakter kodlarını kullanır. Çünkü scan code'dan sanal karakter koduna dönüşüm yapılması aşağı seviyede çalışan klavye sürücüsü tarafından yapılmaktadır. Windows.h içerisinde VK_XXX biçiminde bütün tuşların sanal karakter kodları sembolik sabitler biçiminde tanımlanmıştır. Sonuç olarak özel tuşlar kullanılacaksa onların sanal karakter kodları kullanılmalıdır. Alfabetik ve sayısal karakterlerin sanal karakter kodları ASCII kodlarıyla aynıdır. Bunlar için özel bir VK_ tanımlamasına gerek duyulmamıştır.

Klavye Mesajları


            Klavyede bir tyuşa basıldığında WM_KEYDOWN, çekildiğinde ise WM_KEYUP mesajları gönderilir. Sisteme ilişkin özel tuşlar için ayrıca WM_SYSKEYDOWN ve WM_SYSKEYUP mesajları gönderilir. Bu mesajalrın parametreleri şöyledir: wParam parametresine basılan tuşun sanal karakter kodu yerleştirilir. lParam parametresi aşağıdaki gibi düzenlenmiştir:


Yineleme sayısı normal olarak 1 olur. Sistem çok yavaşladığında bir tuşa sürekli basılma durumunda iki tuşa basılma arasında anı tuşun bilgisini farklı bir mesaj biçimin değil, aynı mesajın yinelenme sayısı biçiminde kodlayabiliyoruz. OEM scan code klavyenin orijinal scan code'udur.

WM_CHAR Mesajı


            WM_CHAR mesajı Windows tarafından kuyruğa gönderilmez. TranslateMessage API fonksiyonu tarafından çağırılır. Prototip:


            Bu fonksiyon isteğe bağlı olarak mesaj döngüsünün içerisine yerleştirilir. Yani bu fonksiyon mesaj dögüsünden kaldırılsa WM_CHAR mesajı oluşmaz. Bu fonksiyon kuyruktan alınan mesajı inceler, bu mesaj WM_KEYDOWN ise basılmış olan tuşun bir ASCII tuşu olup olmadığına bakar. Eğer basılan tuş bir ASCII tuşu ise bu tuş için WM_CHAR mesajını kuyruğa yerleştirir. Bu mesajın wParam parametresi basılan tuşun UNICODE karakter karşılığıdır(ASCII tablosu UNICODE tablosunun ilk 256 karakteridir). lParam WM_KEYDOWN mesajında olduğu gibi ilave bilgileri içerir.
            Program içerisinde görüntülenmek istenen bir yazı söz konusuysa WM_KEYDOWN mesajı yerine WM_CHAR mesajının işlenmesi daha uygundur.


Listbox kontrolünde enter tuşuna basıldığında sanki doubleclick yapılmış gibi seçme işleminin sağlanması yukarıdaki gibi bir işlemle sağlanabilir.

Modeless Dialog Pencereleri


            Modal bir dialog penceresi DialogBox API fonksiyonuyla açılır, EndDialog API fonksiyonuyla kapatılır. Modal bir dialog penceresine girildiğinde dialog penceresinin gerçek pencere fonksiyonu mesaj kuyruğunu kontrol altına alarak yalnızca dialog işlemlerinin yapılmasını sağlar. Oysa modeless dialog pencereleri mesaj döngüsünü kontrol altına almaz. Ayrı bir üst pencere gibi çalışmaktadır. Modeless dialog pencerelerinin mesajları ana mesaj döngüsü yoluyla işlenir. Modeless bir dialog penceresi CreateDialog API fonksiyonuyla yaratılır. Bu fonksiyon kaynaktan(resource) hareketle bütün kontrolleri yaratır ve çalışmasını bitirir. Tabii pencere görünür durumda kalır. Modeless dialog pencerelerinin mesajları normal bir pencere gibi ana mesaj döngüsünden hareketle ele alınmaktadır. Kullanıcı açısından bakıldığında modal ve modeless dialog pencereleri arasında önemli farklar vardır. Modal dialog penceresi açıldığında dialog penceresi dışında diğer pencereler için hiçbir işlem yapılamaz(Kapatılana kadar). Oysa modeless dialog pencereleri açıldığında başka pencerelerle ilgili işlemler gerçekleştirilebilir. Modeless dialog pencereleri çok nadir kullanılır(Tipik uygulaması Find & Replace). Modeless dialog pencereleri "Owned Window" olarak yaratılır. Yani asıl pencerenin dışına sürüklenebilir. Ana pencere minimize edildiğinde o da minimize edilir. Modeless dialog pencereleri normal bir pencere gibi DestroyWindow API fonksiyonuyla kapatılır.CreateDialog API fonksiyonunun prototipi:


            Tıpkı modal dialog pencerelrinde olduğu gibi modeless dialog pencerelerin de bir pencere fonksiyonları vardır. Kontroller yine gerçek pencere fonksiyonunun WM_CREATE mesajında oluşturulur. Programcının son parametre olarak belirttiği pencere fonksiyonu gerçek pencere fonksiyonu değildir, onun tarafından çağırılacak yapay pencere fonksiyonudur.

Modeless Dialog Penceresine İlişkin Uygulama

            Fırtça yaratmak için kullanılan CreateBrushIndirect fırçanın pek çok özelliğini belirlememize olanak sağlanmaktadır. Bu fonksiyonun alternatifi olarak CreateSolidBrush fonksiyonu kullanılabilir. Bu fonksiyon yalnızca fırçanın rengini belirlememize olanak sağlar. Prototipi:

            Uygulamanın menü yapısı:


            Uygulamada modeless dialog penceresinin içerisindeki scroll barların ID değerleri bilinçli olarak 10, 11, 12 biçiminde yani ardışıl olarak verilmiştir. Bunun nedeni dialog penceresine iletilen mesajların kolay işlenmek istenmesidir.
            Bir dialog penceresinin yeniden açıldığında en son görüntüyü koruması bazen istenebilir. Bunun için kontrol bilgileri çıkarken global değişkenlere atanır. WM_INITDIALOG mesajında da o değerlerle tekrar kontroller konumlandırılır.

IsDialogMessage API Fonksiyonu

            Modeless dialog pencereleri için ayrıca mesaj döngüsünün içerisinde IsDialogMessage API fonksiyonunun çağırılması gerekir. Eğer bu fonksiyon çağırılmazsa modeless dialog penceresi pek çok işlemini yapar ancak özellikle klavye ile ilgili işlemlerde başarısız olur. Bu fonksiyon mesajın modeless dialog penceresine ilişkin olup olmadığını tespit eder, eğer ilişkinse bazı ek işlemlerden sonra kendi içerisinde TranslateMessage ve DispatchMessage fonksiyonlarına sokar. Eğer kuyruktan alınan mesaj bir modeless dialog penceresine ilişkinse ayrıca TranslateMessage ve DispatchMessage fonksiyonlarına sokulmamalıdır. Fonksiyonun geri dönüş değeri 0 ise mesaj modeless dialog penceresine ilişkin değildir, o halde işlenmelidir. 0 dışı bir değer ise mesaj modeless dialog penceresine ilişkindir işlenmemelidir. Genellikle modeless dialog pencerelerinin handle değerleri global değişkenlerde saklanır. Başlangıçta bu global değişkenin içerisine NULL değeri koymak kontrol açısından uygundur. özetle bir modeless dialog penceresi açılacaksa programın mesaj döngüsü şöyle olmalıdır:


SetDlgItemInt ve GetDlgItemInt Fonksiyonları

            Bu fonksiyonlar aslında SetDlgItemText ve GetDlgItemText fonksiyonlarının başka biçimleridir. SetDlgItemInt fonksiyonu bir int sayıyı parametre olarak alır. Bunu yazısal biçime dönüştürerek SetDlgItemText ile pencere yazısını değiştirir. GetDlgItemInt fonksiyonu da pencere yazısını alarak bunu atoi fonksiyonundan geçirir ve bir int sayı biçiminde programcıya verir. Bu fonksiyonlar özellikle edit ve static kontrollerinde kullanılmaktadır.

Timer İşlemleri

            Eğer programcı isterse belirlenen bir periyodla kuyruğa WM_TIMER isimli mesaj Windows tarafından gönderilebilir. Bu sayede periyodik işlem gerektiren durumların üstesinden gelinebilir. Örneğin belirli aralıklarla bir işlemi yürüten programlar ya da saat programları bu mesajdan faydalanılarak yazılırlar. Mesajın yollanacağı periyod milisaniye mertebesinde belirlenebilir. Buradaki periyod uzunluğu sistemin çalışmasına bağlı olarak ileri ve geri yönde sapmalar gösterebilir. Zamana dayalı kritik işlemler bu mesaj kullanılarak gerçekleştirilemez. Sistemin WM_TIMER mesajını kuyruğa bırakabilmesi için SetTimer API fonksiyonuyla bir timer yaratmak gerekir. Prototipi:

);

Fonksiyonun birinci parametresi mesajın gönderileceği pencerenin handle değeridir. Fonksiyonun ikinci parametresi yaratılacak timer'ın ID değerdir. Eğer daha önce bu ID değeriyle bir timer yaratılmışsa eskisi silinerek yenisi geçerli olur. Bu değer genellikle sembolik sabit olarak tanımlanır. Bir programın birden fazla timer yaratması durumunda bu ID değeri timer'ların tespit edilmesi amacıyla kullanılır. Windows bir timer'ın zamanı geldiğinde kuyruğa WM_TIMER mesajını bırakır ve mesajın wParam parametresine ID değerini yerleştirir. Programcı da bir switch içerisinde mesajın hangi timer dolayısıyla gönderildiğini anlar. Bu değer aynı zamanda bir handle değeri gibi kullanılmaktadır. Örneğin timer yok edilirken bu ID değeri kullanılmaktadır. Fonksiyonun üçünü parametresi milisaniye cinsinden gönderilme periyodunu belirtir. Fonksiyonun son parametresi timer fonksiyonunun baişlangıç adresini alır. Bu değer NULL girilebilir. Bu fonksiyonun aşağıdaki gibi bir parametrik yapıya sahip olması gerekir:


            Fonksiyonun geri dönüş değeri başarı durumunda ikinci parametresiyle girilen ID değerinin aynısıdır. Başarısızlık durumunda 0'dır. Fonksiyonun başarısının kontrol edilmesinde fayda vardır.

WM_TIMER Mesajı

            Bu mesajın wParam parametresine timer'ın ID değeri, lParam parametresine ise SetTimer fonksiyonunun son parametresi olarak geçirilen fonksiyonun adresi yerleştirilir.
            Yaratılan timer çalışma bitirilince KillTimer fonksiyonuyla yok edilir. Prototipi:

            Örnek programda timer WM_CREATE mesajında yaratılmış, WM_DESTROY mesajında da yok edilmiştir.
            SetTimer fonksiyonun son parametresi NULL yerine belirtilen parametre yapısına sahip bir fonksiyonun başlangıç adresi olarak girilirse periyod dolduğunda doğrudan o fonksiyon çağırılır.Bu durumda WM_TIMER mesajı etkisiz kalır. Aslında bu durumda mesaj yine kuyruğa bırakılır, ancak DispatchMessage API fonksiyonu pencere fonksiyonunu çağırmak yerine bu fonksiyonu çağırır.
            SetTimer fonksiyonunun birinci parametresi de NULL girilebilir. Bu durumda son parametre mutlaka girilmelidir. DispatchMmessage API fonksiyonu belirtilen fonksiyonu çağırır.

Bir BMP Çizimi Yapmanın Adımları

1. Bitmap resource'ta çizilir, ya da FindResource fonksiyonuyla doğrudan dosyadan yüklenir. LoadBitmap fonksiyonuyla bitmap'e ilişkin handle elde edilir.
2. WM_PAINT içerisinde CreateCompatibleDC ile bellek için DC elde edilir ve SelectObject fonksiyonuyla bu DC için bitmap seçilir.
3. BitBlt fonksiyonuyla bellek tabalı DC'den normal DC'ye kopyalama yapılır.


0 yorum: