BG MVC Model View Controller eğitim serisi yayında...

Ana page > Programlama > Windows API Programlama > GDI İşlemleri

GDI İşlemleri

GDI ve Device Context kavramları

Windows GDI, sistemdeki aygıt sürücülerle iletişime geçerek, programların ekran ve yazıcı üzerinde grafik işlemleri gerçekleştirmelerini sağlayan bir arayüzdür.

Device context: Aşağıda gösterilen grafik nesnelerini ve grafik modlarını tanımlamaya yarayan bir yapıdır.

Bir pencere üzerinde grafik işlemleri gerçekleştirmek için o pencereye ait bir DC Handle değeri elde etmek gerekir. Program DC'yi bir pencere için elde eder veya oluşturur. DC elde edildiğinde, ilgili pencere üzerinde, yazı yazma, çizgi çizme, boyama vb. grafik işlemleri yapılabilir.

Grafik nesneleri

Grafik nesneleri

Bitmap: Ekran bölümlerini kopyalamaya yarar. Büyüklük (byte), boyut (piksel), renk, vb.özellikler içerir. CreateBitmap(), CreateBitmapIndirect(), CreateCompatibleBitmap(), CreateDiscardableBitmap() ve CreateDIBitmap() fonksiyonları kullanılarak nesne oluşturulur.

Brush: Boyama ve doldurma işlemleri için renk ve özellikler tanımlamaya yarar. Stil, renk, örnek ve kaynağı özelliklerini içerir. CreateBrushIndirect(), CreateDIBPatternBrush(), CreateDIBPatternBrushPt(), CreateHatchBrush(), CreatePatternBrush() ve CreateSolidBrush() fonksiyonları kullanılarak nesne oluşturulur.

Palette: Mevcut renkleri tanımlamaya yarar. Renk ve boyut özelliklerini içerir. CreatePalette() fonksiyonu ile gerekli işlem yapılır.

Font: Yazı yazma için font ayarlarını yapmaya yarar. Font adı, genişliği, yüksekliği, vb.özellikler içerir. CreateFont() ve CreateFontIndirect() fonksiyonları kullanılarak nesne oluşturulur.

Path: Boyama ve çizme işlemlerinde kullanılır. Şekil özelliği içerir.

Pen: Çizgi çizme işlemi için renk ve özellikler tamımlamaya yarar. Stil, genişlik ve renk özellikleri içerir. CreatePen(), CreatePenIndirect() ve ExtCreatePen() fonksiyonları kullanılarak nesne oluşturulur.

Region: Belirli bölgeler (Dikdörtgen, elips, poligon veya üç şeklin karışımı) üzerinde işlemler yapmak için kullanılır. Yer ve boyutlar özellikleri içerir. CreateEllipticRgn(), CreateEllipticRgnIndirect(), CreatePolygonRgn(), CreatePolyPolygonRgn(), CreateRectRgn(), CreateRectRgnIndirect() ve CreateRoundRectRgn() fonksiyonları kullanılarak nesne oluşturulur.

Bir program bir DC elde ettiğinde veya oluşturduğunda, grafik nesneleri açısından 2 seçeneği vardır:

1. DC için sistem ön tanımlı grafik nesnelerini kullanmak (Bitmap ve Path hariç) veya özelliklerini değiştirerek kullanmak.

2. DC için yeni grafik nesneleri oluşturarak kullanmak (SelectObject() ve DeleteObject() fonksiyonları ile).

Yukarıda gösterilen ve bir grafik nesnesi oluşturan fonksiyonların tamamı oluşturduğu nesneyi gösteren bir Handle değeri döndürür. Program, oluşturulan tüm nesneler için SelectObject() fonksiyonunu kullanarak, elde edilen Handle değerini DC değerinin ön tanımlı değeri haline getirir. Nesne ile ilgili işlemleri tamamladıktan sonra, DeleteObject() fonksiyonunu kullanarak nesneyi siler.

Grafik modları

Grafik modları

Background: Yazı yazma, çizgi çizme ve brush işlemlerinde arka planın ön tanımlı arka plan rengi ile boyanıp boyanmayacağını belirler. Modun durumu GetBkMode() fonksiyonu ile elde edilir, SetBkMode() fonksiyonu ile değiştirilir.

Drawing: Pen, brush, bitmap ve metin işlemleri için kullanılan renklerin ekranda yer alan renklerle ne şekilde harmanlanacağını belirler. Modun durumu GetROP2() fonksiyonu ile elde edilir, SetROP2() fonksiyonu ile değiştirilir.

