seo güncelleme alanı değişimi

Güncelleme alanının değiştirilmesi


            InvalidateRect fonksiyonuyla bir pencerenin güncelleme alanı istenilen dikdörtgensel bölge haline getirilebilir. Güncelleme alanı boş küme olmaktan çıkartılırsa kısa bir süre sonra Windows pencereye WM_PAINT mesajnı gönderir.
  
            Fonksiyonun birinci parametresi güncelleme alanının değiştirileceği handle değeridir. İkinci parametre güncelleme alanının koodinatlarını tutan yapının başlangıç adresidir. Eğer bu parametre NULL olarak girilirse güncelleme alanı çalışma alanı olarak alınır. Üçüncü parametre TRUE ya da FALSE olabilir. TRUE ise pencerenin zemini yeniden boyanır, FALSE ise boyanmaz.

Çizim Bileşenlerinin Belirlenmesi ve Kaldırılması

            Bir çizimde kullanılacak kalem, fırça gibi çizim bileşenleri için bir seçme işleminin yapılması gerekir. Bütün çizim bileşenleri diğerinden bağımsız ayrı bir çizim nesnesidir. Yani bütün çizim bileşenlerinin önce yaratılması gerekir. Örneğin bir kalem yaratmak için CreatePen, bir fırça yaratmak için CreateBrushIndirect gibi API fonksiyonları vardır. Bu fonksiyonlar çizim nesnelerine ilişkin handle değerini geri dönüş değeri olarak verirler. Örneğin:


Çizim nesnesi yaratan API fonksiyonlarının geri dönüş değerleri HPEN, HBRUSH, HBITMAP gibi olsa da bunların hepsinin gerçek türü void * biçimindedir. Bir çizim nesnesi yaratıldıktan sonra kullanılması için bir çizim handle'ı ile ilişkilendirilmesi gerekir. Bu ilişkilendirme işlemi SelectObject API fonksiyonuyla yapılır.


Fonksiyonun birinci parametresi çizim nesnesinin seçildiği DC bilgisidir. Fonksiyonun ikinci parametresi seçilecek çizim nesnesinin handle değeridir. İkinci parametre olarak HPEN, HBRUSH herhangi bir çizim nesnesine ilişkin bir handle girilebilir. Fonksiyonun geri dönüş değeri daha önce seçili olan çizim nesnesinin handle değeridir. SelectObject ile yapılan şey DC veri yapısının ilgili elemanının çizim nesnesinin handle değeriyle doldurulmasıdır. Özetle çizim işlemlerinde şunlar olmaktadır:
1. Çizim için bir DC nesnesi yaratılır. Yaratıldığında çizim nesneleri için default değerler kullanılmaktadır.
2. Çizim nesneleri CreateXXX fonksiyonlarıyla yaratılarak handle değerleri ede edilir.
3. SelectObject API fonksiyonu ile DC nesnesiyle çizim nesnesi ilişkilendirilir.


Temel Çizim Fonksiyonları


            Bir doğru çizebilmek için iki noktaya gereksinim vardır. Noktalardan ilki MoveToEx fonksiyonuyla tespit edilir, daha sonra LineTo fonkiyonuyla diğer nokta belirlenerek çizim yapılır. Windows'da pek çok çizim işleminde güncel nokta kavramı kullanılır. Güncel nokta MoveToEx fonksiyonuyla değiştirilir. Örneğin LineTo fonksiyonu güncel noktadan belirtilen noktaya kadar çizim yapar. LineTo fonksiyonu güncel noktayı doğrunun son noktası olarak günceller.



LineTo fonksiyonu çizgiyi DC nesnesiyle belirtilen kalemle çizer. Yani örneğin farklı bir renkte, farklı bir kalınlıkta, farklı bir biçimde çizebilmek için yeni bir kalem yaratmak gerekir.

Çizim Nesneleri Ne Zaman Yaratılmalı?


            Çizim nesnelerinin her defasında WM_PAINT mesajı içinde yaratılmasına gerek yoktur. Örneğin programında başında WM_CREATE mesajı içerisinde kalemler ve fırçalar yaratılabilir. Ancak çizim nesnesinin SelectObject ile seçilme işlemi DC nesnesi yaratıldıktan sonra Yani WM_PAINT mesjaı içeirisinde yapılmalıdır. Çizim nesnelerini geri bırakmak için DeleteObject API fonksiyonunu kullanmak gerekir.


            Çizim nesneleri boşaltılmazsa program bittiğinde işletim sistemi tarafından boşaltılır(WM_DESTROY mesajı içerisinde boşaltmanın önemli bir anlamı yoktur).

Önceden Tanımlanmış Çizim Nesneleri


            Windows'da bazı çizim nesneleri sistem yüklendiğinde otomatik olarak zaten sistem tarafından oluşturulur. Böylelikle klasik bazı çizimler için çizim nesnesi yaratmaya gerek kalmaz. Tabii bu çizim nesnelerinin SelctObject ile seçilmesi gerekir. Önceden tanımlanmış çizim nesnelerinin handle değerlerini alabilmek için GetStockObject API fonksiyonu kullanılır.



Fonksiyonun parametresi önceden tanımlanmış çizim nesnesini anlatan bir sayıdır. Bu sayı şunlardan biri olabilir:

BLACK_BRUSH
DKGRAY_BRUSH
GRAY_BRUSH
HOLLOW_BRUSH
LTGRAY_BRUSH
NULL_BRUSH
WHITE_BRUSH
BLACK_PEN
WHITE_PEN
NULL_PEN

Dikdörtgen Çizme


            Dikdörtgen çizmek için Rectangle API fonksiyonu kullanılır.



Bu fonksiyon sol üst ve sağ alt köşegeniyle belirtilen dikdörtgeni çizer. Dikdörtgenin çizgileri kalemle çizilir, içi fırçayla boyanır.
            Fırça yaratabilmek için CreatBrushIndirect API fonksiyonu kullanılır.

