Kas
01

Directx ile Programlamaya Giriş (DirectX ve C++ ile ilk program)

Bu bölümde DirectX ile ilk programımızı yapacağız. Ama öncelikle DirectX programlarının derlenebilmesi için  DirectX 9.0 SDK paketini indirmelisiniz. Bu paket içerisinde DirectX programlama için gerekli olan kütüphane dosyaları ve çeşitli yardımcı araçlar bulunmaktadır.

Programlama yaparken yapılan ilk program olmazsa olmaz Hello World programıdır : ) fakat DirectX ile yazı yazmak o kadar kolay olmadığı için bu geleneği uygulayamıyoruz onun yerine arkaplanı mavi boş bir pencere oluşturmakla yetineceğiz.

ilk programı yaparken izleyeceğimiz adımları şöyle açıklayabiliriz :
1 – Global değişkenleri ve fonksiyonlar tanımlama
2 – Direct3D  initialize eden fonksiyonu oluşturarak Direct3D objesi oluşturmak
3 – Çizim fonksiyonunu oluşturmak
4 – Kullanılan hafızaları bırakan fonksiyonu oluşturmak


1- Global değişkenleri ve fonksiyonlar tanımlama

Direct3D ile çalışmaya başlarkan  ilk yapılması  gereken Global değişken ve fonksiyonları tanımlamaktır.

// Pencere ve Direct3D için başlık dosyaları
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>

//  Direct3D Kütüphane dosyası
#pragma comment (lib, "d3d9.lib")

// global değişkenler
LPDIRECT3D9 d3d;    //  Direct3D için işaretçi
LPDIRECT3DDEVICE9 d3ddev;    // Direct3D device için işaretçi

// fonksiyon tanımlamaları
void initD3D(HWND hWnd);    // Direct3D hazırlayan fonksiyon
void render_frame(void);    // çizim fonksiyonu
void cleanD3D(void);    //Direct3D yi kapatan ve hafızayı temizleyen fonksiyon

// WindowProc fonksiyonu için tanımlama
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

 


 

2 – Direct3D initialize metodunu ve  Direct3D device objesi oluşturmak 

Bu bölümde Direct3D kullanımı için ilk adımlar atılmaktadır. Bunun için bazı device bilgilerini tutan struct kullanacağız. Bunlar Direct3D nin hangi pencere üzerinde çizim yapacağı, pencerenin tam ekran mı yoksa pencere halinde mi olacağı gibi birtakım önemli bilgiler.

// bu fonksiyon Direct3D yi kullanım için hazırlıyor
void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);    // Direct3D arayüzünü oluşturur

    D3DPRESENT_PARAMETERS d3dpp;    // çeşitli device bilgilerini tutmak için bir struct değişken

    ZeroMemory(&d3dpp, sizeof(d3dpp));			// struct 'ı kullanmak için temizliyoruz
    d3dpp.Windowed = TRUE;						// program tamekran değil, pencere şeklinde
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // eski çerceçeveleri etkisiz kılar
    d3dpp.hDeviceWindow = hWnd;					// Direct3D nin kullanacağı pencereyi belirtiyoruz

    // d3dpp struct'ını kullanarak bir device sınıfı oluşturur
    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);
}

 


 

 3 – Çizim fonksiyonunu oluşturmak

Bu fonksiyon her bir çerçeve için çalıştırılacak olup çizim işlemlerinin yapıldığı fonksiyondur. Bu yazımızda birşey çizdirmeyip sadece arkaplanı maviye boyayacağız. Tabi isterseniz siz rengi değiştirebilirsiniz.

// herbir çerçeve için tekrarlanarak kullanılacak çizim metodu
void render_frame(void)
{
    // pencereyi arkaplan mavi olacak şekilde temizler
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

    d3ddev->BeginScene();    // 3D çizim'e başlanır 

    // çizilecek şeyleri bu arada çizdiriyoruz

    d3ddev->EndScene();    // 3D SAHNE SONU

    d3ddev->Present(NULL, NULL, NULL, NULL);   // oluşturulan çerçeveleri Pencerede gösterir.
}

