Visual C++ ile Görsel Programlama 2 (win32)

Pencere bileşenleri hakkında örnekler.

Visual C++ ile Görsel Programlama 2( Pencere Bileşenleri )

önceki derste basit bir pencereyi nasıl yapacağımızı gördük. Ama hiçbir komut veya düğme yoktu bomboş bir pencere idi. şimdi pencere üzerine bir düğme koyarak işlem yapan bir sistemi inceleyelim. Ana pencere oluşturma komutu ile aynı komut düğme yapmamıza yarayacak. aşağıda sadece düğme ve metin kutusu yapan kod parçası var. bu kodu önceki derste yaptığımız pencere koduna ekleyeceğiz. Ayrıca LRESULT CALLBACK kısmına da WM_COMMAND mesajını ekleyeceğiz.


#define ID_DUGME    121 //düğmeye daha kolay erişim için bir menü numarası veriliyor
#define ID_TEXT        122 // metin kutusu için menü numarası
HWND hdume; //düğmenin kulpu (handle)
HWND hmetin; //metin kutusu kulpu

hdugme = CreateWindow("BUTTON","Kapat", //burada "BUTTON" isimli sınıf (class) yazmamız önemli
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, //sırası ile "Görünür_Olsun|YavruPencere_olsun |Enter_ile_Basılsın"
150,0,100,30, //düğmenin pencere üzerindeki yeri ve boyu
hwnd, //Ana pencerenin kulpu (handle)
(HMENU) ID_DUGME, hInstance, NULL);

hmetin = CreateWindow("EDIT", "", // sınıfı = metin kutusu "EDIT"
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_AUTOHSCROLL,
150, 40, 500, 200,
hwnd, (HMENU)ID_TEXT,
GetModuleHandle(NULL), //instance değerine bu fonksiyon ile ulaşabiliriz
NULL);

 

 

#include //tanımlamalar #define ID_DUGME 100 #define ID_DUGME2 101 #define ID_TEXT 102 HWND hdugme; HWND hdugme2; HWND hmetin; const char Classismi[] = "pencere"; // gelen mesajları işleyen kısım LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { int wmId; int sayi; char yazi[50]; switch(msg) { case WM_COMMAND: wmId = LOWORD(wParam); switch (wmId) { case ID_DUGME: //birinci düğmeye basıldığında yapılacak işlemler SendDlgItemMessage(hwnd, ID_TEXT,EM_GETLINE,(WPARAM) 0,(LPARAM)yazi); sayi =atoi(yazi); sayi=sayi*sayi; itoa(sayi, yazi, 10); MessageBox(NULL,yazi,"bulunan sonuç",MB_OK); break; case ID_DUGME2: //ikinci düğmeye basıldığında yapılacak işlem SendMessage(hmetin, WM_SETTEXT, 0,(LPARAM)" "); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX penceretipi; //aşağıda tanımlamasını yapacağımız pencere özellikleri içeren değişken HWND hwnd; MSG Msg; //birinci adım: Pencere özelliklerini belirten bir sınıf değişkeni tanımlanıyor penceretipi.cbSize = sizeof(WNDCLASSEX); penceretipi.style = 0; penceretipi.lpfnWndProc = WndProc; penceretipi.cbClsExtra = 0; penceretipi.cbWndExtra = 0; penceretipi.hInstance = hInstance; penceretipi.hIcon = LoadIcon(NULL, IDI_APPLICATION); penceretipi.hCursor = LoadCursor(NULL, IDC_ARROW); penceretipi.hbrBackground = (HBRUSH)(COLOR_WINDOW); penceretipi.lpszMenuName = NULL; penceretipi.lpszClassName = Classismi; penceretipi.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&penceretipi)) { MessageBox(NULL, "Pencere tanımlama hatası!", "Hata!", MB_ICONEXCLAMATION | MB_OK); return 0; } // ikinci adım pencere oluşturma hwnd = CreateWindow(Classismi,"Sayı Giriniz",WS_OVERLAPPEDWINDOW, 200, 200, 400, 300,NULL, NULL, hInstance, NULL); hdugme = CreateWindow("BUTTON","Karesini Al", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 220,10,100,30, hwnd, (HMENU) ID_DUGME, hInstance, NULL); hdugme2 = CreateWindow("BUTTON","Temizle", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 220,50,100,30, hwnd, (HMENU) ID_DUGME2, hInstance, NULL); hmetin = CreateWindow("EDIT", "", WS_CHILD | WS_VISIBLE |WS_BORDER| ES_NUMBER, 10, 10, 200, 30, hwnd, (HMENU)ID_TEXT,GetModuleHandle(NULL),NULL); SendDlgItemMessage(hwnd, ID_TEXT,EM_SETLIMITTEXT,(WPARAM) 4,(LPARAM)0); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); // üçüncü adım: mesajların alınması ve ayrılması while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }

Eğer başka bir düğme daha olsaydı aşağıdaki gibi bunları da alt alta yazacaktık.