HBRUSH CreateBrushIndirect(CONST LOGBRUSH *lplb);

Fonksiyon parametre olarak LOGBRUSH türünden bir yapı değişkeninin adresini alır.

Pencere Zemininin Silinmesi


            BeginPaint fonksiyonu çizime ilişkin handle'ı almadan önce WM_ERASEBCGND mesajını SendMessage ile pencere yollar(GetWindowDC ve GetDC fonksiyonları bu mesajı yollamaz). WM_ERASEBKGND mesajı işlenmezse DefWindowProc tarafından işlenir. DefWindowProc WNDCLASS yapısının hbrBackground elemanı ile belirtilen fırça ile tüm pencere zeminini boyar. Bir pencerenin zemin rengini değiştirmek için tek yapılacak şey WNDCLASS yapısının hbrBackground elemanını başka bir fırça ile set etmektir. Bu eleman WNDCLASS register ettirilmeden önce set edilmelidir. Ya da SetClassLong ile GCL_HBRBACKGROUND parametresi kullanılarak herhangi bir yerde örneğin WM_CREATE mesajı içerisinde saet edilebilir.

WM_MOUSEMOVE Mesajı

            Mouse pencere içerisinde dolaştırıldığında Window sürekli olarak WM_MOUSEMOVE mesajını kuyruğa bırakır. Böylelikle mouse hareketinin takip edilebilmesi sağlanır. Bu mesajın parametre bilgileri şunlardır:

wParam
Tuş bilgisi
LOWORD(lParam)
x
HIWORD(lParam)
y


Sürükle ve Bırak İşlemlerinin Gerçekleştirilmesi


             En kolay yöntem WM_MOUSEMOVE mesajında mouse'un sol tuşuyna nasılı olup olmadığının tespit edilmesidir. Sürükleme işlemi şöyle anlaşılabilir:

Çizim İşleminin WM_PAINT Mesajının Dışında Başka Bir Yerde Yapılması


            Çizim işlemi kalıcı bir biçimde yapılacaksa WM_PANT mesajı içerisinde yapılacaktır. Ancak bazı durumlarda başka mesajlarda da çizimin yapılması zorunlu olabilir. Örneğin sistemin aşırı yüklenmesi sonucunda çizim işleminin InvalidateRect sonrası belirsiz bir zamanda yapılacak olması gecikmeye yol açabilir. Klavyeden basılan tuş karşısında hemen çizim yapılması gerektiği bir durum buna örnek verilebilir. WM_PAINT mesajı dışında çizimin yapıldığı diğer bir örnek ekranda hızlı bir çizim işleminin görüntülenmek istendiği durumdur. Örneğin mouse'un sürüklenmesi ile içi boyalı dikdörtgensel bir alan çizilecek olsa ikide bir WM_PAINT mesajının gelmesi ve bütün pencere çizimlerinin yeniden yapılması görüntüde titremelere yol açabilir. Çizim işlemi başka bir mesajda yapılacaksa GetDC API fonksiyonuyla handle alınır, çizim bu handle ile yapılır. Aynı çizim WM_PAINT mesajı içerisinde kalıcı bir biçimde tekrar yapılmalıdır.



Çizim Görüntülerinin WM_PAINT Mesajı için Saklanması


            Çizim işlemleri başka bir mesajla yapılıyorsa aynı işlemlerin görüntünün korunması amacıyla WM_PAINT mesajı içerisinde de yapılması gerekir. Bunun için yapılan çizim işlemlerinin bir veri yapısı içerisinde saklanması gerekebilir. Bu veri yapısı için bir yapı dizisi kullanılabilir. Tabii en iyi eknik bir bağlı liste yapısının kullanılmasıdır.

Koordinat Sistemleri



            Koordinat sistemi DC nesnesinde belirtilen "mapping mode"a bağlıdır. Koordinat sistemi genellikle ya çalışılan pencerenin çalışma alanının sol üst köşesi olur ya da desktop'ın sol üst köşesi olur. Bir grup API fonksiyonunda koordinat sistemi eğer ana pencere söz konusuysa dektop'ın sol üst köşesi, alt pencere söz konusu ise çalışma alanının sol üst köşesidir. Örneğin CreateWindow ve MoveWindow API fonksiyonları böyle çalışır. Ancak bazı grup API fonksiyonlarında koordinat sistemi her zaman desktop'ın sol üst köşesidir. Örneğin GetWindowRect fonksiyonu bu biçimde çalışır. Nihayet bir grup API fonksiyonunda da koordinat sistemi her zaman çalışma alanının sol üst köşesidir. 
Devamı... 2 Temmuz 2013 Salı Unknown 0 yorum

çizim işleminin bileşenleri

Çizim İşleminin Bileşenler


            Çizim kavramı pencere içerisine yerleştirilen tüm görüntüleri içerir ve çok fazla bileşeni vardır. Örneğin bir çizimin şekil çizgileri birkaç bileşene sahip olan kalemle yapılır. Bir kalem çizginin biçimi, rengi, kalınlığı ile karakterize edilir. En basit bir çizim için bile bir kaleme sahip olmak gerekir ve çizimin bu kalemle yapılacağını sisteme açıklamak gerekir. Diğer bir biçim bileşeni fırçadır. Bir bölgenin içi boyanacaksa bir fırçayla boyanır. Bir fırçayı fırçanın rengi ve deseni karakterize eder. Bir yazı yazılacaksa karakterlerin görüntüsünü belirten bir font oluşturmak gerekir. Font bir yazıdaki bütün karakterlerin görüntü biçimlerini tanımlayan bir kavramdır.