4 – Direct3D’ yi kapatan ve hafızayı temizleyen fonksiyonu oluşturmak 

Oyun programlamada hafızayı kontrol etmek çok önemli bir olaydır. Çok ufak bile olsa kullanılıp işi biten her nesneyi silmek hafızadan çıkarmak gereklidir, aksi taktirde hafıza taşacak program kapanacaktır.

// bu metod Direct3D 'yi ve hafızayı temizler
void cleanD3D(void)
{
    d3ddev->Release();    // 3D device'i kapatır ve hafızadan kaldırır
    d3d->Release();		  //Direct3D'yi kapatır ve hafızadan kaldırır
}

Sonuç
Bu yazımızda Directx ve C++ kullanarak ilk programımızı yaptık.Henuz bir çizgi dahi çizmemiş olsak ta Directx’in bacağını kırdığımızı düşünüyorum. Bir sonraki dersimizde çizim yapmaya başlayacağız.
Bu dersin tam kodunu aşağıdaki linke tıklayarak görebilirsiniz .

/* 	yazar  : Muhammet Gümüş
    kaynak : muhammedgumus.com
*/
// temel pencere ve Direct3D başlık dosyaları
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>

// Direct3D kütüphane dosyası
#pragma comment (lib, "d3d9.lib")

// global tanımlamalar
LPDIRECT3D9 d3d;			// Direct3D için işaretçi
LPDIRECT3DDEVICE9 d3ddev;    // Direct3D device için işaretçi

// fonksiyon tanımlamaları
void initD3D(HWND hWnd);    //Direct3D hazırlayan fonksiyon
void render_frame(void);    // çizim fonksiyonu
void cleanD3D(void);		//Direct3D yi kapatan ve hafızayı temizleyen fonksiyon

// WindowProc fonksiyonu için tanımlama
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// Windows programları için kullanılan Winapi fonksiyonu
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = L"WindowClass";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
                          L"WindowClass",
                          L"ilk Direct3D Programim",
                          WS_OVERLAPPEDWINDOW,
                          300, 300,
                          800, 600,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);

    ShowWindow(hWnd, nCmdShow);

    // Direct3D hazırlayıp çalıştıran metod
    initD3D(hWnd);

    // ana döngüye giriyor
    MSG msg;
    while(TRUE)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if(msg.message == WM_QUIT)
            break;

        render_frame();
    }

    // Directx'i ve hafızayı temizle
    cleanD3D();

    return msg.wParam;
}

// Programın ana mesaj handle'i
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

// bu fonksiyon Direct3D yi kullanım için hazırlıyor ve çalıştırıyor
void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);    // Direct3D arayüzünü oluşturur

    D3DPRESENT_PARAMETERS d3dpp;    // çeşitli device bilgilerini tutmak için bir struct değişken

    ZeroMemory(&d3dpp, sizeof(d3dpp));			// struct 'ı kullanmak için temizliyoruz
    d3dpp.Windowed = TRUE;						// program tamekran değil, pencere şeklinde
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // eski çerceçeveleri etkisiz kılar
    d3dpp.hDeviceWindow = hWnd;					// Direct3D nin kullanacağı pencereyi belirtiyoruz

    // d3dpp struct'ını kullanarak bir device sınıfı oluşturur
    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);
}

// herbir çerçeve için tekrarlanarak kullanılacak çizim metodu
void render_frame(void)
{
    // pencereyi arkaplan mavi olacak şekilde temizler
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

    d3ddev->BeginScene();    // 3D çizim'e başlanır 

    // çizilecek şeyleri bu arada çizdiriyoruz

    d3ddev->EndScene();    // 3D SAHNE SONU

    d3ddev->Present(NULL, NULL, NULL, NULL);   // oluşturulan çerçeveleri Pencerede gösterir.
}

// bu metod Direct3D 'yi ve hafızayı temizler
void cleanD3D(void)
{
    d3ddev->Release();    // 3D device'i kapatır ve hafızadan kaldırır
    d3d->Release();		  //Direct3D'yi kapatır ve hafızadan kaldırır
}

Kas
01

Directx Nedir ve Nasıl Çalışır

