// SimpleRE.cpp : Simple Rich Edit Application
//
// Demonstrates setting CJK Unicode text into a RichEdit20W control.
// Tested on Windows 2000 and Windows 98, Second Edition 4.10.2222A
// Riched20.dll version 5.30.11.2410
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <richedit.h>

BOOL InitInstance(HINSTANCE hInst, INT cmdShow);
VOID TermInstance(VOID);

#define SZ_APPNAME  "Simple Richedit Host"    // app name/title
#define SZ_FONT     "SimHei"                  // Facename of font for rich edit control
#define IDC_RE      100                       // id of richedit window
#define WSZ_SAMPLE  L"\x4e2d\x570b"           // sample Unicode text

// Get the x, y, width, height of a RECT
#define RC_XYWH(rc) (rc).left, (rc).top, (rc).right-(rc).left, (rc).bottom-(rc).top

HMODULE     g_hRiched = NULL; // RichEd20.dll module handle
HFONT       g_hf      = NULL; // Font

INT APIENTRY WinMain (HINSTANCE hInst, HINSTANCE, LPSTR, INT nCmdShow)
{
    MSG msg = {0};
    if (InitInstance(hInst, nCmdShow))
    {
      while (GetMessage(&msg, NULL, 0, 0))
      {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
      }
    }
    TermInstance();
    return msg.wParam;
}

LONG APIENTRY AppWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    RECT rc;

    switch (msg)
    {
    case WM_CREATE:
        {
            // calculate rect of the richedit control
            GetClientRect(hwnd, &rc);
            InflateRect(&rc, -1, -1); // 1-pixel border

            // create richedit child window
            HWND hwndRE = CreateWindowEx(0, "RichEdit20W", "",
                WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_SAVESEL|WS_VSCROLL,
                RC_XYWH(rc), hwnd, (HMENU)IDC_RE, g_hRiched, NULL
                );

            // set the font in the richedit control
            SendMessage(hwndRE, WM_SETFONT, (WPARAM)g_hf, FALSE); 

            // initialize the richedit control with some Unicode CJK text
            SETTEXTEX ste;
            ste.flags    = ST_SELECTION;  // replace everything
            ste.codepage = 1200;          // Unicode is codepage 1200
            SendMessage(hwndRE, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)WSZ_SAMPLE);

            SetFocus(hwndRE);
        }
        break;

    case WM_SIZE:
        {
            HWND hwndRE = GetDlgItem(hwnd, IDC_RE);
            if (hwndRE)
            {
                GetClientRect(hwnd, &rc);
                InflateRect(&rc, -1, -1); // 1-pixel border
                SetWindowPos(hwndRE, NULL, RC_XYWH(rc), SWP_NOZORDER|SWP_SHOWWINDOW);
            }
        }
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0L;
}

BOOL InitInstance(HINSTANCE hInst, INT cmdShow)
{
    // load richedit
    g_hRiched = LoadLibrary("riched20.dll");

    // create an interesting font
    g_hf = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SZ_FONT);
    
    WNDCLASS  wc;

    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon          = NULL;
    wc.lpszMenuName   = NULL;
    wc.lpszClassName  = SZ_APPNAME;
    wc.hbrBackground  = (HBRUSH) GetStockObject(GRAY_BRUSH);
    wc.hInstance      = hInst;
    wc.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW;
    wc.lpfnWndProc    = (WNDPROC)AppWndProc;
    wc.cbWndExtra     = 0;
    wc.cbClsExtra     = 0;
    
    if (!RegisterClass(&wc))
        return FALSE;
    
    HWND hwnd = CreateWindowEx (0, SZ_APPNAME, SZ_APPNAME, 
        (WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX),
        CW_USEDEFAULT, CW_USEDEFAULT, 300, 100,
        NULL, NULL, hInst, NULL);
    
    if (!hwnd)
        return FALSE;

    ShowWindow(hwnd, cmdShow);
    
    return TRUE;
}

VOID TermInstance(VOID)
{
    if (g_hf)
        DeleteObject((HGDIOBJ)g_hf);
    if (g_hRiched)
        FreeLibrary(g_hRiched);
}

