Hi All,
I'm going to play with the richedit control to try get it to draw RTF documents with formatting. My plan is to write a program that can display but not edit, then let somebody else add the editting functionality afterwards :) Once I can get the attached program to work, the plan is to change the code in text-writer.c to add the formatting information to the richedit control via standard richedit messages. If anybody is already working on it, or wants to have a go, let me know.
Mike
#include <stdio.h> #include <windows.h> #include <winuser.h> #include <richedit.h>
void fill_richedit( HWND hwnd ) { PARAFORMAT pf; CHARFORMAT cf;
SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "this is a test\n");
// add text on the right memset( &pf, 0, sizeof pf ); pf.cbSize = sizeof pf; pf.dwMask = PFM_ALIGNMENT; pf.wAlignment = PFA_RIGHT; SendMessage( hwnd, EM_SETPARAFORMAT, FALSE, (LPARAM) &pf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "right\n");
// add text in the center memset( &pf, 0, sizeof pf ); pf.cbSize = sizeof pf; pf.dwMask = PFM_ALIGNMENT; pf.wAlignment = PFA_CENTER; SendMessage( hwnd, EM_SETPARAFORMAT, FALSE, (LPARAM) &pf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "centre\n");
// add text on the left memset( &pf, 0, sizeof pf ); pf.cbSize = sizeof pf; pf.dwMask = PFM_ALIGNMENT; pf.wAlignment = PFA_LEFT; SendMessage( hwnd, EM_SETPARAFORMAT, FALSE, (LPARAM) &pf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "left\n");
// add bold text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_BOLD; cf.dwEffects = CFE_BOLD; SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "bold ");
// add italic text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_ITALIC | CFM_BOLD; cf.dwEffects = CFE_ITALIC; SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "italic ");
// add underlined text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_ITALIC | CFM_BOLD | CFM_UNDERLINE; cf.dwEffects = CFE_UNDERLINE; SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "underline ");
// add strikeout text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_ITALIC | CFM_BOLD | CFM_UNDERLINE | CFM_STRIKEOUT; cf.dwEffects = CFE_STRIKEOUT; SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "strikeout");
// add normal text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_STRIKEOUT; SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) " normal\n");
// add red text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_COLOR; cf.crTextColor = RGB(255,0,0); SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "red ");
// add green text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_COLOR; cf.crTextColor = RGB(0,255,0); SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "green ");
// add blue text memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_COLOR; cf.crTextColor = RGB(0,0,255); SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "blue\n");
// try some fonts memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_FACE | CFM_SIZE; cf.yHeight = 300; strcpy(cf.szFaceName, "Tahoma"); SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "tahoma ");
// try some fonts memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_FACE; strcpy(cf.szFaceName, "Helvetica"); SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "Helvetica ");
// try some fonts memset( &cf, 0, sizeof cf ); cf.cbSize = sizeof cf; cf.dwMask = CFM_FACE; strcpy(cf.szFaceName, "Courier"); SendMessage( hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); SendMessage( hwnd, EM_REPLACESEL, FALSE, (LPARAM) "Courier "); }
LRESULT WINAPI ParentWindowProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { RECT r; HWND hwndRichedit = (HWND) GetWindowLong( hWnd, 0 ); char *cls; //cls = RICHEDIT_CLASS; //cls = "RICHEDIT10A"; cls = "RICHEDIT";
switch(msg) { case WM_CREATE: GetClientRect( hWnd, &r ); hwndRichedit = CreateWindow( cls, "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_SUNKEN, 0, 30, r.right-r.left, r.bottom - r.top - 30, hWnd, NULL, NULL, NULL ); fill_richedit( hwndRichedit ); SetWindowLong( hWnd, 0, (LONG) hwndRichedit ); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_LBUTTONDOWN: InvalidateRect( hWnd, NULL, TRUE ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; } return DefWindowProc(hWnd,msg,wParam,lParam); }
/*********************************************************************** * * WinMain */
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) { WNDCLASS cls; char className[] = "parentclass"; /* To make sure className >= 0x10000 */ char winName[] = "Richedit control"; HWND hWnd; MSG msg;
LoadLibrary("riched32");
cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; cls.lpfnWndProc = ParentWindowProc; cls.cbClsExtra = 0; cls.cbWndExtra = 4; cls.hInstance = 0; cls.hIcon = LoadIcon (0, IDI_APPLICATION); cls.hCursor = LoadCursor (0, IDC_ARROW); cls.hbrBackground = GetStockObject (WHITE_BRUSH); cls.lpszMenuName = 0; cls.lpszClassName = className;
if (!RegisterClass (&cls)) return FALSE;
/* Setup windows */ hWnd = CreateWindow (className, winName, WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0, NULL, hInstance, 0);
ShowWindow (hWnd, show); UpdateWindow (hWnd);
/* now enter mesage loop */
while( 0 != GetMessage( &msg, 0, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }
return 0; }
Mike McCormack wrote:
I'm going to play with the richedit control to try get it to draw RTF documents with formatting.
I've started the richedit thing long ago, and now I have some working text wrapping code ready. So far it can use different fonts and attributes (with row height adapting to largest font in the row, words can consist of characters of different font), omit spaces beyond right margin, align paragraphs to left/right/center (no justify, but original richedit doesn't have that either), can display the caret in proper place (but only move left/right/home/end) and use different wrapping strategies depending on available width.
As the company I work for is interested in licensing it from me, I could double license it to be used both in Wine and the proprietary application (which wouldn't like the rocksucking API and horrible limitations of the original RichEdit).
Of course, that doesn't make sense when somebody has much more code, waiting for me to finish a basic implementation for others to hack on would be just wasting time.
Chris
Krzysztof Foltman wrote:
As the company I work for is interested in licensing it from me, I could double license it to be used both in Wine and the proprietary application (which wouldn't like the rocksucking API and horrible limitations of the original RichEdit).
Of course, that doesn't make sense when somebody has much more code, waiting for me to finish a basic implementation for others to hack on would be just wasting time.
Hi Chris,
It would be great if you returned your changes to Wine! I may be able to help you a little with it... I have written a small test program, which you can download from:
http://mandoo.dyndns.org/richedit
Mike