Çizim için Handle Alınması(Display Context)

            Bir çizim işlemi için öncelikle bir handle elde edilmesi gerekir. Handle özel API fonksiyonlarıyla elde edilebilir. Bir handle'ın elde edilmesi sırasında Windows çizim için gereken bütün bilşenleri bir veri yapısı biçiminde dinamik olarak oluşturur ve çizim bileşenlerine default bazı değerleri yerleştirir. Bu API fonksiyonları handle olarak veri yapısının başlangıç adresini verirler. Çizim için alınan handle değerinin typedef ismi HDC biçimindedir(HDC'nin gerçek türü void *'dır). Alınan bu handle değeri çizim ile ilgili bütün API fonksiyonlarına parametre olarak geçirilir. Böylece bu API fonksiyonları çizim bileşenlerinin neler olduğunu anlayabilir. Çizim için handle değeri WM_PAINT mesajının başında alınmalı sonunda geri bırakılmalıdır. Çünkü bu handle için tahsis edilen alan dinamik bir alandır ve bütün çalışan programlar için ortak bir alan söz konusudur. Bir programda alınmış olan bir handle'ın bırakılmaması diğer bir program için özellikle Win3.x sistemlerinde bir kaynak azalması yaratır. 32 bit Windows sistemlerinde GDI modülünün heap alanı çok geniş olduğu için alınan handle'ın bırakılmaması sebebiyle ciddi bir problem çıkmayabilir. Çizim için handle alan üç tür API fonksiyonu vardır: BeginPaint, GetDC, GetWindowDC. Eğer handle BeginPaint fonksiyonuyla alınırsa EndPaint fonksiyonuyla bırakılmalıdır. GetDC veya GetWindowDC fonksiyonlarıyla alınmış ise ReleaseDC fonksiyonuyla bırakılmalıdır. BeginPaint fonksiyonu çizim handle'ını almasının yanı sıra güncelleme alanını boş küme yapar. Oysa GetDC güncelleme alanını boş küme yapmaz. Bu durumda WM_PAINT içerisinde BeginPaint API fonksiyonula handle almak daha doğrudur ve uygulamada hep böyle yapılır. Örneğin tipik bir WM_PAINT mesajı şöyle işlenmelidir:



Çizim yapan bir API fonksiyonuna BeginPaint fonksiyonuyla alınan bir handle değeri geçirilirse bu API fonksiyonu hiçbir zaman güncelleme alanının dışına çizim yapamaz. Yani çizim parametreleri tüm pencereye ilişkin olsa bile yalnızca güncelleme alanı içerisindeki bölgeyi çizerler. Aslında bu çalışma biçimi gereksiz çizim yapılmaması için tasarlanmıştır. Ancak tabii güncelleme alanının tamamen dışında kalan çizimler için bile API fonksiyonlarının içine girilir(Halbuki bu fonksiyonlar reel olarak hiçbir çizim yapamayacaklardır), böylece yine gereksiz bir zaman kaybı oluşabilecektir. Bu zaman kaybının da oluşmaması isteniyorsa WM_PAINT içerisinde önce güncelleme alanına bakılmalı, program akışının gereksiz çizimlere girmemesi sağlanmalıdır. Ancak çizim yapan API fonksiyonlarına GetDC ile alınan handle geçirilirse bu API fonksiyonları çalışma alanının her tarafına çizim yapabilirler. BeginPaint ve GetDC fonksiyonlarıyla alınan handle için orijin noktası çalışma alanının sol üst köşesidir. Yani bu handle'lar ile ancak çalışma alanı içerisine çizim yapılabilir. Ancak GetWindowDC ile alınan handle için orijin noktası pencere başlığının sol üst köşesidir. Yani pencerenin her yerine çizim yapılabilir.

BeginPaint ve EndPaint Fonksiyonları

            Prototipleri:



            BeginPaint fonksiyonunun birinci parametresi çizim için alınacak handle'a ilişkin pencerenin handle değeridir. İkinci parametre PAINTSTRUCT türünden yapının adresini alır. BeginPaint bu yapının içerisini faydalı bilgilerle doldurur. Fonksiyonun geri dönüş değeri çizim işlemi için elde edilen handle bilgisidir.



            Alınan handle değerinin geri bırakılması BeginPaint fonksiyonundaki parametrelerle yapılır.
            Tipik bir WM_PAINT mesajı şöyle işlenir:

Çizim İşlemlerinde Renk


            Windows'daki bütün renkler kırmızı, yeşil ve mavinin bileşiminden elde edilir. Burada bu üç rengin herbiri 0-255 arasında bir ton ile ifade edilir ve bunların karışımından da bir renk elde edilir(RGB bilgileri video kartına bağlı olarak 8 bitten daha az olabilir. Ancak Windows bunları uygun bir biçimde oranlamaktadır). Örneğin R=0, G=0, B=255 değerleri kullanıldığında tam bir mavi renk elde edilir. Toplam elde edilebilecek renk sayısı 8 * 8 * 8 biçimindedir. (24 bit True Color mode RGB tonlarının herbirinin 1'er byte ile ifade edildiğini anlatır).
            API fonksiyonları bir renk bilgisini parametre olarak alacağı zaman bunu ayrı ayrı RGB parametreleri biçiminde değil tek bir long sayı biçiminde alırlar. Windows.h içerisinde şöyle bir typedef vardır:

typedef long COLORREF;

Bütün API fonksiyonları RGB tonlarını bir long sayı içerisinde aşağıdaki gibi beklerler:


Ayrı ayrı parametrelerle verilmiş olan RGB bilgilerini long bir sayı biçimine dönüştüren bir makro windows.h içerisinde aşağıdaki gibi tanımlanmıştır:


Yani sonuç olarak bir API fonksiyonu renk bilgisini COLORREF parametresiyle ister, biz de onu RGB makrosuyla veririz.

SetPixel Fonksiyonu

 Icon İşlemleri

            .ico dosyas formatına sahip içerisinde görüntü tek tek pixel renkleriyle kodlanmış bir biçimde bulunan grafiksel görüntülere icon denir. Icon görüntülenme işlemleri Windows tarafından doğrudan desteklenmektedir. Win95'e karar yalnızca 32x32'lik icon görüntüleri kullanılıyordu. Daha sonra Win sistemleri 16x16'lık icon görüntülerini de destekler hale gelmiştir. Windows içerisinde görev çubuğunda, masa üstünde, pencerenin sol üst köşesinde icon görüntüleri kullanılır. Bunun dışında programcının istediği yerde herhangi bir icon görüntülenebilir.