Mapping: Grafik çıktısının pencere, ekran veya yazıcıya hangi ölçülerde ve ne şekilde aktarılacağını belirler. Modun durumu GetMapMode() fonksiyonu ile elde edilir, SetMapMode() fonksiyonu ile değiştirilir.

Polygon-fill: Poligonların iç bölgesini dolduran fonksiyonlar için doldurm modunu belirler. Modun durumu GetPolyFillMode() fonksiyonu ile elde edilir, SetPolyFillMode() fonksiyonu ile değiştirilir.

Stretching: Bitmap sıkıştırıldığında veya orantılandığında, bitmap renklerinin pencere veya ekran renkleri ile ne şekilde harmanlanacağını belirler. Modun durumu GetStretchBltMode() fonksiyonu ile elde edilir, SetStretchBltMode() fonksiyonu ile değiştirilir.

Bir program bir DC elde ettiğinde veya oluşturduğunda, grafik modları açısından da 2 seçeneği vardır:

1. DC için sistem ön tanımlı grafik modlarını kullanmak.

2. DC için grafik modlarını değiştirerek kullanmak.

DC çeşitleri

4 farklı DC vardır:

Ekran (Display): Ekran üzerindeki çizim işlemleri için kullanılır. Programlar, BeginPaint(), GetDC() veya GetDCEx() fonksiyonlarından birisini kullanarak bir ekran DC'si oluşturur. Bu durumda, sadece client bölgeye çizim yapılabilirken, GetWindowDC() fonksiyonu ile oluşturulan DC ile tüm pencere üzerine çizim yapılabilir. Programlar çizim işlemini tamamladıklarında, kullanılan DC oluşturma fonksiyonlarına bağlı olarak EndPaint() veya ReleaseDC() fonksiyonlardan birisi ile DC'yi serbest bırakır.

Yazıcı (Printer): Yazıcıdaki çizim işlemleri için kullanılır. Yazıcı DC'si CreateDC() fonksiyonu ile oluşturulur, yazma işlemi bittikten sonra DeleteDC() fonksiyonu ile silinir.

Bellek (Memory): Bitmap üzerindeki çizim işlemleri için kullanılır. Bu durumda, belleğin bir bölümü bitmap verilerini depolamak için kullanılır. CreateCompatibleDC() fonksiyonu ile oluşturulur.

Bilgi (Information): Ön tanımlı aygıt (device) verilerini almak için kullanılır. Programlar, CreateIC() fonksiyonu ile oluştururlar. Bilgi alma işlemi sona erdiğinde DeleteDC() fonksiyonu ile DC silinir.

Şimdi, programımıza grafik işlemleri ile ilgili kodları eklemeye çalışalım:

resource.rc dosyası oluşturma

resource.rc

Resource dosyası içinde, piksel işlem ayarlarını yapmayı sağlayan CHECKBOX, COMBOBOX ve BUTTON kontrollerini içeren modeless bir diyalog kutusu ile 2 açılır menüye sahip bir menü oluşturulur.


#include "resource.h"

IDD_VERIBOX DIALOGEX 70, 10, 200, 80
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
FONT 8, "MS Sans Serif"
BEGIN
    CHECKBOX "Rastgele renk seçimi", IDC_CHECK, 10, 10, 120, 10
    LTEXT "Piksel tekrar sayısı", IDC_TEXT, 10, 30, 100, 100
    COMBOBOX IDC_COMBO, 70, 28, 50, 74, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
    DEFPUSHBUTTON "&OK", IDOK, 140, 20, 50, 14
END

IDR_MENU MENU
BEGIN
    POPUP "&İşlemler"
    BEGIN
        MENUITEM "&Çizgi çizme", IDM_CIZGI
        MENUITEM "&Şekil çizme", IDM_SEKIL
        MENUITEM "&Yazı yazma", IDM_YAZI
        MENUITEM "&Çıkış", IDM_CIKIS
    END

    POPUP "&Seçenekler"
    BEGIN
        MENUITEM "&Renk seç", IDM_RENK_SEC
        MENUITEM "&Piksel seçenekleri", IDM_PIKSEL_DIA
    END
END

resource.h dosyası oluşturma

resource.h

Bu dosya içinde, tüm kontrol ve menü seçenek tanımlayıcı değerlerinin bildirimi yapılır:


#include <windows.h>

#define IDD_VERIBOX 301
#define IDR_MENU 401
#define IDC_STATIC01 101
#define IDC_STATIC02 102

#define IDC_CHECK 201
#define IDC_TEXT 202
#define IDC_COMBO 203

#define IDM_CIZGI 11
#define IDM_SEKIL 12
#define IDM_YAZI 13
#define IDM_CIKIS 19
#define IDM_RENK_SEC 21
#define IDM_PIKSEL_DIA 22

