Visual C++ ile Görsel Programlama 4 (Win32)

Visual C++ ile Görsel Programlama 4, Resimler ve Komutları

Untitled Document

Visual C++ ile Görsel Programlama 4 ( Resimler ve Komutları)

Öncelikle Projemize kaynak dosyaları eklemeyi öğrenelim (Resources). Bunlar ikon, resim, menü ve diyalog kutusu gibi dosyalardır. bunları isterseniz VisualC++ içindeki editör yardımı ile çizersiniz veya import diyerek önceden hazırlanmış bir dosyayı açabilirsiniz.

Kaynak Ekleme

Kaynak eklemek için insert >> Resource menüsüne giriyoruz

karşımıza çıkan pencerede Yeni bir dosya(New) yada önceden çizilmiş hazır dosya seçeneklerinden birini seçiyoruz. Burada öncelikle bitmap diyerek projemize bir resim ekleyelim.

Daha sonra kaydet düğmesine basıyoruz. Burada kaydedilen dosya script.rc isimli bir kaynak dosyası oluyor. Sadece resim ve ikonları değil bunları proje içinde çağırmak için kullanılan sayılar da bu dosya ile birlikte otomatik oluşturuluyor.

Kaydettiğimiz script.rc dosyası şu anda projeye dahil değil çünkü sol taraftaki dosyalar sekmesinde görünmüyor. Bu dosyayı prıjeye eklediğimizde resim dosyası da bununla birlikte eklenecektir. Resource Files dosyasına sağ tıklayıp Add Files to Folder diyerek az önce kaydettiğimiz script.rc dosyasını seçiyoruz.

Script.rc dosyasını ekledikten sonra Header Files kısmına bakıyoruz eğer resource.h dosyası burada görünmüyorsa; Header Files yazısına sağ tıklayıp Add Files to Folder diyerek resource.h dosyasını seçiyoruz.

Resource.h dosyası bir başlık dosyasıdır ve projeye eklenen tüm kaynaklar bu dosyada görünür.

Kaynak dosyalarını ekledikten sonra sol alt tarafta yeni bir sekme oluştuğunu göreceksiniz. Bu sekmeye geçerek buradan tüm kaynakları görme ve düzenleme imkanınız olacaktır ( resim ikon vb. kaynakları düzenledikten sonra kaydetmeyi unutmayın)

Yukardaki resme bakarsanız projenin bu resme otomatik olarak IDB_BITMAP1 adını verdiğini göreceksiniz. bu isimden faydalanarak resim dosyasını kod içersinden çağırabileceğiz. Bir Örnek ile resim yapıştırmayı görelim. ( bu işlem size uzun gelebilir ama 2 boyutlu ilk oyun denememizde bunu kullanacağız.)

 

 

 

 
#include <windows.h> #include "resource.h" const char Classismi[] = "pencere"; HBITMAP resim=NULL; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: DeleteObject(resim); PostQuitMessage(0); break; case WM_CREATE: resim = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1)); break; case WM_PAINT: //esas çizim kodu bu kısımda yazılı HDC hdc; HDC resimhdc; PAINTSTRUCT ps; RECT anakare; hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &anakare); FillRect(hdc, &anakare, (HBRUSH)(LTGRAY_BRUSH)); resimhdc = CreateCompatibleDC(hdc); SelectObject(resimhdc,resim); BitBlt(hdc, 0, 0, 150, 200, resimhdc, 0, 0, SRCCOPY); DeleteDC(resimhdc); EndPaint(hwnd, &ps); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = Classismi; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Pencere tanımlama hatası!", "Hata!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindow(Classismi,"Pencere başlığı",WS_OVERLAPPEDWINDOW, 200, 200, 300, 200,NULL, NULL, hInstance, NULL); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }

Bu projeye eklediğimiz kod parçalarını yazıyorum. öncelikle resource.h dosyasını projey eekledik ama bu kod içinde kullanılacağını belirtmedik. çünkü projemizde birçok kod sayfası olabilir ve programa resource.h dosyasının hangisinde kullanılacağını belirtmeliyiz. bunun için en başa

#include "resource.h"

yazdık. ikinci önemli konu ise resim dosyasının ilk oluşturulması ve hafızadan silinmesi işlemleri için WM_CREATE ve WM_DESTROY sırasında da resim dosyasıyla ilgili kod yazıyoruz.

case WM_CREATE:
  resim = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1));
break;

burada dikkat edeceğimiz nokta projenin en başında HBITMAP resim=NULL; diyerek belirlediğimiz resim değişkenine yüklenen (LoadBitmap) resmin adıdır.(IDB_BITMAP1). Daha önce menülerden projeye eklediğimiz resim dosyasını burada kod yardımı ile bir değişkene atıyoruz (resim). bundan sonra proje içinde resim isimli değişkeni kolayca kullanabiliriz.. eğer birçok resim dosyamız olsaydı bunları da bu şekilde farklı değişkenlere yüklememiz gerekecekti.

case WM_DESTROY:
   DeleteObject(resim);
   PostQuitMessage(0);
break;