Programın Ana Icon'ının Oluşturulması


            Genel olarak bir icon şu adımlardan geçilerek kullanılır:
1. Icon özel editörlerle çizilir ve ico uzantısıyla diskte saklanır.
2. Icon'ın kaynak dosyasında aşağıdaki gibi belirtilmesi gerekir:
Kaynak_ismi Icon Dosya_ismi
Örnek: MYICON ICON X.ICO
3. LoadIcon API fonksiyonuyla icon kaynağı kullanıma hazır hale getirilir. Prototipi:
HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);

            Bir programın ana icon'ını belirleme işlemi WNDCLASS yapısının hIcon elemanına LoadIcon fonksiyonundan alınan handle değerinin yerleştirilmesiyle yapılır. Ancak Windows'da çalışmayı kolaylaştırmak amacıyla önceden tanımlanmış özel icon handle değerleri vardır. Bunların kullanılması için kaynak içinde belirtilmesine gerek yoktur.
            Bir pencerenin parametrik bilgileri üzerinde işlem yapan GetWindowLong, SetWindowLong fonksiyonlarının yanı sıra bir pencerenin yaratıldığı WNDCLASS yapısının elemanları üzerinde işlem yapan GetClassLong ve SetClassLong fonksiyonları da vardır. SetClassLong fonksiyonunu kullanarak WNDCLASS yapısının hIcon elemanı istenildiği zaman değiştirilebilir. Böylece herhangi bir zaman ana pencerenin icon'ı değiştirilmiş olur. Örneğin mouse'un sol tuşuna basıldığında icon şöyle değiştirilebilir:

Pencere İçerisine Icon Çizilmesi


            Bir pencere içerisine icon çizebilmek için icon'ın kaynakta belirtilip LoadIcon ile yüklenmesi gerekir. LoadIcon ile yükleme işlemi örneğin WM_CREATE mesajı içerisinde yapılabilir. Ancak çizim işleminin WM_PAINT mesajı içerisinde DrawIcon fonksiyonuyla yapılması gerekir. Prototipi:


Burada x, y koordinatları icon'ın çizileceği bölgenin sol üst köşebnin koordinatlarıdır.

Programın Çalışma Zamanı Sırasında Herhangi Bir Icon'ın Görüntülenmesi


            LoadIcon fonksiyonu ile HICON elde edebilmek için icon dosyasının kaynakta belirtilmiş olması gerekir. Halbuki kaynağa yazılma işlemi programın çalışmasından önce yapılmaktadır. Bir ico dosyasının ismini vererek hiç kaynakta belirtmeden HICON elde edebilmek için LoadImage API fonksiyonu kullanılmaktadır. LoadImage şömyle kullanılır:



Devamı... Unknown 0 yorum

seo standart penceresi

Standart Dialog Pencereleri


işletim
            Her Windows programında gördüğümüz Open, Save, Find-Replace, Color, Font, Print gibi dialog pencereleri tek bir API fonksiyonuyla oluşturulabilen standart dialog pencereleridir.

Open ve Save Dialog Pencereleri


            Open ve Save dialog pencereleri hemen hemen birbirlerinin aynısıdır. Open penceresi dosya açmak, Save penceresi saklamak amacıyla kullanılır. Open dialog penceresi GetOpenFileName API fonksiypnuyla, Save dialog penceresi ise GetSaveFileName API fonksiyonuyla yaratılır. Bu dialog pencereleri ilgili API fonksiyonlarıyla yaratıldıktan sonra kullanıcı bir dosya seçerek OK tuşuna basar(Dosya ismi klavyeyle de yazılabilir). Böylece fonksiyon sonlanır. Programcı seçilen dosyanın ismini elde eder. Bu iki API fonksiyonu da OPENFILENAME isimli bir yapı değişkeninin adresini alır. OPENFILENAME yapısının elemanları genel olarak ikisi dışında bu dialog penceresini konfigüre etmek amacıyla kullanılır. Ancak iki eleman bu API fonksiyonları tarafından doldurulur. Seçilmiş dosyanın isim ve path ifadesi bu iki elemana yazılır. Bu API fonksiyonlarının geri dönüş değerleri FALSE ise kullanıcı dialog penceresini cancel ile kapatmıştır, TRUE ise ok ile kapatmıştır. OPENFILENAME yapısının lpstrFilter elamanı Open ve Save pencerelerinde çıkan filtreleme bilgilerini barındırır. Her filtre elemanı iki parçadan oluşur. Birinci parça yazı parçasıdır, ikinci parça filtreleme bilgisini tutar.


Pencere Başlık Yazısının Değiştirilmesi

            Pencere başlığı üzerinde işlem yapan iki fonksiyon vardır: GetWindowText ve SetWindowText. SetWindowText fonksiyonu CreateWindow fonksiyonunun ikinci parametresiyle belirtilen pencere başlığı yazısının değiştirilmesini sağlar.

BOOL SetWindowText(HWND hWnd, LPCSTR lpString);

Bu fonksiyon pushbutton penceresine uygulanırsa düğme üzerindeki yazının değiştirilmesine, editbox penceresine uygulanırsa editbox içerisindeki yazının değiştirilmesine, static penceresine uygulanırsa static pencere yazısının değiştirilmesine yol açar.
            GetWindowText fonksiyonu bunun tam tersi olarak pencere başlık yazısının elde edilmesinde kullanılır.

BOOL GetWindowText(HWND hWnd, LPSTR lpString, int nMaxCount);

            Bu fonksiyonlara ek olarak üst pencerenin handle değeri ve alt pencerenin ID değerleri bilindiğinde alt pencerenin pencere başlığı üzerinde işlem yapan SetDlgItemText ve GetDlgItemText fonksiyonları da vardır. Tabii bu fonksiyonlar kendi içlerinde GetDlgItem ve SetWindowText, GetWindowText fonksiylarını kullanarak işlem yaparlar.

