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

Ana page > Programlama > Windows API Programlama > WinAPI örnek kodlar > winapi_ornek00003

Windows API örnek kodlar

Bir kontrolün çerçeve rengini değiştirme

Bir Windows API programında kullanılan herhangi bir kontrolün dış çerçeve rengini değiştirmek için, kontrol için subclassing işlemi uygulayarak bir fonksiyon tanımladıktan sonra, bu fonksiyon içinde WM_NCPAINT ve WM_NCCALCSIZE mesajlarına işlem yapabiliriz.

Subclassing işlemi için commctrl.h başlık dosyasına ihtiyaç duyulmaktadır.

WM_NCPAINT mesajı bir kontrol penceresi dış çerçevesi çizileceği zaman pencereye gönderilir.

WM_NCCALCSIZE mesajı bir kontrol penceresinin istemci (client) alanının boyutu ve pozisyonu yeniden hesaplanması gerektiğinde gönderilir. Program bu mesaja işlem yaparak, bir pencerenin boyutu veya konumu değiştiğinde, pencerenin istemci (client) alanının içeriğini kontrol edebilir.

Ancak, WM_NCCALCSIZE mesajı Subclass fonksiyonu içinde çağrılmadığından, SetWindowPos() fonksiyonu SWP_FRAMECHANGED seçeneği ile kullanılmalıdır.

Programda birer adet Static, Edit, ListView ve ListBox kontrolu ile işlem yapılmaktadır. Programın ana dosya içeriği aşağıdaki şekilde olacaktır.

main.c


#define _WIN32_WINNT 0x0601  // DefSubclassProc için gerekli
#define _WIN32_IE 0x0501     // DefSubclassProc için gerekli

#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif

#include <tchar.h>
#include <windows.h>
#include <commctrl.h> // DefSubclassProc için gerekli
#include <stdio.h>

HWND hwndStatic, hwndEdit, hwndListView, hwndListBox, hwndRichEdit;

//  Declare Windows procedure
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
// Subclassing fonksiyon bildirimi
LRESULT CALLBACK ControlBorderProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
void CreateListView(HWND hwndParent);
void CreateListBox(HWND hwndParent);

//  Make the class name into a global variable
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               // This is the handle for our window
    MSG messages;            // Here messages to the application are saved
    WNDCLASSEX wincl;        // Data structure for the windowclass

    // The Window structure
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      // This function is called by windows
    wincl.style = CS_DBLCLKS;                 // Catch double-clicks
    wincl.cbSize = sizeof (WNDCLASSEX);

    // Use default icon and mouse-pointer
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 // No menu
    wincl.cbClsExtra = 0;                      // No extra bytes after the window class
    wincl.cbWndExtra = 0;                      // structure or the window instance
    // Use Windows's default colour as the background of the window
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    // Register the window class, and if it fails quit the program
    if (!RegisterClassEx (&wincl))
        return 0;

    // The class is registered, let's create the program
    hwnd = CreateWindowEx (
           0,                   // Extended possibilites for variation
           szClassName,         // Classname
           _T("Custom control border"), // Title Text
           WS_OVERLAPPEDWINDOW, // default window
           CW_USEDEFAULT,       // Windows decides the position
           CW_USEDEFAULT,       // where the window ends up on the screen
           525,                 // The programs width
           380,                 // and height in pixels
           HWND_DESKTOP,        // The window is a child-window to desktop
           NULL,                // No menu
           hThisInstance,       // Program Instance handler
           NULL                 // No Window Creation data
           );

    // Make the window visible on the screen
    ShowWindow (hwnd, nCmdShow);

    // Run the message loop. It will run until GetMessage() returns 0
    while (GetMessage (&messages, NULL, 0, 0)) {
        // Translate virtual-key messages into character messages
        TranslateMessage(&messages);
        // Send message to WindowProcedure
        DispatchMessage(&messages);
    }

    // The program return-value is 0 - The value that PostQuitMessage() gave
    return messages.wParam;
}


