// SimpleRE.cpp : Simple Rich Edit Application // // Demonstrates setting CJK Unicode text into a RichEdit20W control // and displaying it legibly on Windows 9x. // // Compiles and runs with VC++ 6.0. // // You can use this code however you like. No warranties are // expressed or implied. // // #define WIN32_LEAN_AND_MEAN #include #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 THE_CHARSET GB2312_CHARSET // charset of the font #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 //================================================================ // basic WinMain 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; } //================================================================ // SetRichEditText - add Unicode text to a richedit control struct StreamInData { PCWSTR pszData; LPBYTE pbCur; LONG cbCur; }; DWORD CALLBACK SimpleEditStreamCallback(DWORD dwCookie, LPBYTE pb, LONG cb, LONG *pcb) { StreamInData * psid = (StreamInData *)dwCookie; if (!psid->pbCur) { psid->pbCur = (LPBYTE)psid->pszData; psid->cbCur = wcslen(psid->pszData) * sizeof(WCHAR); } LONG cbWritten; for (cbWritten = 0; (cbWritten < cb) && (cbWritten < psid->cbCur); cbWritten++) { *pb++ = *psid->pbCur++; } psid->cbCur -= cbWritten; *pcb = cbWritten; return 0; } LRESULT SetRichEditText (HWND hwndRE, LPCWSTR psz) { #if 1 // EM_STREAMIN works with Richedit 2.0 StreamInData sid = { psz, NULL, 0 }; EDITSTREAM es = { (DWORD)&sid, 0, SimpleEditStreamCallback }; return SendMessage(hwndRE, EM_STREAMIN, (WPARAM)(UINT)(SF_TEXT|SF_UNICODE), (LPARAM)&es); #else // EM_SETTEXTEX is Richedit 3.0 only SETTEXTEX ste; ste.flags = ST_SELECTION; // replace everything ste.codepage = 1200; // Unicode is codepage 1200 return SendMessage(hwndRE, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)psz); #endif } //================================================================ // AppWndProc - main window procedure // 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 SetRichEditText(hwndRE, WSZ_SAMPLE); // give it focus so the caret appears 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; } // // initialize everything we need for this application // 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, THE_CHARSET, 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; } // // clean up the app // VOID TermInstance(VOID) { if (g_hf) DeleteObject((HGDIOBJ)g_hf); if (g_hRiched) FreeLibrary(g_hRiched); }