OPENFILENAME Yapısının Önemli Elemanları


            Bu yapının ilk elemanı olan lStructSize elemanı yapının byte uzunluğunu tutmalıdır. hwndOwner elemanı standart dialog penceresini açan üst pencerenin handle değerini tutar. hInstance elemanına programın hInstance değeri girilmelidir. Bu yapının en önemli elemanlarından birisi lpstrFilter elemanıdır. Bu eleman birden fazla yazıyı tutan bir gösterici biçimindedir. C'de char türünden bir göstericinin birden fazla yazıyı tutabilmesi şöyle mümkün olabilir: Her yazının sonu NULL karakter ile bitirilir, tüm yazının bittiği ise iki NULL karakter kullanılarak anlatılır. lpstrFilter elemanı filtre yazılarını tutar. Her filtre elemanı iki yazıdan oluşmaktadır. Bu yazının ilki filtreleme sırasında çıkacak yazıyı belirtit ve filtreleme üzerinde bir etkisi yoktur. İkinci yazı filtrelemeye ilişkin yazıdır. Birden fazla filtreleme için ; koymak gerekir. Örnek:

x.lpstrFilter = "Executable Files\0*.exe;*.com\0Text Files\*.txt\0";

Seçim yapıldıktan sonra elde edilen dosya ismi bu API fonksiyonları tarafından lpstrFileTitle elemanının gösterdiği adrese yerleştirilir. Yani fonksiyon çağırılmadan önce bu elemanın tahsis edilmiş bir diziyi göstermesi gerekir. nMaxFileTitle elemanı ise bu dizinin en büyük uzunluğunu belirtmektedir. Bu eleman dosya ismini path ifadesi olmadan yalnızca isim biçiminde tutar. Tabii dosyanın uzantısı da alınmaktadır. Yapının lpstrInitialDir elemanı dialog penceresinin default hangi dizin için açılacağını belirtir. Seçilen dosyanın ismi tüm path bilgisiyle birlikte lpstrFile elemanının gösterdiği adrese yerleştirilir. Bu elemanın gösterdiği yazının maksimum elemanın nMaxFile elemanında saklanmalıdır.



Örnek Programın Açıklaması


            Örnek programda bir menü alınmış, menüye Open, Save ve Exit elemanları yerleştirilmiştir. Sembolik sabitleri ID_FILE_OPENX, ID_FILE_SAVEX, ID_FILE_EXITX.

Checkbox ve Radiobutton Kontrolleri


            Checkbox küçük bir kare ve yanında yazı bulunan bitr konroldür. Genellikle dialog pencerelerinin içerisinde kullanılır. Üzerine click yapıldığında içi çarpılanır. Genellikle bir özelliği dahil etmek ya da kaldırmak amacıyla kullanılır. Bu kontrolden elde edilecek bilgi kontrolün çarpılanıp çarpılanmadığıdır. Checkbox kontrolü CreateWindow fonksiyonunda "button" sınıf ismi girilerek yaratılır. Ancak pencere biçimi olarak BS_CHECKBOX girilir.

hCheckBox = CreateWindow("button", "Example", WS_CHILD | WS_VISIBLE | BS_CHEKBOX.....);

CreateWindow fonksiyonunun ikinci parametresinde belirtilen pencere başlık yazısı kare görüntüsünün yanında çıkar. Checkbox'lar otomatik, normal ve üç konumlu omlak üzere üçe ayrılırlar. Checkbox kontrolüne çarpı koyabilmek için BM_SETCHECK mesajı gönderilir. Bu mesajda lParam 0 alınır, wParam 1 ya da 0 olabilir. 1 çarpılama oluşacağını, 0 oluşmayacağını belirtir.

SendMessage(hCheckBox, BM_SETCHECKBOX, 1, 0);

Checkbox kontrolünün çarpılanıp çarpılanmadığını BM_GETCHECK mesajı ile elde edebiliriz. Bu mesajda wParam ve lParam 0 girilir. Fonksiyonun geri dönüş değeri 0 ya da 1 olur. 1 çarpılı, 0 çarpısız anlamına gelir.

status = SendMessage(jhCheckBox, BM_GETCHECK, 0, 0);

Checkbox kontrolü üzerine click yapıldığında tıpkı pushbutton kontrolünde olduğu gibi checkbox kontrolü WM_COMMAND mesajı ile BN_CLICKED durum kodu ile çağırılır. Normal checkbox'larda kontrolün üzerine click yapıldığında çarpılama işlemi kontrolün kendisi tarafından değil, gönderilen mesaj ile programcı tarafından yapılır. Normal checkbox'larda çarpılama işlemi aşağıdaki gibi yapılabilir.

case WM_COMMAND:
                switch(LOWORD(wPAram)) {
                               case ID_CHECK:
                                               if (HIWORD(wParam) == BN_CLICKED) {
                                                               if (SendMessage(hCheckBox, BM_GETCHECK, 0, 0))
                                                                              SendMessage(hCheckBox, BM_SETCHECK, 0, 0);
                                                               else
                                                                              SendMessage(hCheckBox, BM_SETCHECK, 1, 0);
                                               }
                               break;
                }

Oysa otomatik checkbox kontrolünde çarpılama işlemi kontrolünden kendisi tarafından zaten yapılmaktadır. Otomatik checkbox yaratabilmek için BS_CHECKBOX yerine BS_AUTOCHECKBOX pencere biçimi kullanılır. Checkbox genellikle dialog pencerelerinde kullanılır. Dialog penceresi ilk görüntülendiğinde çarpılanmış bir görüntü elde edebilmek için WM_INITDIALOG mesajında çarpılama işleminin bilinçli bir şekilde yapılması gerekir.

