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

Ana page > Programlama > Windows API Programlama > Richedit

Richedit

► Kontroller

Windows API ile bir Richedit kontrolü oluşturmak için CreateWindowEx() fonksiyonunun ikinci parametresinde MSFTEDIT_CLASS değerini kullanmamız gerekir. Richedit kontrolü için kullanılacak değerler richedit.h başlık dosyasında yer aldığından bu dosya programımıza dahil edilmelidir. Ayrıca, Msftedit.dll kütüphane dosyası programın başında yüklenmelidir.

Richedit kontrolü oluşturma

1. Öncelikle Burada gösterildiği gibi bir Windows API projesi oluşturalım. Projeyle birlikte otomatik olarak oluşturulan main.c dosyasının başlangıç kısmını aşağıdaki şekilde düzenleyelim:


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

#include <tchar.h>
#include <windows.h>
#include <richedit.h>

/* Eğer derleyici hata verirse, aşağıdaki tanımlama yapılmalıdır. */
#if !defined MSFTEDIT_CLASS
#define MSFTEDIT_CLASS "RICHEDIT50W"
#endif

#define IDC_RICHEDIT 101

HWND hwndRichedit;

BOOL FillRichEditFromFile(HWND hwnd, LPCTSTR pszFile);
DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb);

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

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

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)

Aşağıdaki satır ile richedit.h başlık dosyası ile Treeview kontrolü oluşturma ile ilgili fonksiyonların ve değerlerin kullanımı sağlanır.


#include <richedit.h>

Aşağıdaki satırlar ile Richedit kontrolünü dosyadan doldurmak için kullanılacak FillRichEditFromFile() ve EditStreamCallback() fonksiyonlarının tanımlaması programa eklenir.


BOOL FillRichEditFromFile(HWND hwnd, LPCTSTR pszFile);
DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb);

Aşağıdaki satır ile bir adet Richedit kontrolü oluşturulur.


HWND hwndRichedit;

2. Windows Procedure düzenleme

WindowProcedure içinde oluşturacağımız WM_CREATE seçeneğine aşağıdaki satırları ekleyelim:


LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
        {
             /* Gerekli kütüphane dosyasını yükleme */
             LoadLibrary(TEXT("Msftedit.dll"));

             /* Richedit kontrolü oluşturma */
             hwndRichedit = CreateWindowEx(0, MSFTEDIT_CLASS, TEXT("Type here"),
                    ES_MULTILINE | WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_AUTOVSCROLL,
                    10, 10, 400, 320,
                    hwnd, (HMENU)IDC_RICHEDIT, 0, NULL);

             /* Richedit kontrol içeriğini dosyadan doldurma */
             FillRichEditFromFile(hwndRichedit, "richedit.rtf");
        }
        break;

Önce LoadLibrary() fonksiyonu ile Msftedit.dll dosyası yüklenir. Sonra, Richedit kontrolü oluşturularak, içeriği FillRichEditFromFile() fonksiyonu ile dosyadan yüklenir.

3. FillRichEditFromFile() ve EditStreamCallback() fonksiyonlarını oluşturma

Bu fonksiyonlar Richedit içeriğinin dosyadan yüklenmesi için kullanılacaktır.


/* Richedit kontrolünü dosyadan dolduran fonksiyon */
BOOL FillRichEditFromFile(HWND hwnd, LPCTSTR pszFile)
{
  BOOL fSuccess = FALSE;
  HANDLE hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ,
                            0, OPEN_EXISTING,
                            FILE_FLAG_SEQUENTIAL_SCAN, NULL);

  if (hFile != INVALID_HANDLE_VALUE) {
      EDITSTREAM es = { (DWORD_PTR)hFile, 0, EditStreamCallback };
      if (SendMessage(hwnd, EM_STREAMIN, SF_RTF, (LPARAM)&es) && es.dwError == 0) {
          fSuccess = TRUE;
      }
      CloseHandle(hFile);
  }
  return fSuccess;
}

DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb)
{
  HANDLE hFile = (HANDLE)dwCookie;
  return !ReadFile(hFile, lpBuff, cb, (DWORD *)pcb, NULL);
}

4. Richedit içeriği için .rtf dosyası oluşturma

Aşağıdaki içeriğe sahip bir adet richedit.rtf adlı dosya oluşturarak, programı derlediğinizde .exe dosyanın oluşturulduğu dizine kopyalayın.

Richedit  içeriğidir

Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.
Bu metin Richedit kontrolü içeriğini oluşturur.

5. Kodların son hali (main.c dosyası)

Yukarıdaki kodları eklediğimizde, main.c dosyasının en son hali aşağıdaki şekilde olacaktır.

main.c


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

#include <tchar.h>
#include <windows.h>
#include <richedit.h>

/* Eğer derleyici hata verirse, aşağıdaki tanımlama yapılmalıdır. */
#if !defined MSFTEDIT_CLASS
#define MSFTEDIT_CLASS "RICHEDIT50W"
#endif

#define IDC_RICHEDIT 101

HWND hwndRichedit;

BOOL FillRichEditFromFile(HWND hwnd, LPCTSTR pszFile);
DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb);

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  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("Richedit Örneği"),  /* Title Text */
           WS_OVERLAPPEDWINDOW,    /* default window */
           CW_USEDEFAULT,          /* Windows decides the position */
           CW_USEDEFAULT,          /* where the window ends up on the screen */
           544,                    /* The programs width */
           375,                    /* 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:
        {
             /* Gerekli kütüphane dosyasını yükleme */
             LoadLibrary(TEXT("Msftedit.dll"));

             /* Richedit kontrolü oluşturma */
             hwndRichedit = CreateWindowEx(0, MSFTEDIT_CLASS, TEXT("Type here"),
                    ES_MULTILINE | WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_AUTOVSCROLL,
                    10, 10, 400, 320,
                    hwnd, (HMENU)IDC_RICHEDIT, 0, NULL);

             /* Richedit kontrol içeriğini dosyadan doldurma */
             FillRichEditFromFile(hwndRichedit, "richedit.rtf");
        }
        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;
}

/* Richedit kontrolünü dosyadan dolduran fonksiyon */
BOOL FillRichEditFromFile(HWND hwnd, LPCTSTR pszFile)
{
  BOOL fSuccess = FALSE;
  HANDLE hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ,
                            0, OPEN_EXISTING,
                            FILE_FLAG_SEQUENTIAL_SCAN, NULL);

  if (hFile != INVALID_HANDLE_VALUE) {
      EDITSTREAM es = { (DWORD_PTR)hFile, 0, EditStreamCallback };
      if (SendMessage(hwnd, EM_STREAMIN, SF_RTF, (LPARAM)&es) && es.dwError == 0) {
          fSuccess = TRUE;
      }
      CloseHandle(hFile);
  }
  return fSuccess;
}

DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, PLONG pcb)
{
  HANDLE hFile = (HANDLE)dwCookie;
  return !ReadFile(hFile, lpBuff, cb, (DWORD *)pcb, NULL);
}

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

Programı IDE ortamından değil .exe dosyanın ve .rtf uzantılı dosyanın yer aldığı dizinden çalıştırmalısınız. Aksi takdirde, .rtf uzantılı dosyayı okumaz.

6. Proje dosyaları ve .exe dosya

Programın kaynak kodları

Programın exe dosyası