DirectX Nedir ?
DirectX, Windows platformları için kullanılan Oyun Uygulamaları Programlama Arayüzüdür(API-Application Programming Interface).Günümüzde farklı amaçlar içinde kullanılmaktadır.Bu tanım DirectX açıklamak da pek de yeterli görünmüyor. DirectX’i açıklayabilmek için zamanda biraz geri gitmemiz gerekebilir. DirectX çıkmadan önce programcılar, oyun programlarını DOS işletim sistemi üzerinde geliştiriyorlardı. DOS işletim sistemi programcılara, ekran kartının bütün fonksiyonlarını kullanmasına izin vermekteydi. Programcı direkt olarak ekran kartını kontrol edebiliyordu.Bu sayede oyunun ihtiyaç duyduğu hızı karşılayabiliyorlardı. Windows için ne yazıkki aynı şeyi söyleyemiyoruz. Windows ekran kartını direkt kullanıma müsade etmemektedir.Bunun yerine kullanıcıya GDI adı verilen arayüzü geliştirmiştir.Bu arayüz çeşitli API fonksiyonlarından ve yapılardan oluşmaktadır.Fakat GDI oyun programcılarının hız konusundaki beklentilerini karşılayamamaktaydı. Oyun programcıları doğal olarak DOS işletim sisteminde programlamaya devam ettiler. DOS’un sağladığı özgürlüğünde dez avantajları vardı elbette.Ekran kartları farklılık göstermekteydi. Bu sebepten dolayı farklı ekran kartları için farklı derleyiciler geliştilmesi gerekiyordu(Programcılar yazdıkları komutları ekran kartının makine kodlarına çevirmek zorundaydılar.Ekran kartlarının farklı olması bu kodlarında farklı olmasına yol açabiliyordu). Aynı işlemler ses kartları ve diğer kartlar içinde geçerliydi. Microsoft bütün bu sorunlara çözüm olarak DirectX’i geliştirdi.

DirectX, programcı ile Ekran kartı arasında bir arayüz görevi görür.Üretilen her kart için Aygıt Sürücüsü(Device Driver) adı verilen küçük yazılım paketleri geliştirilir. Bu yazılımın görevi aldığı DirecX direktiflerini kartın anlayabileceği kodlara çevirmektir. Bu sayede programcı üzerindeki büyük bir yükten kurtulmuş olur.

 

DirectX Nasıl Çalışır ?

Ekran kartları için üretilen sürücüler içerisinde HAL(Hardware Abstraction Layer) adı verilen bir yapı bulunmaktadır. HAL ekran kartı ile direkt iletişim kurabilmekte dir.Bu da onu oldukça hızlı yapmaktadır.HAL‘ın asıl görevi aldığı DirectX komutlarını kartın anlayabileceği komutlara çevirmektir(Tabi ekran kartının desteklediği komutlarsa).
Programcı ekran kartının desteklemediği bir özelliği kullandığında HEL(Hardware Emulation Layer) devreye girer.HEL ekran kartının desteklemediği işlemleri İşlemciye yaptırır.Elbette HAL den daha yavaştır ama en azından program hata vermeden gerekeni yapar.
DirectX sayesinde kullanıcı ekran kartının faydalarından yararlanırken arka planda gerçekleşen bir çok angarya işden de arındırılmaktadır.
Şekilde de görüldüğü gibi program DirecX araçlarını kullandığında HAL veya HEL devreye girmektedir.Başlangıçta basit bir arayüz olarak karşımıza çıkan DirectX, günümüzde vazgeçilmez bir yapı haline gelmiştir.

 

DirectX ve COM
DirectX ,COM objelerinden oluşmaktadır.Peki COM nedir. COM’ un açılımı Component Object Model dir.COM objeleri aslında C++ nesnelerinden ibarettir.DirectX e sağlağdığı avantaj ise programlama dili özgürlüğü ve eski versiyonlarla uyumdur. Derslerimizde COM yapısı ile ilgili daha fazla bilgiye ihtiyaç duymadığımızdan fazla detaya inmek istemiyorum. COM objeleri normal nesneler gibi new komutuyla oluşturulmazlar.Onlara ait adrese ulaşmak için çeşitli fonksiyonlar kullanıyoruz..Bunun örneğini ilerde göreceğiz. COM nesnelerini kaldırmak için delete komutu yerine herbirinin içinde barındırdığı Release() fonksiyonunu kullanıyoruz.COM objeleri hakkında anlatılacak daha çok şey olmasına karşın bizim için bu kadarı yeterli.

 