Program kapatılırken resim isimli değişkeni de hafızadan silmeyi unutmuyoruz. şimdi gelelim kodun en önemli kısmına. Resmi hdc üzerine yapıştırma işlemi. hdc'nin ne olduğunu daha önceki dersimizde görmüştük. Bu kodu WM_PAINT mesajı içersine yazıyoruz. bu mesaj genelde şu durumlarda çağrılır: pencere yeniden çizildiğinde , pencere haraket ettiğinde, simge durumuna geçtiğinde, başka bir programın arkasına gidip geldiğinde... vb şekilde ekrana tazelenerek geldiği durumlarda.

 

case WM_PAINT:
  HDC hdc; // ana pencere çizim alanı
  HDC resimhdc; //resmi taşıyan çizim alanı
  PAINTSTRUCT ps; //çizime başlarken kullanılan yapı
  RECT anakare; //Ana pencere ölçülerini alacak dikdörtgen yapı

  hdc = BeginPaint(hwnd, &ps); //Bu komut ile çizime başlanıyor
  GetClientRect(hwnd, &anakare); //Ana pencerenin ölçüleri alınıyor
  FillRect(hdc, &anakare, (HBRUSH)(LTGRAY_BRUSH)); //Ana pencere Gri renge boyanıyor

  resimhdc = CreateCompatibleDC(hdc); // resimhdc yapısı tanımlanıyor
  SelectObject(resimhdc,resim); // resimhdc içersine resim aktarılıyor
  BitBlt(hdc, 0, 0, 150, 200, resimhdc, 0, 0, SRCCOPY); // bilgi kopyalama ( hdc <<< resimhdc )

  DeleteDC(resimhdc); //resimhdc yok ediliyor
  EndPaint(hwnd, &ps); //çizim bitiriliyor
break;

Bu kod içersinde en önemlisi ise BitBlt isimli fonksiyondur. Bu fonksiyon iki farklı HDC arasında bilgi taşıma yada karşılaştırma gibi işlemler yapar.

BitBlt( hedefHDC, ilknoktaX, ilknoktaY, ikincinoktaX, ikincinoktaY, kaynakHDC, ikiX, ikiY, KOMUT);
ilknoktaX : hedefte sol üst köşe X konumu
ilknoktaY : hedefte sol üst köşe Y konumu
ikincinoktaX : hedefin eni
ikincinoktaY : hedefin boyu
ikiX : kaynak alanın sol üst köşesi X konumu
ikiY :kaynak alanın sol üst köşesi Y konumu
KOMUT: işlem komutu

Buradaki resmin taşınması işlemini aşağıdaki resimden daha iyi anlayabilirsiniz.

Yukarda sadece kopyalama yapan komut kullanıldı. BitBlt birçok komut içermektedir. listesi aşağıda.

BLACKNESS Hedef alanı 0 numaralı renk ile doldurur (normalde siyah renk)
DSTINVERT Hedef alanın renklerini ters çevirir
MERGECOPY Hedef Alanın renklerini belirtilen Desen ile VE (AND)komutunu kullanarak birleştirir.
MERGEPAINT Renkleri ters çevrilmiş kaynak ile hedef alanı VEYA(OR) komutu ile birleştirir.
NOTSRCCOPY Ters Çevrilmiş kaynak Alanı hedef Alan üzerine kopyalar.
NOTSRCERASE Kaynak ve Hedef renklerini VEYA(OR) komutu ile karıştırıp sonucu ters çevirir.
PATCOPY Kaynak Deseni Hedef Resme kopyalar
PATINVERT Kaynek Desen ile Hedef Alanı VEYADEĞİL(XOR) komutu ile birleştirir.
PATPAINT Desen ile Kaynağın ters çevrilmiş renklerini VEYA (OR) komutu ile birleştirir.Bu işlemin sonucu alınıp Hedef ile VEYA(OR) komutu kullanılarak birleştirilir.
SRCAND Hedef ve kaynak Alanlar VE(AND) komutu ile birleştirilir.
SRCCOPY Kaynak Alan direkt olarak hedefe kopyalanır.
SRCERASE Hedefin Renkleri ters çevrilerek Kaynak Alan ile VE(AND) komutu ile birleştirilir.
SRCINVERT Kaynak ve Hedef Alanların renkleri VEYADEĞİL(XOR)komutu ile birleştirilir.
SRCPAINT Hedef ve Kaynak Alanlar VEYA (OR) komutu ile birleştirilir
WHITENESS Hedef Alan 1 numaralı renk ile doldurulur (normalde bu renk beyazdır)

Bu komutların nasıl çalıştığını örnekte inceleyelim. VE komutunun çalışması için kaynak ve hedef alanların ikisinde de aynı renk bulunmalıdır. VEYA komutunda ise iki alandan birinde renk bulunması yeterlidir.VEYADEĞİL komutu iki alanda de renk boş ise çıkış verir.

VE (AND)
VEYA (OR)
VEYADEĞİL(XOR)
Kesişme noktası dolu ise çıkış verir Resim olan noktalar birleşir Resim olmayan noktalar birleşip sonuç olur

Sahneye resim çağırayı da öğrendik şimdi de zaman aracını öğrenip ilk oyunumuzu yazmaya geçeceğiz.

Konuyu anladık mı ?
Uygulama sorusu: Ana pencereye farklı noktalarda iki resim yapıştırın, ikinci resim birincinin tersi olsun.

Ekleyen: drekon

DMCA.com