case WM_INITDIALOG:
                SendDlgItemMessage(hWnd, ID_CHECK, BM_SETCHECK, 1, 0);
                return TRUE;

Üç konumlu checkbox kontrolünde checkbox'ın 3 durumu vardır: Çarpılı, çarpısız ve etkin omayan durum. Bu chackbox kontrolü pencere biçimine ek olarak BS_3STATE eklenerek yaratılırlar. Otomatik ve üç konumlu chackbox kontrolleri Win32 sistemleriyle eklenmiştir.
            Radiobutton kontrolü dairesel bir şeklin içerisine noktasal bir şeklin yerleştirilmesine olanak sağlar. Genellikle bir grup radiobutton kontrolü biçiminde kullanılır. Genellikle radiobutton kontrollerinin bir anda yalnızca bir tanesi seçili olacak biçimde kullanılır. Uygulamada birden fazla seçenekten yalnızca bir tanesinin seçilmesi gerektiği durumlarda kullanılır. Checkbox kontrolleri tek başlarına kullanılabilir, ancak radiobutton kontrolleri grup olarak kullanılmalıdır. Bu kontrolün yanında tıpkı checkbox'ta olduğu gibi betimleyici bir yazı vardır. Bir grup içerisindeki bütün radiobutton kontrolleri tek tek CreateWindow fonksiyonuyla yaratılmalıdır. Radiobutton kontrolleri normal ve otomatik olmak üzere iki kısma ayrılırlar. Otomatik radiobutton kontrolleri Win32 sistemleriyle tanımlanmıştır. Bu kontrolü yaratabilmek için CreateWindow fonksiyonu içerisinde sınıf ismi olarak "button" girmek, pencere biçimi olarak BS_RADIOBUTTON ya da BS_AUTORADIOBUTTON vermek gerekir. Pencere başlık yazısı betimleyici yazı olarak görünür. Bu kontrol ana pencerenin içerisine gömülmek yerine genellikle dialog pencerelerinde kullanılır. Radiobutton kontrolünün üzerine click yapıldığında kontrol üst pencereye BN_CLICKED durum koduyla mesaj gönderir. Radiobutton kontrolünü çarpılamak için checkbox'ta yapıldığı gibi BM_SETCHECK mesajı gönderilir.

SendMessage(hRadioButton, BM_SETCHECK, 1, 0);

Bu kontrolün çarpılanıp çarpılanmadığı BM_GETCHECK mesajı ile sorgulanabilir.

status = SendMessage(hRadioButton, BM_GETCHECK, 0, 0);


Normal radiobutton'larda bir grup kontrolden bir tanesine click yapıldığında click yapılanı çarpılamak, çarpılı olanı silmek programcının görevidir. Autoradiobutton yalnızca dialog pencerelerinde kullanılır. Bunun için bir radiobutton grubu tanımlanması gerekir. Bu grup kaynak içerisinde tanımlanabilmektedir. Autoradiobutton grubunda bir kontrole click yapıldığında click yapılan otomatik olarak çarpılanır. Çarpılanmış olan da otomatik olarak silinir. Normal radiobutton'larda çarpılama işlemi birkaç biçimde yapılabilir:






case WM_COMMAND:
                switch(LOWORD(wParam)) {
                               case ID_RADIO1:
                                               ......
                                               ......
                                               ......
                               case ID_RADIO2:
                                               ......
                                               ......
                                               ......
                               case ID_RADIO3:
                                               ......
                                               ......
                                               ......
                }
                break;

yada daha sistematik bir yöntem kullanılabilir:

struct CBOX {
                WORD id;
                int status;
} x[4] = {{ID_RADIO1, 0}, {ID_RADIO2, 1}, {ID_RADIO3, 0}, {ID_RADIO4, 0}};

switch (LOWORD(wParam)) {
                case ID_RADIO1:
                case ID_RADIO2:
                case ID_RADIO3:
                case ID_RADIO4:
                               ProcessCheck(LOWORD(wParam));
                               break;
}

void ProcessCheck(WORD id)
{
                int i;
                HWND hRadio;

                for (i = 0; i < 4; ++i) {
                               if(x[i].status == 1) {
                                               x[i].status = 0;
                                               hRadio = GetDlgItem(hWnd, x[i].id);
                                               SendMessage(hRadio, BM_SETCHECK, 0, 0);
                               }
                               if (x[i].id == id) {
                                               x[i].status = 1;
                                               hRadio = GetDlgItem(hWnd, id);
                                               SendMessage(hRadio, BM_SETCHECK, 1, 0);
                               }
                }
}

            Örnek programda iki radiobutton dialogh penceresi üzerine çıkartılmış ve durumları elde edilmiştir. İster auto, ister normal olsun bir grup içerisindeki hangi radiobutton'ın çarpılanmış olduğunu anlamak için bir sorgulama yapılması gerekir. En pratik yöntem hepsine BM_GETCHECK mesajı göndermek ve hangisi çarpılanmışsa onu tespit etmek olabilir.
            Autoradiobutton'larda radiobutton grubunun tespit edilmesi WS_GROUP pencere biçimiyle yapılmaktadır. Dialog kaynağında radiobutton kontrolü RADIOBUTTON ismiyle yaratılır. Kaynakta ilk WS_GROUP pencere biçimine sahip radiobutton grubun ilk elemanı kabul edilir. Bundan sonraki radiobutton kontrolleri grup içerisindedir. Bir sonraki WS_GROUP pencere biçimli radiobutton kontrolüne kadarki tüm radiobutton kontrolleri bu grup içinde kabul edilir.