//  This function is called by the Windows function DispatchMessage()
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                    // handle the messages
    {
        case WM_CREATE:
        {
             hwndStatic = CreateWindowEx(0, "STATIC", "Static kontrol",
                                WS_CHILD | WS_VISIBLE, 20, 20, 300, 20,
                                hwnd, 0, NULL, NULL);
             // Subclassing işlemi için fonksiyon tanımlama
             SetWindowSubclass(hwndStatic, ControlBorderProc, 0, 0);
             // Subclass fonksiyonu içinde WM_NCCALCSIZE mesajı çağrılmadığından, SetWindowPos() fonksiyonu SWP_FRAMECHANGED seçeneği ile çağrılmalıdır.
             SetWindowPos(hwndStatic, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); // Static kontrol için gerekli

             hwndEdit = CreateWindowEx(0, "EDIT", "Edit kontrol",
                              WS_CHILD | WS_VISIBLE, 20, 50, 300, 20,
                              hwnd, 0, NULL, NULL);
             // Subclassing işlemi için fonksiyon tanımlama
             SetWindowSubclass(hwndEdit, ControlBorderProc, 0, 0);
             SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); // Edit kontrolu için gerekli

             CreateListView(hwnd);
             // Subclassing işlemi için fonksiyon tanımlama
             SetWindowSubclass(hwndListView, ControlBorderProc, 0, 0);

             CreateListBox(hwnd);
             // Subclassing işlemi için fonksiyon tanımlama
             SetWindowSubclass(hwndListBox, ControlBorderProc, 0, 0);
             SetWindowPos(hwndListBox, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); // ListBox kontrolu için gerekli
        }
        break;
        case WM_DESTROY:
             PostQuitMessage (0);       // send a WM_QUIT to the message queue
             break;
        default:                        // for messages that we don't deal with
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

// Subclassing fonksiyonu
LRESULT CALLBACK ControlBorderProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
  switch (message) {
     case WM_NCPAINT:
     {
          RECT rect;
          HDC hdc;

          hdc = GetWindowDC(hwnd);
          GetWindowRect(hwnd, &rect);
          OffsetRect(&rect, -rect.left, -rect.top);
          FrameRect(hdc, &rect, CreateSolidBrush(RGB(255, 0, 0)));
          ReleaseDC(hwnd, hdc);
          return 0;

          break;
     }
     // Static, Edit ve ListBox kontrolleri için gerekli
     case WM_NCCALCSIZE:
          if(lParam) {
             NCCALCSIZE_PARAMS* sz = (NCCALCSIZE_PARAMS*)lParam;
             InflateRect(&sz->rgrc[0], -1, -1);
             return 0;
          }
          break;

     break;
  }

  return DefSubclassProc(hwnd, message, wParam, lParam);
}

void CreateListView(HWND hwndParent)
{
  LVCOLUMN lvc;
  LVITEM lvI;
  int idCol=3, idItem=8;
  char cdizi[15];
  int id1, id2;

  hwndListView = CreateWindowEx(WS_EX_CLIENTEDGE , WC_LISTVIEW, "",
                                  WS_CHILD | LVS_REPORT | WS_VISIBLE,
                                  20, 80, 300, 245, hwndParent,
                                  0, NULL, NULL);

  // LVCOLUMN structure için ilk değer atama işlemlerini yapar.
  lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  lvc.cx = 98;           // Sütun genişliği değeri
  lvc.fmt = LVCFMT_LEFT; // Sütunları sol tarafa ayarlar

  // Sütun ekleme işlemleri
  for (id1=0; id1<idCol; id1++) {
       lvc.iSubItem = id1;
       sprintf(cdizi, "%s%d", "Column", id1+1);
       lvc.pszText = cdizi;
       // Sütun ekleme işlemi
       ListView_InsertColumn(hwndListView, id1, &lvc);
  }


  // LVITEM structure için ilk değer atama işlemlerini yapar.
  lvI.mask      = LVIF_TEXT | LVIF_STATE;
  lvI.stateMask = 0;
  lvI.iSubItem  = 0;
  lvI.state     = 0;

  // Satır ekleme işlemleri
  for (id1=0; id1<idItem; id1++) {
       lvI.iItem  = id1;
       sprintf(cdizi, "%s%d", "Item", id1+1);
       lvI.pszText   = cdizi;
       // İlk sütun için öğe ekleme işlemleri
       ListView_InsertItem(hwndListView, &lvI);

       // Diğer sütunlar için öğe ekleme işlemleri
       for (id2=1; id2<idCol; id2++) {
            sprintf(cdizi, "%s%d-%d", "SubItem", id1+1, id2+1);
            ListView_SetItemText(hwndListView, id1, id2, cdizi);
       }
  }
}

void CreateListBox(HWND hwndParent)
{
  char cdizi[15];
  int id;

  hwndListBox = CreateWindowEx(0, "LISTBOX", NULL,
                     WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 340, 20, 150, 310,
                     hwndParent, 0, NULL, NULL);

  for (id=0; id<10; id++) {
       sprintf(cdizi, "%s%d", "Item", id+1);
       SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM) cdizi);
  }

  SendMessage(hwndListBox, LB_SETCURSEL, 0, 0);
}

Program derleyip çalıştırdığımızda aşağıdakine benzer bir ekran görüntüsü karşımıza gelecektir:

Programın kaynak kodları

Programın exe dosyası