Çerçeve Tamponu(Frame Buffer) ve Değişim Zinciri (Swap Chain)

Monitörlerin çoğunluğu saniyede 60 resim gösterme kapasitesine sahiptir. Ekranda bir an için gösterilen resim ekran kartının belirli bir hafıza alanında bulunmaktadır. Kart bu alandaki bilgileri sürekli olarak monitöre yollamaktadır.Şimdi hayal gücümüzü biraz çalıştıracağız. 1024×768 çözünürlüğe sahip bir monitör düşünelim.Her bir pixelin 32-bit lik renk değerleri ile temsil edildiğini düşünelim.Monitörde oluşacak bir resim için ayırılması gereken alan.

1024×768=786432 adet pixel bulunmakta
(786432*32)/8=3.145.728 byte= 3,14 MB lık bir hafıza alanı gerekmektedir.

Programcı ekrana çıkmasını istediği çizimleri bu hafıza alanına yerleştirir.Fakat bu sistemde bir problem ortaya çıkmaktadır. Monitörlerin tazeleme oranı 60 dan 100Hz e kadar değişmektedir.Monitör tazeleme yaparken ekran kartındaki hafıza alanına başka bir resim yerleştirilirse Monitördeki resim iki parçaya ayrılacaktır.Üst de eski resimin yarısı alt da yeni resimin yarısı yer alacaktır. Bu olaya tearing(yırtılma) adı verilir. Bu yan etkiden kurtulmak için DirectX Swapping(Değişim) adı verilen bir özelliği kullanır.

Resimleri direk monitöre göndermek yerine DirectX resimlerimizi ikinci bir hafıza alanına yerleştirir.Bu alana Arka Tampon adı verilir.Ön Tamponise monitöre gönderilen hafıza alanıdır.Biz çizimlerimizi Back Buffer a yaparız. İşimiz bittiğinde DirectX Ön Tampon daki eski resmin üzerine Arka Tampon daki resmi yerleştirecektir. Fakat bu bile yırtılmaya sebep olabilir. Çünkü kopyalama işlemi monitör tazeleme yaparken gerçekleşebilir. Bu durumdan kurtulmak için DirectX iki tampon için birer pointer(gösterici) barındırır. Gerektiği zaman sadece bu adresleri değiştirir.

Eki
31

Pencere Oluşturma (C++ ve Windows ile)

C++ kullanarak Windows üzerinde pencere oluşturmak C#, Java gibi üst seviye diller kullanan programcılar için bir hayli zor ve uzun görülebilir. Fakat bu sizi tedirgin etmesin çünkü kodlar hep aynıdır. Pencereyi bir kere oluşturursunuz değil mi ?  : ) ezberlemenize bile gerek yoktur.elinizin altında bir örneği bulunsun (gerektiği zaman kopyala yapıştır yaparsınız).Ama her ihtimale karşı kodların ne işe yaradığını bilmekte fayda var. Öncelikle C++ ve Windows programlamada pencere oluşturmak için gerekli kodlar aşağıdaki  gibidir. Gerekli açıklamalar kodun altında yapılacaktır.