case WM_COMMAND: switch (wmId) { case ID_DUGME: //birinci düğmeye basıldı break; case ID_DUGME2: //ikinci düğmeye basıldı break; case ID_DUGMEKAPAT: //üçüncü düğmeye basıldı break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break;

 

Tüm Komutlar da Birer Mesajdır

Windowsta tüm bileşenler pencere varsayılmaktadır.( düğme ve metin kutusu da windows sisteminde birer pencere kabul edilir) Herhangi bir pencere ile işlem yapabilmek için o pencereye mesaj yollamamız gerekir.

Aslında esas mesaj komutu SendMessage komutudur. Fakat handle numarası bilinmiyorsa başka komutlar da kullanılabilir. açılımı şu şekildedir.

SendMessage(HWND,MSG,wParam,Lparam);

HWND: mesajı alacak olan pencere ( hwnd yada hdugme gibi.)

MSG: yollanacak mesajın cinsi bu her pencere için farklı türdedir.
WM_ENABLE: pencereyi aktif yada iptal etmek için, WM_SETTEXT: pencere üzerindeki yazıyı değiştirmek için, WM_SIZE: pencere boyunu değiştirmek için ve benzeri birçok mesaj türü vardır. uzun bir listeyi microsoft sitesinde bulabilirsiniz. sizden gelen talep fazla olursa burada da yayınlayabilirim.

wParam ve Lparam : Mesaj türüne göre bu iki parametre de değişmektedir. bu parametrelerin ne olduğu mesaj ile birlikte açıklanır. mesela:

WM_SETTEXT
wParam = 0; // not used; must be zero
lParam = (LPARAM)(LPCTSTR)lpsz; // address of window-text string

internette herhangi bir kaynakta açıklamayı bu şekilde bulursunuz. burada wParam=0 olması zorunlu. Lparam ise pencereye atanacak yazıyı içeren değişkeni belirtmeli. bizim yukardaki örnekte WM_GETLINE komutunu kullanırken yazi isimli değişken kullanmamız gibi.

SendDlgItemMessage(hwnd, ID_TEXT,EM_GETLINE,(WPARAM) 0,(LPARAM)yazi);

Yukardaki SendDlgItemMessage komutunu ; herhangi bir pencerenin sadece Menü adını biliyorsak kullanabiliriz ( ID_TEXT ) fakat biz handle( kulp ) adını da bildiğimizz için isteseydik.

SendMessage( hmetin, EM_GETLINE,(WPARAM) 0,(LPARAM)yazi);

bu şekilde de yazabilirdik. Nitekim ikinci düğme ile yazı silme işlemi için SendMessage(hmetin, WM_SETTEXT, 0,(LPARAM)" "); sadece handle numarasını kullanarak işlem yaptık. WM_SETTEXT komutu ile metin kutusuna yazı atamak istediğimizi söylüyoruz fakat yazı olarak " " boşluk girdiğimiz için metin kutusundaki yazı gidip yerine boşluk geliyor.

STANDART C BiLMEDEN OLMAZ

işlem yaparken kullandığımız birkaç küçük fonksiyon vardı. Bunlar standart Ansi-C fonksiyonları. Bunları bilmeden yaptığımız işlemler sadece pencere çizmek ve pencereleri haraket ettirmek olacaktır. Yapılacak esas işlemler C komutları ile yapılacaktır. örneğin bir dosyayı silmek istiyorsanız yada adını değiştirmek istiyorsanız yine C komutlarından faydalanacaksınız. tabii bunu yaparken de gerekli fonksiyon dosyalarını include komutu ile projeye dahil etmelisiniz.


sayi =atoi(yazi); // itoa fonksiyonu: yazıyı sayıya çevirir.

sayi=sayi*sayi; //sayıyı kendisi ile çarpıyoruz.

itoa(sayi, yazi, 10); //bulduğumuz sonucu tekrar yazıya çeviriyoruz. çünkü sonucu mesaj kutusuna yazacağız ve mesaj kutusu sadece yazı değişkenlerini alır

Hazırladığınız EXE dosyasını win95, winNT gibi farklı ortamlarda deneyip uyumunu kontrol edebilirsiniz. kesinlikle diğer program dillerine fark atan bir çıktınız olacaktır. yazı kısmı daha uzun ama neyi niçin yazdığınızı biliyorsunuz. Yazdığınız program sadece bugünkü windows sistemlerinde değil ilerde çıkacak windows sürümleri ile de tam uyumludur.

Temel Windows bilgisini aldınız sayılır. Bundan sonrası diğer pencereler. Combobox, ListView, TreeView... vb.
Ayrıca öğreneceğiniz birçok fonksiyon ve Makro var. bunların dev gibi bir listesi www.microsoft.com sitesinde bulunuyor. Yeri geldikçe sonraki derslerde bunlara değineceğiz. Türkçe bir kaynak olan şu siteyi de ziyater edebilirsiniz. http://www.platformsdk.com.tr.tc/

Biz bundan sonraki derslerde oyun yapımı ile iligili uygulamalara geçiyoruz.

Konuyu anladık mı ?
Uygulama sorusu: Pencereye üç tane metin giriş kutusu yapın ve ilk iki kutuya sayı girip düğmeye bastığımızda ilk iki kutuya yazdığımız değerler toplanıp üçüncü kutuya yazılsın

Ekleyen: drekon

Kapalı

Topic closed automatically because it`s been more than a year!