Çizim İşlemleri


            Bir pencerenin üzerine doığrudan yazısal ya da grafiksel çizimler yapılabilir. Pencerenin üzerine yazı yazma işlemi de bir çeşit çizim işlemi olarak değerlendirilir. Aslında static kontrolünü kullanarak yazı yazılması durumunda da bir çeşit çizim işlemi yapılmaktadır. Ancak burada çizim işlemini static kontrolünün pencere fonksiyonu yapar. Oysa bir yazı yazmak için bir alt pencerenin tanımlanması gerekmez. Bir pencere içerisinde yapılan çizim Windows tarafından otomatik olarak saklanmaz. Örneğin bir pencere başka bir pencere tarafından kapatıldığında Windows kapatılan pencere içerisindeki çizim görüntüsünü saklamaz. Bu görüntünün, yani bütün pencere çizimlerinin yeniden programcı tarafından yapılması gerekir. Windows bir pencerenin bir bölümü herhangi bir biçiminde kapatıldığında ya da açıldığında o pencere için mesaj kuyruğuna WM_PAINT mesajını bırakır. Bu durumda pencere içerisindeki bütün mesajlar WM_PAINT mesajı içerisinde yapılmalıdır. WM_PAINT mesajı şu durumlarda gönderilir:

1. Pencerenin boyutları değiştirildiğinde,
2. Bir pencereyi kaplamış olan başka bir pencerenin çekilmesi durumunda,

WM_PAINT şu durumlarda gönderilmez:

1. Bir menünün açılmasıyla ve kapatılmasıyla oluşan durumda Windows pencere görüntüsünü otomatik olarak saklar, WM_PAINT mesajını göndermez.
2. Bir pencere taşındığında Windows pencere görüntüsünü otomatik olarak oluşturur.

Pencere Çizimleri Nerede Yapılamalıdır?


            Windows pencere çizim görüntülerini otomatik olarak saklamadığı için pencere görüntüsünün her değişiminde yani her WM_PAINT mesajı geldiğinde bütün çizimler yeniden yapılmalıdır. Bu durumda bütün çizimler WM_PAINT mesajı içerisinde yapılmalıdır. Eğer çizimler başka yerde yapılırsa pencere görüntüsünün değişiminde başka yerde yapılan çizimler kaybolur.

Pencere Güncelleme Alanı(Window Update Region)

            Bir pencerenin yeniden çizilmesi gereken en küçük dikdörtgensel alanına güncelleme alanı denir. Güncelleme alanı dikdörtgensel olmak zorundadır. Pencere

içerisindeki görüntüyü yeniden oluşturmak için yalnızca güncelleme alanı içerisindeki bölümün yeniden çizilmesi yeterlidir. Üçgensel bir bölge ya da dairesel bir bölge güncelleme alanı olamaz. Windows bu bölgelere ilişkin en küçük dikdörtgeni hesap ederek güncelleme alanı yapar. Windows her pencere için bir günceleme alanının koordinat bilgisini tutmaktadır. Tabii Windows her pencere için tek pencere alanı tutar ve bunu sürekli güncelleştirir. Örneğin bir pencerenin boyutu değiştirildiğinde güncelleme alanı tüm pencere olur. Bir pencerenin güncelleme alanının koordinat bilgisi bir API fonksiyonu yardımıyla sistemden alınabilir. Güncelleme alanı boş küme ise  pencerenin hiçbir bölgesinin yeniden çizilmesine gerek yoktur. Güncelleme alanının boş küme yapılması Windows tarafından otomatik bir biçimde yapılmaz. Windows güncelleme alanını gerektiğinde güncelleştirir. Örneğin daraltp genişletebilir. Ancak boş küme yapmaz. Windows bütün pencerelerin güncelleme alanlarına periyodik olarak bakar, güncelleme alanı boş küme olmayan bir pencere alanıyla karşılaştığında ona WM_PAINT mesajını gönderir. Bu mesajı göndermesiyle kendisi güncelleme alanını ototatik olarak boş küme yapmaz. Güncelleme alanı programcı tarafından boş küme yapılmalıdır. Güncelleme alanının boş küme yapılması için en iyi yer WM_PAINT mesajının içidir. Yani sonuç olarak eğer WM_PAINT içerisinde güncelleme alanı boş küme yapılmazsa pencereye sürekli WM_PAINT mesajı gönderilir, program da sürekli ,çiizm yapan bir biçimde çalışır ve performans kaybı olur(Aslında Windows yeni güncelleme alanı eski güncelleme alanının içerisinde kalıyorsa güncelleme alanını güncellemez).
Devamı... Unknown 0 yorum

seo dialog penceresi

WM_INITDIALOG Mesajı


            Yapay dialog penceresi fonksiyonunda WM_CREATE mesajı işlenmeye çalışılırsa programcı şunu bilmelidir: Bu noktada henüz dialog penceresinin kendi penceresi yaratılmış olmasına karşın içerisindeki kontroller henüz yaratılmamıştır. Dolayısıyla bu mesajın yapay dialog penceresi içerisinde işlenmesi pek faydalı değildir. Oysa kontroller yaratıldıktan sonra gerçek pencere fonksiyonu yapay pencere fonksiyonunu WM_INITDIALOG mesajıyla çağırır. Bu noktada kontroller yaratılmıştır ama görünür halde değildir. Yani gerçek dialog penceresi fonksiyonunun WM_CREATE mesaında şunlar yapılmıştır:
1. Yapay dialog penceresi fonksiyonu WM_CREATE mesajıyla çağırılmıştır.
2. Kontroller WS_VISIBLE pencere biçimi olmadan yaratılmıştır.
3. Yapay dialog penceresi fonksiyonu WM_INITDIALOG mesajıyla çağırılmıştır.
4. Kontroller ShowWindow fonksiyonuyla görüntülenmiştir. 