#include<windows.h>
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	HWND hWnd; //Penceremizin handle'ı
	WNDCLASSEX WndEx; //Penceremizin sınıfını
	ZeroMemory(&WndEx,sizeof(WNDCLASSEX)); //Pencere Sınıfımızın hafızadaki alanını sıfırlanır
	WndEx.style=CS_HREDRAW|CS_VREDRAW; //Pencerenin stili
	WndEx.lpfnWndProc=WndProc; //Pencere fonksiyonunun adı
	WndEx.cbClsExtra=0;
	WndEx.cbWndExtra=0;
	WndEx.hInstance=hInstance; //Ait olduğu uygulamanın Id si
	WndEx.hIcon=::LoadIcon(0,IDI_APPLICATION);//Pencere ikonu
	WndEx.hCursor=::LoadCursor(0, IDC_ARROW); //Kursorun alacağı şekil
	WndEx.hbrBackground=(HBRUSH)COLOR_WINDOW; //Pencerenin rengi
	WndEx.lpszClassName=L"PencereClass"; //Pencere sınıfının adı
	WndEx.cbSize=sizeof(WNDCLASSEX); //Pencere sınıfının boyutu
	RegisterClassEx(&WndEx); //Pencere sınıfı Windowsa tanıtılır
	hWnd = CreateWindowEx(NULL, //Pencere oluşturma fonksiyonunu çalıştırılır
		L"PencereClass", //Pencere sınıfının adı.
		L"Deneme Projesi", //Pencerenin başlığı
		WS_OVERLAPPEDWINDOW, //Pencerenin biçimi
		200, //Pencerenin başlangıç x noktası.
		200, //Pencerenin başlangıç y noktası.
		640, //Pencerenin Genişliği
		480, //Pencerenin Boyu
		NULL, //Anne pencerenin handle'ı
		NULL, //Pencerenin menüsünün adresi
		hInstance, //Ait olduğu uygulamanın ID'i
		NULL);
	ShowWindow(hWnd,nCmdShow); //Penceremizi kullanıcı için görünür yapılır
	MSG message;
	while(GetMessage(&message,NULL,NULL,NULL)) //Mesaj Döngüsü başlangıcı
	{
		TranslateMessage(&message);
		DispatchMessage(&message);
	}
	return message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)//Pencere Fonskiyonu Tanımlanıyor
{
	switch(message) //Alınan mesaj "switch" koşul yapısına atılır
	{
	case WM_DESTROY:
		{
			PostQuitMessage(0); //Pencere WM_DESTROY mesajı aldığında uygulamaya kapatma
			return 0; //komutu gönderilir
		}
	}
	return DefWindowProc(hWnd,message,wParam,lParam);
}
Bu kodları kısaca açıklayacak olursak :
HWND hWnd : Oluşturacağımız pencere işaret eden bir işaretçidir.Bu değişken pencerenin kimliği gibi düşünülebilir.
WNDCLASSEX WndEx : pencerenin özelliklerini barındıran WNDCLASSEX yapısından WndEx adıyla bir değişken oluşturulur, bu değişken pencerenin özelliklerini barındıracak.
WNDCLASSEX yapısı aşağıdaki gibidir.
typedef struct {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;
C++ dilinde bir değişken oluşturulduğunda bir hafıza değeri o deşikene verilir, değişken için bir başlangıç değeri atanmaz dolayısıyla verilen hafıza bölgesinde, önceden kalma bazı değerler olabilir ve bu değerler yeni oluşturulan değişken için problem teşkil edebilir. Bu nedenle oluşturulan bir değişkenin hafıza alanının temizlenmesi önemlidir. Bu işlem ZeroMemory fonksiyonu ile gerçekleştirilir.
WndEx.style=CS_HREDRAW|CS_VREDRAW : bu değişken ile pencerenin stil değeri saklanır. Burada kullanılan CS_HREDRAW ve CS_VREDRAW değerleri pencerenin boyutunun değiştirildiği zaman pencerenin yeniden çizileceğini gösterir.
WndEx.lpfnWndProc=WndProc : Bu değişkende pencere fonksiyonun adı saklanır. Pencere uygulamadan aldığı mesajları bu fonksiyona gönderir.
WndEx.cbClsExtra=0, WndEx.cbWndExtra=0 : Pencerenin ihtiyaç duyabileceği extra byte sayıları bu iki değerle belirtilir.
WndEx.hInstance=hInstance : Pencereyi kontrol eden uygulamanın kimliği niteliğinde olan bir değişkendir.Bu değişkene ―handle‖ denilmektedir.
RegisterClassEx(&WndEx) : Oluşturulan WndEx yapısı windowsa tanıtılır, aksi taktirde Windows pencere oluşturmayacaktır.
hWnd=CreateWindowEx(…) : RegisterClassEx fonksiyonu sayesinde Windows pencereden haberdardır fakat hala pencere oluşturulmamıştır. Pencere oluşturma işlemini adından da anlaşılacağı gibi CreateWindowEx fonksiyonu gerçekleştirir ve fonksiyonun dönüş değeri hWnd değişkenine atanır.CreateWindowEx fonksiyonunun parametreleri aşağıdaki gibidir ve gerekli açıklamalar yapılmıştır.
hWnd = CreateWindowEx(NULL, L"PencereClass", //Pencere sınıfının adı.
L"Deneme Projesi", //Pencerenin başlığı
WS_OVERLAPPEDWINDOW, //Pencerenin biçimi
200, //Pencerenin başlangıç x noktası.
200, //Pencerenin başlangıç y noktası.
640, //Pencerenin Genişliği
480, //Pencerenin Boyu
NULL, //Anne pencerenin handle'ı
NULL, //Pencerenin menüsünün adresi
hInstance, //Ait olduğu uygulamanın ID'i
NULL);
ShowWindow(hWnd,nCmdShow) : Pencere oluşturuldu fakat henuz kullanıcıya gösterilmedi bu işi yapan ShowWindow fonksiyonudur. Bu fonksiyonun ilk parametresi gösterilecek olan pencerenin adresi, ikinci parametresi ise pencerenin ekranda nasıl gösterileceğini belirten bir değerdir.

Eki
30

Windows Olay ve Mesaj Sistemi

Windows programlama Console programlamadan biraz farklıdır. Console programlama da program main fonksiyonu ile başlar ve herhangi bir döngü veya fonksiyon gelene kadar satır satır sıra ile işlenir.Windows programlamada ise program bir şeylerin(olay) olmasını bekler.Bu olay klavyeden bir tuşa basılması veya farenin tıklanması olabilir.Eğer herhangi bir olay olmaz ise program sadece beklemedir. Herhangi bir olay olduğunda Windows bu olaya uygun mesajı uygulamanın Mesaj Kuyruğu’ na yerleştirir.

Şekil : Windows Olay ve Mesaj sistemi çalışma döngüsü
typedef struct {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
}MSG, *PMSG;
Mesaj yapısı yukarıdaki gibi tanımlanmıştır. Windows oluşan herhangi bir olay için bu yapıyı dolduracaktır.
MSG message;
while(GetMessage(&message,NULL,NULL,NULL)) //Mesaj Döngüsü başlangıcı
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
Yukarıdaki kod parçası ile bir mesaj yapısı oluşturulur ardından döngüye girilir. Döngü, GetMessage fonksiyonu ile ilgili bir hata olmadıkça devam edecektir. GetMessage fonksiyonu kuyruktaki mesajı aldıktan sonra bir kopyasını message isimli değişkene atar ve TranslateMessage fonksiyonu bu değişkeni uygun formata çevirir.Daha sonra DispatchMessage fonksiyonu devreye girer. Bu fonksiyon, mesajın ait olduğu pencerenin fonksiyonunu çağırır.Bu pencere fonksiyonu içerisinde programcı, pencere ile ilgili mesajları yakalar ve olaylarla ilgili çeşitli işlemler yaptırabilir.Örneğin klavyeden ESC tuşuna basıldığında programın sonlandırılması gibi. Bahsedilen pencere fonksiyonu şu şekilde olmalıdır.
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch(message) //Alınan mesaj "switch" koşul yapısına atılır
	{
	case WM_DESTROY:
		{
			PostQuitMessage(0); //Pencere WM_DESTROY mesajı aldığında
			return 0; // uygulamaya kapatma komutu gönderilir
		}
	} return DefWindowProc(hWnd,message,wParam,lParam);
}