Ana program dosyası oluşturma (main.c)

main.c

Aşağıdaki satırlar programın başına global değerler olarak eklenir:


#include <windowsx.h>   /* ComboBox_... makroları için */
#include <stdio.h>      /* sprintf() fonksiyonu için */
#include <stdlib.h>     /* srand() ve rand() fonksiyonları için */
#include <time.h>       /* time() fonksiyonu için */

/*Diyalog kutu fonksiyon bildirimi*/ 
BOOL CALLBACK WndProcDlg(HWND, UINT, WPARAM, LPARAM); 
COLORREF RenkSec(HWND); /* RenkSec() fonksiyonu bildirimi */

HWND hwndDialog = NULL; /* Diyalog kutusu pencere Handle değeri */
HWND hwndStatic01, hwndStatic02; /* STATIC kontrolleri pencere Handle değerleri */
HDC hdc;                /* DC Handle değeri */
HPEN hPen;              /* Pen Handle değeri */  
HBRUSH hBrush;          /* Brush Handle değeri */
HFONT hFont;            /* Font Handle değeri */
COLORREF cref = RGB(128, 128, 255); /* İşlemler için renk değeri */

WinMain() fonksiyonuna eklenen turuncu renkle gösterilen satırlar ile ana program mesaj döngüsünde, diyalog kutusu açık değilse (IsWindow() fonksiyonu ile kontrol edilir) veya mesaj diyalog kutusu ile ilgili değilse (IsDialogMessage() fonksiyonu ile kontrol edilir), mesaj ana pencere veya mevcutsa diğer pencerelerin mesaj işlem fonksiyonlarına gönderilir:


 while (GetMessage (&messages, NULL, 0, 0) > 0) {
    if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &messages)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
  }

WindowProcedure() program mesaj işlem fonksiyonunda 3 lokal değişken bildirimi yapılır:


RECT rcClient; /* GetClientRect() fonksiyonu için */ 
int id1;       /* Piksel işlem döngüsü için */ 
POINT pt[4];   /* Polygon() fonksiyonu için */     

WM_CREATE mesajı ile ana program penceresi ile birlikte 2 statik konrol ve modeless diyalog kutusu oluşturulur.:


case WM_CREATE:
   hwndStatic01 = CreateWindowEx(0, "STATIC", "Statik kontrol",
                            WS_CHILD | WS_VISIBLE | SS_LEFT, 10, 290, 350, 20,
                            hwnd, (HMENU) IDC_STATIC01, NULL, NULL);
   hwndStatic02 = CreateWindowEx(0, "STATIC", "Statik kontrol",
                            WS_CHILD | WS_VISIBLE | SS_LEFT, 430, 290, 90, 20,
                            hwnd, (HMENU) IDC_STATIC02, NULL, NULL);
   hwndDialog = CreateDialog (ghInst, MAKEINTRESOURCE(IDD_VERIBOX), 
                         hwnd, (DLGPROC)WndProcDlg);
   break;

WM_COMMAND altındaki IDM_CIZGI menü komutu ile GetDC() fonksiyonu kullanılarak ana program penceresi DC değeri elde edilir. CreatePen() fonksiyonu ile 2 farklı Pen grafik nesnesi oluşturulur ve SelectObject() fonksiyonu ile elde edilen DC'ye aktarılır. 5 adet çizgi çizildikten sonra, DeleteObject() fonksiyonu ile oluşturulan Pen grafik nesnesi silinir ve ReleaseDC() fonksiyonu ile elde edilen DC serbest bırakılır:


case WM_COMMAND:
   switch(LOWORD(wParam)) {
      case IDM_CIZGI:
         hdc = GetDC(hwnd); /* DC değeri elde etme */ 

         /* Pen grafik nesnesi oluşturma */ 
         hPen = CreatePen(PS_SOLID, 1, cref); 
         SelectObject(hdc, hPen); /* Pen grafik nesnesini DC'ye aktarma */ 
         MoveToEx(hdc, 20, 20, NULL); /* DC üzerinde koordinat değiştirme */ 
         LineTo(hdc, 500, 20); /* DC üzerinde çizgi çizme */ 
         MoveToEx(hdc, 20, 40, NULL);
         LineTo(hdc, 220, 120);
         MoveToEx(hdc, 240, 40, NULL);
         LineTo(hdc, 440, 120);

         /* Pen grafik nesnesi oluşturma */ 
         hPen = CreatePen(PS_DOT, 1, RGB(255, 0, 0));
         SelectObject(hdc, hPen);
         MoveToEx(hdc, 20, 280, NULL);
         LineTo(hdc, 450, 50);
         MoveToEx(hdc, 400, 40, NULL);
         LineTo(hdc, 100, 100);
         SetWindowText(hwndStatic01, "5 adet çizgi çizildi.");

         DeleteObject(hPen); /* Pen grafik nesnesini silme */ 
         ReleaseDC(hwnd, hdc); /* DC'yi serbest bırakma */ 

         break;

WM_COMMAND altındaki IDM_SEKIL menü komutu ile GetDC() fonksiyonu kullanılarak ana program penceresi DC değeri elde edilir. CreatePen() fonksiyonu ile oluşturulan Pen grafik nesnesi ve CreateSolidBrush() fonksiyonu ile oluşturulan Brush grafik nesnesi SelectObject() fonksiyonu ile elde edilen DC'ye aktarılır. 6 adet farklı şekil çizildikten sonra, DeleteObject() fonksiyonu ile oluşturulan Pen ve Brush grafik nesneleri silinir ve ReleaseDC() fonksiyonu ile elde edilen DC serbest bırakılır:


case IDM_SEKIL:
   hdc = GetDC(hwnd); /* DC değeri elde etme */ 
   /* Pen grafik nesnesi oluşturma */ 
   hPen = CreatePen(PS_SOLID, 1, RGB(255, 200, 100)); 
   SelectObject(hdc, hPen); /* Pen grafik nesnesini DC'ye aktarma */ 
   hBrush = CreateSolidBrush(cref); /* Brush grafik nesnesini oluşturma */ 
   SelectObject(hdc, hBrush); /* Brush grafik nesnesini DC'ye aktarma */ 

   Rectangle(hdc, 10, 10, 110, 60); /* Dikdörtgen çizme */ 
   /* Kenarları yuvarlak dikdörtgen çizme */ 
   RoundRect (hdc, 120, 10, 220, 60, 10, 10); 
   Ellipse(hdc, 230, 10, 330, 60); /* Elips çizme */ 
   Chord(hdc, 340, 10, 440, 60, 340, 20, 400, 50); /* Daire kesen çizgi çizme */ 
   /* Daire (belirli bölümü hariç) çizme */ 
   Pie(hdc, 10, 80, 160, 230, 20, 120, 110, 130);

   pt[0].x = 180;
   pt[0].y = 80;
   pt[1].x = 270;
   pt[1].y = 120;
   pt[2].x = 240;
   pt[2].y = 180;
   pt[3].x = 200;
   pt[3].y = 150;
   Polygon(hdc, pt, 4); /* Poligon (çok kenarlı şekil) çizme */ 

   SetWindowText(hwndStatic01, "6 adet şekil çizildi.");
   DeleteObject(hPen);   /* Pen grafik nesnesini silme */ 
   DeleteObject(hBrush); /* Brush grafik nesnesini silme */ 
   ReleaseDC(hwnd, hdc); /* DC'yi serbest bırakma */ 

   break;

WM_COMMAND altındaki IDM_YAZI menü komutu ile GetDC() fonksiyonu kullanılarak ana program penceresi DC değeri elde edilir. Ekrana yazılan yazılar arka plan rengini değiştirmesini engellemek için SetBkMode() fonksiyonu ile arka plan rengi TRANSPARENT olarak ayarlanır. İkinci font değeri için, SetBkMode() fonksiyonu ile arka plan rengi OPAQUE olarak ayarlanır ve SetBkColor() fonksiyonu ile arka plan renk seçimi yapılır. CreateFont() fonksiyonu ile oluşturulan farklı özelliklere sahip Font grafik nesnesi SelectObject() fonksiyonu ile elde edilen DC'ye aktarılır ve ekrana 4 cümle yazılır. DeleteObject() fonksiyonu ile oluşturulan Font grafik nesnesi silinir ve ReleaseDC() fonksiyonu ile elde edilen DC serbest bırakılır:


case IDM_YAZI:
   hdc = GetDC(hwnd); /* DC değeri elde etme */ 
   SetBkMode(hdc, TRANSPARENT); /* Arka plan rengi devre dışı bırakılır */ 
   strcpy(cdizi, "Font değerleri ayarlanmış cümle yapısı!");

   /* Font grafik nesnesi oluşturma */ 
   hFont = CreateFont(16, 0, 0, 0, FW_MEDIUM, 0, 0, 0, TURKISH_CHARSET, 
                      0, 0, 0, 0, TEXT("Tahoma"));
   SelectObject(hdc, hFont);
   TextOut(hdc, 20, 20,  cdizi,  strlen(cdizi)); /* Ekrana yazı yazma */ 

   SetBkMode(hdc, OPAQUE); /* Arka plan rengi devreye girer */ 
   SetBkColor(hdc, RGB(128, 128, 240)); /* Arka plan rengi ayarlanır */ 
   hFont = CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, TURKISH_CHARSET, 
                      0, 0, 0, 0, TEXT("Arial"));
   SelectObject(hdc, hFont);
   TextOut(hdc, 20, 50,  cdizi, strlen(cdizi));

   SetBkMode(hdc, TRANSPARENT);
   SetTextColor(hdc, RGB(255, 0, 0));
   hFont = CreateFont(20, 0, 0, 0, FW_MEDIUM, 0, 0, 0, TURKISH_CHARSET, 
                      0, 0, 0, 0, TEXT("Times New Roman"));
   SelectObject(hdc, hFont);
   TextOut(hdc, 20, 80,  cdizi,  strlen(cdizi));

   SetTextColor(hdc, cref);
   hFont = CreateFont(22, 0, 0, 0, FW_MEDIUM, 0, 0, 0, TURKISH_CHARSET, 
                      0, 0, 0, 0, TEXT("Verdana"));
   SelectObject(hdc, hFont);
   TextOut(hdc, 20, 110,  cdizi,  strlen(cdizi));

   SetWindowText(hwndStatic01, "Ekrana 4 cümle yazıldı.");

   DeleteObject(hFont);  /* Font grafik nesnesini silme */ 
   ReleaseDC(hwnd, hdc); /* DC'yi serbest bırakma */ 

   break;