Örnek Dialog Penceresi Programı


            Dağıtılan örnek programda menü'den bir seçim yapıldığında bir dialog penceresi oluşturulmuştur. Dialog penceresi içerisinde 4 tane kontrol yaratılmıştır. Edit box içerisine yazılan yazı bir push button'a basıldığında list box'a eklenmiştir. Diğer push button'a basıldığında dialog penceresi sonlandırılmıştır. Pencere açıldığında list box'ın içerisinde iki yazı görünmektedir. Bu yazılar WM_INITDIALOG mesajında eklenmiştir. EndDialog fonksiyonu doğal olarak yapay dialog penceresi fonksiyonu içerisinde çağırılmalıdır. DialogBox API fonksiyonu dialog pencerelerini ve kontrolleri yarattıktan sonra kendi mesaj döngüsüne girer. Tıpkı WinMain'deki mesaj döngüsü gibi kuruktan mesajları alır, dialog penceresine ilişkinse DispatchMessage ile işler, başka bir pencereye ilişkinse kuyruktan alarak görmemezlikten gelir ve siler.Böylece modal dialog penceresi açıldığında kapanana kadar arka planda bir işlem gerçekleşemez. yapay pencere fonksiyonu içerisinde EndDialog API fonksiyonu çağırıldığında gerçek dialog penceresi fonksiyonu dialog penceresini kapatır, DialogBox içerisindeki mesaj döngüsünden çıkılır, böylece akış DialogBox fonksiyonundan devam eder.

Default Push Button

            Deafult push button sadece dialog pencerelerinde kullanılır. Dialog penceresi üzerinde hiçbir push button kontrolü aktif kontrol değilse(örneğin o anda edit kontrolü üzerinde yazı yazılıyor olabilir) enter tuşuna basıldığında üzerine click yapılmış varsayılan push button kontroldür. Bir dialog üzerinde tek bir DEFPUSHBUTTON kontrolü olmalıdır. Eğer hiçbir push button DEFPUSHBUTTON değilse enter tuşuna basıldığında LOWORD(wParam) IDOK olacak biçimde WM_COMMAND mesajı çağırılır. Dialog penceresi içerisinde ESC ya da Ctrl+break tuşlarına basıldığında WM_COMMAND mesajı LOWORD(wParam) IDCANCEL olacak biçimde çağırılır.

Sınıf Çalışması: Programın menüsü şu biçimdedir:
Dialog1
Dialog2
Exit

Dialog1: Adı Soyadı ve bu değeri alacak bir edit box, No ve bu değeri alacak bir edit box bir list box, ok ve exit pushbutton'ları
Dialog2: Static kontrol ve ok tuşu

Dialog Tabanlı Uygulamalar

            Dialog tabanlı çalışma programda bir ana pencere olmadan yalnızca dialog penceresi açarak çalışma anlamına gelir. Tabii bu durumda DialogBox fonksiyonunda hWndParent parametresi olarak NULL girmek gerekir. Dialog tabanlı çalışma küçük uygulamalarda hızlı kod yazma olanağını sağlar. Dialog tabanlı çalışmada WinMain içerisinde yalnızca DialogBox fonksiyonuyla dialog penceresi açılır. Başka bir koda gereksinim duyulmaz.


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdParam, int nCmdShow)
{
                return DialogBox(
                               hInstace,
                               MAKEINTRESOURCE(ID_DIALOG),
                               NULL,
                               (DLGPROG)DialogProc
                );
}

Böylece yalnızca yapay dialog penceresi fonksiyonunun yazılması ile küçük uygulamalar gerçekleştirilebilir. Herhangi bir WNDCLASS yapısının tanıtılması ve mesaj döngüsünün oluşturulması gerekmez, çünkü DialogBox fonksiyonu zaten dialog penceresinin ana penceresini yaratmak için önceden tanımlanmış bir sınıfı kullanmaktadır. DialogBox fonksiyonu ayrıca kendi mesaj döngüsüne sahip olduğu için WinMain içerisinde bir mesaj döngüsü yaratmaya gerek kalmaz. İçinden çıkılabilen en basit diloag pencere fonksiyonu şöyle yapılabilir:

BOOL CALLBACK DialogProc(HWND hWnd, UINT iMessage,
WPARAM wParam, LPARAM lParam)
{
                if (iMessage == WM_COMMAND && LOWORD(wParam) == IDOK) {
                               EndDialog(hWnd, 0);
                               return TRUE;
                }
                return FALSE;
}

Bu minimum kodla yazılmış olan dialog penceresi fonksiyonu dialog mesajlarını işlemez ancak test amacıyla kullanılabilir.

Özel Kontroller


            Programcı kendisinin yarattığı bir kontrolü de dialog penceresinin içerisine yerleştirebilir. Gerçek dialog penceresi fonksiyonu ilgili kontrolü CreateWindow fonksiyonuyla yaratabilmek için kontrolün yaratılacağı sınıf ismine gerek duyar. Aslında dialog penceresinin resource'unun içinde kullanılan PUSHBUTTON, EDITTEXT gibi dialog elemanları bu kontrollerin yaratılması esnasında kullanılacak sınıf ismini belirtir. En genel dialog kaynağı elemanı "CONTROL" diye isimlendirilen elemandır. Çünkü bu eleman içerisinde yaratuılacak kontrolün sınıfı belirtilebilir. Böylece PUSHBUTTON, EDITTEXT, STATIC gibi ayrı anahtar sözcükler kullanmak yerine bu kontrollerin hepsi sınıf ismi belirtilerek CONTROL anahtar öszcüğüyle belirtilebilir. Yani dialog elemanı olarak PUSHBUTTON yazmak yerine CONTROL yazarak button biçiminde sınıf ismi belirtmek aynı anlama gelir.


CONTROL Elemanının Syntax'i


CONTROL "başlık yazısı",
                alt_pencere_id_değeri,
                "sınıf ismi",
                pencere biçimi,
                x,
                y,
                genişlik,
                yükseklik

Örneğin aşağıdaki iki kontrol elemanı eşdeğer anlamdadır:

PUSHBUTTON "Edit Ok",
                IB_PBOK,
                75,
                32,
                50,
                14,
                WS_CHILD | WS_VISIBLE
CONTROL "Edit Ok",
                ID_PBOK,
                "button",
                WS_CHILD | WS_VISIBLE,
                75,
                32,
                50,

                14
Devamı... Unknown 0 yorum