Yukarıdaki kodda yakalanan mesajın WM_DESTROY olması durumunda programa çıkış mesajı yollanacaktır. Mesaj, switch koşul yapısı ile kontrol ediliyor ve yakalanan mesajlara uygun işlemler yaptırılıyor.

 

 

 

Eki
19

Java – mysql Stored procedure Türkçe karakter sorunu

Üzerinde çalıştığım bir JSF projesinde böyle bir problemle karşı karşıya kaldım proje üzerinden veritabanına kaydettiğim veriler Türkçe karakterleri desteklemiyordu  tam olayı çözdüm derken, kullandığım Procedure lerde

java.sql.SQLException: Incorrect string value: ‘xC5x9FxC5x9F…..’ for column ‘mproblem’ at row 1

şeklinde bir hata almaya başladım biraz daha araştırmanın sonucunda iki probleme de çözüm budum sizlerle paylaşayım :

öncelikle java – mysql kullanıyorsanız ve de Türkçe karakter desteklesin istiyorsanız connection Stringinizi şu şekilde ayarlamalısınız :

jdbc:mysql://localhost:3306/veritabaniadi?characterSetResults=UTF-8&characterEncoding=UTF-8&useUnicode=true”,”username”,”password”

turuncu renklerle yazılanlar karakterleri desteklemesi açısından gerekli.