WM_COMMAND altındaki IDM_RENK_SEC menü komutu ile RenkSec() fonksiyonu çağrılır. Kullanıcı tarafından seçilen renk değeri cref değişkenine atanır. IDM_PIKSEL_DIA menü komutu ile ShowWindow() fonksiyonu çağrılarak hwndDialog diyalog kutusu ekranda gösterilir:


case IDM_RENK_SEC:
   cref = RenkSec(hwnd); /* Renk seçme diyalog kutusunun açılması */ 
   SetWindowText(hwndStatic01, "Renk seçildi."); 
   break;

case IDM_PIKSEL_DIA:
   ShowWindow(hwndDialog, SW_SHOW); /* Diyalog kutusunun ekranda gösterilmesi */ 
   break;

WM_KEYDOWN mesajı ile eğer kullanıcı BOŞLUK tuşuna basarsa, diyalog kutusu COMBOBOX kontrolünde belirtilen miktar kadar pikseli, yine diyalog kutusundaki CHECKBOX değerine bağlı olarak rastgele veya seçili renklerle boyar:


case WM_KEYDOWN:
   if (wParam==32) {
       /* GetDlgItemText(hwndDialog, IDC_COMBO, cdizi, 6); */
       /* Diyalog kutusu COMBOBOX seçili değerini alır */  
       ComboBox_GetText(GetDlgItem(hwndDialog, IDC_COMBO), cdizi, 6);

       hdc = GetDC(hwnd);
       GetClientRect(hwnd, &rcClient); /* Client pencere değerlerini alır */  
       /* rand() fonksiyonu için rastgele sayı üretme sistemini tetikler */  
       srand(time(NULL)); 
       /* cdizi değeri kadar ekranda piksel boyar */  
       for (id1=0;id1<atoi(cdizi); id1++) {
            /* Eğer diyalog kutusu CHECKBOX değeri seçili ise */  
            if (IsDlgButtonChecked (hwndDialog, IDC_CHECK)==BST_CHECKED) 
                /* Ekranda piksel boyar */  
                SetPixel(hdc, rand()%rcClient.right, rand()%rcClient.bottom, 
                         RGB(rand()%255, rand()%255, rand()%255));
            else SetPixel(hdc, rand()%rcClient.right, rand()%rcClient.bottom, cref);
       }
       ReleaseDC(hwnd, hdc);
   }
   break;

WM_MOUSEMOVE mesajı ile kullanıcı fareyi her oynattığında elde edilen fare koordinat değerleri ekrana yazılır. Modeless diyalog kutusu program ana penceresi ile birlikte oluşturulur ve WM_DESTROY mesajı ile program ana penceresi ile birlikte yok edilir:


case WM_MOUSEMOVE:
   sprintf (cdizi, "x:%d y:%d",
                    (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
   SetWindowText(hwndStatic02, cdizi);
   break;

case WM_DESTROY:
   DestroyWindow(hwndDialog);
   PostQuitMessage (0);
   break;

Aşağıda gösterilen modeless diyalog kutusu mesaj işlem fonksiyonunda, diyalog kutusu oluşturulduğunda, WM_INITDIALOG mesajı ile, SendMessage() fonksiyonunda CB_ADDSTRING değeri kullanılarak COMBOBOX kontrolüne 5 değer eklenir. Bu fonksiyona alternatif olarak kullanılabilecek ComboBox_AddString() fonksiyonu da kodlar içinde gösterilmiştir. SendMessage() fonksiyonunda CB_SETCURSEL değeri kullanılarak COMBOBOX kontrolünün 3 ncü değeri aktif olarak seçilir. WM_COMMAND mesajı altında, IDC_CHECK seçneğinde CheckDlgButton() fonksiyonu ile CHECKBOX kontrolünün durumu değiştirilir. IDOK seçeneğinde ShowWindow() fonksiyonu ile diyalog kutusu gizlenir:


BOOL CALLBACK WndProcDlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
    case WM_INITDIALOG:
      SetWindowText(hwndStatic01, "Diyalog penceresi oluşturuldu.");
      /* COMBOBOX kontrolüne değer ekleme */ 
      SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "1000");
      /* ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO), "1000"); */
      SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "2500");
      SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "5000");
      SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "10000");
      SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "20000");

      /* COMBOBOX kontrolünün aktif değerini belirleme */ 
      SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_SETCURSEL, 2, 0);
      /* ComboBox_SetCurSel(GetDlgItem(hwndDlg, IDC_COMBO), 2); */
      return TRUE;
      break;
    case WM_COMMAND:
      switch (LOWORD(wParam)) {
         case IDC_CHECK:
            /* CHECKBOX kontrolünün durumunu değiştirme */ 
            CheckDlgButton(hwndDlg, IDC_CHECK,
                           !IsDlgButtonChecked (hwndDlg, IDC_CHECK));
            return TRUE;

         case IDOK:
            /* Diyalog kutusunu gizleme */  
            ShowWindow(hwndDialog, SW_HIDE);
            return TRUE;
      }
      break;
  }
  return FALSE;
}

Program kaynak dosyaları

Programın çalışan en son halinde yer alan dosyalar aşağıdadır:

resource.rc


#include "resource.h"

IDD_VERIBOX DIALOGEX 70, 10, 200, 80
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
FONT 8, "MS Sans Serif"
BEGIN
    CHECKBOX "Rastgele renk seçimi", IDC_CHECK, 10, 10, 120, 10
    LTEXT "Piksel tekrar sayısı", IDC_TEXT, 10, 30, 100, 100
    COMBOBOX IDC_COMBO, 70, 28, 50, 74, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
    DEFPUSHBUTTON "&OK", IDOK, 140, 20, 50, 14
END

IDR_MENU MENU
BEGIN
    POPUP "&İşlemler"
    BEGIN
        MENUITEM "&Çizgi çizme", IDM_CIZGI
        MENUITEM "&Şekil çizme", IDM_SEKIL
        MENUITEM "&Yazı yazma", IDM_YAZI
        MENUITEM "&Çıkış", IDM_CIKIS
    END

    POPUP "&Seçenekler"
    BEGIN
        MENUITEM "&Renk seç", IDM_RENK_SEC
        MENUITEM "&Piksel seçenekleri", IDM_PIKSEL_DIA
    END
END

resource.h


#include <windows.h>

#define IDD_VERIBOX 301
#define IDR_MENU 401
#define IDC_STATIC01 101
#define IDC_STATIC02 102

#define IDC_CHECK 201
#define IDC_TEXT 202
#define IDC_COMBO 203

#define IDM_CIZGI 11
#define IDM_SEKIL 12
#define IDM_YAZI 13
#define IDM_CIKIS 19
#define IDM_RENK_SEC 21
#define IDM_PIKSEL_DIA 22

main.c


#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK WndProcDlg(HWND, UINT, WPARAM, LPARAM);
COLORREF RenkSec(HWND);

char szClassName[ ] = "WinAPIWindowsApp";
HINSTANCE ghInst;
char cdizi[200];