veritabanına kayıt ederkenki türkçe karakter sorununu aşmış bulunmaktayız (insert into ile kaydederken)
ama  oldu da Procedure kullandınız ve yukarda belirtiğim gibi bir hata almaktaktasınız o zaman procedure lerinizi şu şekilde düzeltmelisiniz :

CREATE PROCEDURE `procedureName`(
IN mName VARCHAR(255) charset utf8)
BEGIN

insert into `tblperson`(name) values (convert(mName using utf8));

END;

turuncu renkteki  ek ifadeleri procedure nize eklerseniz bu problemi de aşmış olacaksınız

umarım işinize yarar …

Eki
19

JavaServer Faces’ a Giriş – JSFDers-1

 Bu yazılarımda  Java Server Faces nedir, diğerlerine göre ne tarz yararları vardır niçin kullanıyorum gibi şeylerden bahsetmeyeceğim – JSF Misyonerliği yapmayacağım kısacası : )- bu yazıyı okuyanların bu tarz soruları aşıp kendilerini geliştirmek isteyen kişiler olduğunu varsayıyorum. . . ozaman hadi başlayalım:

bu projeyi yaparken video alarak kaydettim dilerseniz izleyebilirsiniz:

ben projelerimde IDE olarak Netbeans kullanıyorum  indirmek isteyenler http://netbeans.org/downloads/index.html adresinden indirebilirler.

ilk olarak bir JSF projesi oluşturuyoruz  File-> New Project-> Dynamic Web Project->
ve  bu projenin Framework u olarak Java Server Faces’ i seçiyoruz  versiyon olarak 2.0 versiyonunu seçiyoruz ve artık JSF projemiz kullanıma hazır. Configurasyon Dosyalarından bahsedelim biraz

web.xml

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
web.xml dosyasında bulunan yukarıdaki kod proje çalıştığı an hangi sayfanın çalıştırılacağını gösterir

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

yine web.xml dosyasında bulunan yukarıdaki kodlar  ‘*.jsf’  sayesinde sayfaların uzantıları .jsf olarak kullanılır örneğin browser daki /anasayfa.jsf  adresi anasayfa.xhtml  dosyasını çalıştırır.

ManagedBean
ManagedBean JSF nin en yaralı özelliklerinden biridir ve bu özellik JSF 2.0 da çok da kullanışlı hale gelmiş durumda  Managed Bean, oluşturduğumuz .java class ları web sayfaları üzerinde kullanmamızı sağlar. peki nasıl kullanılır :

@ManagedBean
public class HelloBean {
private String welcome;
private String content;

görüldüğü gibi gayet basit tek yapmamız gereken sınıfın üstüne @ManagedBean Annotation nu koymak, tabi bu sınıftaki kullanmak istediğimiz değişkenlerin getter ve setter metodlarının bulunması gerekir.
Peki bu değişkenleri sayfa içinde nasıl göstereceğiz? çok basit   #{helloBean.welcome} işte bu şekilde daha fazla örnek ve bilgi için  hazırladığım videoyu izleyebilir ayrıca videodaki proje dosyasını BURDAN indirebilirsiniz