HWND hwndDialog = NULL;
HWND hwndStatic01, hwndStatic02;
HDC hdc;
HPEN hPen;
HBRUSH hBrush;
HFONT hFont;
COLORREF cref = RGB(128, 128, 255);

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
  HWND hwndMain;
  MSG messages;
  WNDCLASSEX wincl;

  ghInst = hThisInstance;

  wincl.hInstance = hThisInstance;
  wincl.lpszClassName = szClassName;
  wincl.lpfnWndProc = WindowProcedure;
  wincl.style = CS_DBLCLKS;
  wincl.cbSize = sizeof (WNDCLASSEX);

  wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  wincl.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
  wincl.cbClsExtra = 0;
  wincl.cbWndExtra = 0;
  wincl.hbrBackground = GetSysColorBrush(COLOR_3DFACE);

  if (!RegisterClassEx (&wincl)) return 0;

  hwndMain = CreateWindowEx (0, szClassName, "WinAPI Temel Program",
                  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                  544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);

  if (!hwndMain) return 0;

  ShowWindow (hwndMain, nCmdShow);
  UpdateWindow(hwndMain);

  while (GetMessage (&messages, NULL, 0, 0) > 0) {
    if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &messages)) {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
  }

  return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
  RECT rcClient;
  int id1;
  POINT pt[4];

  switch (message)
  {
    case WM_CREATE:
       hwndStatic01 = CreateWindowEx(0, "STATIC", "Statik kontrol",
                                WS_CHILD | WS_VISIBLE | SS_LEFT, 10, 290, 350, 20,
                                hwnd, (HMENU) IDC_STATIC01, NULL, NULL);
       hwndStatic02 = CreateWindowEx(0, "STATIC", "Statik kontrol",
                                WS_CHILD | WS_VISIBLE | SS_LEFT, 430, 290, 90, 20,
                                hwnd, (HMENU) IDC_STATIC02, NULL, NULL);
       hwndDialog = CreateDialog (ghInst, MAKEINTRESOURCE(IDD_VERIBOX), 
		                          hwnd, (DLGPROC)WndProcDlg);
       break;

    case WM_COMMAND:

       switch(LOWORD(wParam)) {

          case IDM_CIZGI:
             hdc = GetDC(hwnd);

             hPen = CreatePen(PS_SOLID, 1, cref);
             SelectObject(hdc, hPen);
             MoveToEx(hdc, 20, 20, NULL);
             LineTo(hdc, 500, 20);
             MoveToEx(hdc, 20, 40, NULL);
             LineTo(hdc, 220, 120);
             MoveToEx(hdc, 240, 40, NULL);
             LineTo(hdc, 440, 120);

             hPen = CreatePen(PS_DOT, 1, RGB(255, 0, 0));
             SelectObject(hdc, hPen);
             MoveToEx(hdc, 20, 280, NULL);
             LineTo(hdc, 450, 50);
             MoveToEx(hdc, 400, 40, NULL);
             LineTo(hdc, 100, 100);
             SetWindowText(hwndStatic01, "5 adet çizgi çizildi.");

             DeleteObject(hPen);
             ReleaseDC(hwnd, hdc);

             break;

          case IDM_SEKIL:
             hdc = GetDC(hwnd);
             hPen = CreatePen(PS_SOLID, 1, RGB(255, 200, 100));
             SelectObject(hdc, hPen);
             hBrush = CreateSolidBrush(cref);
             SelectObject(hdc, hBrush);

             Rectangle(hdc, 10, 10, 110, 60);
             RoundRect (hdc, 120, 10, 220, 60, 10, 10);
             Ellipse(hdc, 230, 10, 330, 60);
             Chord(hdc, 340, 10, 440, 60, 340, 20, 400, 50);
             Pie(hdc, 10, 80, 160, 230, 20, 120, 110, 130);

             pt[0].x = 180;
             pt[0].y = 80;
             pt[1].x = 270;
             pt[1].y = 120;
             pt[2].x = 240;
             pt[2].y = 180;
             pt[3].x = 200;
             pt[3].y = 150;
             Polygon(hdc, pt, 4);

             SetWindowText(hwndStatic01, "6 adet şekil çizildi.");
             DeleteObject(hPen);
             DeleteObject(hBrush);
             ReleaseDC(hwnd, hdc);

             break;

          case IDM_YAZI:
             hdc = GetDC(hwnd);
             SetBkMode(hdc, TRANSPARENT);
             strcpy(cdizi, "Font değerleri ayarlanmış cümle yapısı!");

             hFont = CreateFont(16, 0, 0, 0, FW_MEDIUM, 0, 0, 0, TURKISH_CHARSET, 
                                0, 0, 0, 0, TEXT("Tahoma"));
             SelectObject(hdc, hFont);
             TextOut(hdc, 20, 20,  cdizi,  strlen(cdizi));

             SetBkMode(hdc, OPAQUE);
             SetBkColor(hdc, RGB(128, 128, 240));
             hFont = CreateFont(18, 0, 0, 0, FW_BOLD, 0, 0, 0, TURKISH_CHARSET, 
                                0, 0, 0, 0, TEXT("Arial"));
             SelectObject(hdc, hFont);
             TextOut(hdc, 20, 50,  cdizi,  strlen(cdizi));

             SetBkMode(hdc, TRANSPARENT);
             SetTextColor(hdc, RGB(255, 0, 0));
             hFont = CreateFont(20, 0, 0, 0, FW_MEDIUM, 0, 0, 0, TURKISH_CHARSET, 
                                0, 0, 0, 0, TEXT("Times New Roman"));
             SelectObject(hdc, hFont);
             TextOut(hdc, 20, 80,  cdizi,  strlen(cdizi));

             SetTextColor(hdc, cref);
             hFont = CreateFont(22, 0, 0, 0, FW_MEDIUM, 0, 0, 0, TURKISH_CHARSET, 
                                0, 0, 0, 0, TEXT("Verdana"));
             SelectObject(hdc, hFont);
             TextOut(hdc, 20, 110,  cdizi,  strlen(cdizi));

             SetWindowText(hwndStatic01, "Ekrana 4 cümle yazıldı.");

             DeleteObject(hFont);
             ReleaseDC(hwnd, hdc);

             break;

          case IDM_RENK_SEC:
             cref = RenkSec(hwnd);
             SetWindowText(hwndStatic01, "Renk seçildi.");
             break;

          case IDM_PIKSEL_DIA:
             ShowWindow(hwndDialog, SW_SHOW);
             break;

          case IDM_CIKIS:
             SendMessage(hwnd, WM_CLOSE, 0, 0);
             break;
       }

       break;

    case WM_KEYDOWN:

       if (wParam==32) {
           /* GetDlgItemText(hwndDialog, IDC_COMBO, cdizi, 6); */
           ComboBox_GetText(GetDlgItem(hwndDialog, IDC_COMBO), cdizi, 6);

           hdc = GetDC(hwnd);
           GetClientRect(hwnd, &rcClient);
           srand(time(NULL));
           for (id1=0;id1<atoi(cdizi); id1++) {
                if (IsDlgButtonChecked (hwndDialog, IDC_CHECK)==BST_CHECKED) 
                    SetPixel(hdc, rand()%rcClient.right, rand()%rcClient.bottom, 
                             RGB(rand()%255, rand()%255, rand()%255));
                else SetPixel(hdc, rand()%rcClient.right, rand()%rcClient.bottom, cref);
           }
           ReleaseDC(hwnd, hdc);
       }

       break;

    case WM_MOUSEMOVE:

       sprintf (cdizi, "x:%d y:%d",
                       (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam));
       SetWindowText(hwndStatic02, cdizi);
       break;

    case WM_DESTROY:
       DestroyWindow(hwndDialog);
       PostQuitMessage (0);
       break;

    default:
       return DefWindowProc (hwnd, message, wParam, lParam);
  }

  return 0;
}

COLORREF RenkSec(HWND hwnd) {
  CHOOSECOLOR cc;
  static COLORREF acrCustClr[16];
  HBRUSH hbrush;
  static DWORD rgbCurrent=0;

  ZeroMemory(&cc, sizeof(cc));
  cc.lStructSize = sizeof(cc);
  cc.hwndOwner = hwnd;
  cc.lpCustColors = (LPDWORD) acrCustClr;
  cc.rgbResult = rgbCurrent;
  cc.Flags = CC_FULLOPEN | CC_RGBINIT;

  if (ChooseColor(&cc)==TRUE) {
      hbrush = CreateSolidBrush(cc.rgbResult);
      rgbCurrent = cc.rgbResult;
  }

  return rgbCurrent;
}

BOOL CALLBACK WndProcDlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
     case WM_INITDIALOG:
        SetWindowText(hwndStatic01, "Diyalog penceresi oluşturuldu.");

        SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "1000");
        /* ComboBox_AddString(GetDlgItem(hwndDlg, IDC_COMBO), "1000"); */
        SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "2500");
        SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "5000");
        SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "10000");
        SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_ADDSTRING, 0, (LPARAM) "20000");

        SendMessage(GetDlgItem(hwndDlg, IDC_COMBO), CB_SETCURSEL, 2, 0);
        /* ComboBox_SetCurSel(GetDlgItem(hwndDlg, IDC_COMBO), 2); */
        return TRUE;
        break;
     case WM_COMMAND:
        switch (LOWORD(wParam)) {
           case IDC_CHECK:
              CheckDlgButton(hwndDlg, IDC_CHECK,
                             !IsDlgButtonChecked (hwndDlg, IDC_CHECK));
              return TRUE;

           case IDOK:
              ShowWindow(hwndDialog, SW_HIDE);
              return TRUE;
        }
        break;
  }
  return FALSE;
}

Program ekran görüntüleri

Program çalıştığında karşınıza gelecek ekran görüntüleri aşağıdadır: