|
Download demo project - 40 Kb
Download source - 6 Kb
While MFC does provide a rich edit control, it does not provide a quick and
easy way to handle formatting and RTF codes. CAutoRichEditCtrl is a derivative
of CRichEditCtrl. This new class adds several functions that allow you to add
formatting quickly. It also provides two functions to let you retrieve the
formatted text (RTF) in a CString, and to insert an RTF CString into the
control.
To use CAutoRichEditCtrl in a dialog box, follow these instructions.
- Insert a normal rich edit control in your dialog box.
- Using ClassWizard, attach a control variable of type
CRichEditCtrl to your control.
- Copy AutoRichEditCtrl.cpp and AutoRichEditCtrl.h (download below) to your source directory, and #include "AutoRichEditCtrl.h" in your dialog's header.
- In your dialog's header, change
CRichEditCtrl to CAutoRichEditCtrl.
- In your application's InitInstance (
CMyApp::InitInstance()), include a call to AfxInitRichEdit() - this is needed for all rich edit controls.
- Add interface elements that use
CAutoRichEditCtrls's functions - see below.
Once you've inserted the control into your project, you can add toolbar buttons, menu commands, or other elements to call the following functions:
- GetRTF() - returns a
CString holding the text of the control (including the RTF formatting code).
- SetRTF(CString sRTF) - parameter sRTF is an RTF formatted CString. Calling this will insert and format the string. If a
CString is passed that does not have valid RTF code, the control will be cleared.
- SelectionIsBold() - returns
true if the current selection is bold, otherwise false.
- SelectionIsItalic()- returns
true if the current selection is italic, else false.
- SelectionIsUnderlined() - returns
true if the current selection is underlined, else false.
- SetSelectionBold() - sets the current selection to be bold (Note: this will actually act like pressing the Bold toolbar button in Wordpad - if the text is not bold, it will become bold; if the text is already bold, it will remove the bold formatting; if part of the selection is bold, the entire selection will become bold; if there is not anything selected, the format is changed to bold so when the user starts typing, it will be in bold).
- SetSelectionItalic() - sets the current selection to italic (see note in
SetSelectionBold()).
- SetSelectionUnderlined() - sets the current selection to underlined (see note in
SetSelectionBold()).
- SetParagraphCenter() - sets the current paragraph to be centered.
- SetParagraphLeft() - sets the current paragraph to be left justified.
- SetParagraphRight() - sets the current paragraph to be right justified.
- ParagraphIsCentered() - returns
true if the current paragraph is centered, else false.
- ParagraphIsLeft() - returns
true if the current paragraph is left justified, else false.
- ParagraphIsRight() - returns
true if the current paragraph is right justified, else false.
- SetParagraphBulleted() - sets the bullet style (see note in
SetSelectionBold()).
- ParagraphIsBulleted() - returns
true if the current selection is bulleted, else false.
- SelectColor() - displays a color selection dialog box and sets the selection to the chosen color (if OK is pressed).
- SetFontName(CString sFontName) - sets the selected font to
sFontName.
- SetFontSize(int nPointSize) - sets the selection to
nPointSize.
- GetSelectionFontName() - returns a
CString holding the selection's font name.
- GetSelectionFontSize() - returns a
long holding the selection's font size.
- GetSystemFonts(CStringArray &saFontList) -
saFontList will hold an array of all true-type fonts available on the system.
- GetCharFormat() - returns the
CHARFORMAT structure of the current selection.
To see examples of these functions, download the demo app. The source code that shows examples of how to use each function is located in CRichEdDlg::OnExecute().
A quick example here: if you want a rich edit control in a dialog to use formatting, you may create a toolbar with the typical bold, italic, and underline buttons. Just use ClassWizard to add a function for when the user presses the button (like OnBold), then call the right function (like m_richedit.SetSelectionBold();, assuming your rich edit control is named m_richedit). That's all it takes to set up the formatting correctly.
When you want to save the text, just do a CString sText = m_richedit.GetRTF();, then save the string however you like - when you call m_richedit.SetRTF(sText); with the same string, the formatting will be just like it was when you saved it.
Two thank you's are in order for Zafir Anjum and Girish Bharadwaj. The code that streams the RTF string into the control was taken from Zafir's article, Inserting an RTF string using StreamIn. The code that retrieves all the fonts on the system was derived from Girish's article, Owner Drawn Font Selection ComboBox.
You are free to use/modify this source code for whatever you like. If you do make any modifications or additions, I would appreciate it you let me know (or better, let everybody know by posting a comment). Of course, this control is provided as is, and no warranty is expressed or implied as to its fitness for any particular purpose.
Hope this helps you out!
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 43 (Total in Forum: 43) (Refresh) | FirstPrevNext |
|
 |
|
|
I have a DLL that I am trying to use this control in, and the DLL has to be UNICODE. I am trying to auto populate the control with text when the user does something in the dialog. I am using the control only for formatted information display, no edit ability when it ships to the user, but is editable during my debugging. When I call SetRTF, nothing appears in the control. If I manually type something in it and then do something in the dialog that causes it to change, the text I typed in will disappear, but no new text appears. In order to get it to compile in UNICODE I had to change the following line in the streamin function.
memcpy(pbBuff, (LPCSTR) *pstr, *pcb);
to
memcpy(pbBuff, (LPCTSTR) *pstr, *pcb * sizeof(TCHAR));
Since I am in a DLL, I could not call AfxInitRichEdit in the InitInstance, so I placed it in the DllMain function instead. Any ideas on how to get it to work?
I am using Visual Studio 2005
I converted the demo app to UNICODE and it exhibits the same behaviour. I can type text in the RichEditCtrl and execute the GetRTF command and it shows the formatted text in the top edit box, and can immediately execute the SetRTF command and the RichEditCtrl empties.
-- modified at 12:48 Monday 12th February, 2007
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
Necessary to generate a DLL that to recoup the text formatted (rtf) for a CString. How I must proceed?
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
1.Riched20.dll different. 2.Unicode and DBCS
replace dll, but problem stay? Can you help me?
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
Hi,
What is the correct way to capture Tab Key presses in a RichEditCtrl. I saw the answer for Catching tabs but was not convinced with the answer. If I have to get the current position of the Cursor in the RichEditCtrl (GetSel()), how do I do that, and from there on how do I insert a Tab. Some one could help me.
Thanks and Regards Frank
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Let's do this the easy way! Open the project folder and delete the file "yourapp.clw" Now press Ctrl + W to bring up the class wizard. Select "Yes" you would like to build the class wizard database from the source files and press "Ok". This will allow the class "CAutoRichEditCtrl" to be modified by using the class wizard (much easier this way). Now open class wizard again and select the "CAutoRichEditCtrl" class and add the message "WM_GETDLGCODE". Now edit the body of the function so it looks like the following:
UINT CAutoRichEditCtrl::OnGetDlgCode() { return DLGC_WANTALLKEYS; }
If you don't like the default tab stops you can change them using the SetParaFormat() function.
Jason
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I have tried using the CAutoRichEditCtrl class (which is great) but i have stumbled upon a problem. I enable the control to recieve OLE objects (in my case pictures) by implementing IRichEditOleCallback and adding a SetOLECallback to my InitDialog. This works fine, the control accepts bitmap objects and the GetRTF function returns perfect RTF code containing all the OLE items. The problem is that when i try to insert this text back into the control all OLE objects are removed and replaced by spaces. When i insert the same text into a CRichEditView all is fine.
Any ideas how this can be corrected?
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
iam using a different font in which some characters have a dot above it. whenever i try to write such characters a white space gets automatically appended. how do i remove such white spaces???
please help me......
thanks!
ramya.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
ok - i can retrieve text from the control
but how do i insert text to it ? (not using GUI ofcourse)
(btw - Great Control)
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
 | abc |  | Anonymous | 19:48 26 Aug '03 |
|
|
 |
|
|
I think it's not releated to your code - but an error in RichEdit control itself. Try this:
Add a bullet and write something, then add few blank lines and write something. It should looks like that:
* some text
another text
Then click on GetRTF and SetRTF few times - extrad dots are beign generated! Any idea how to get rid of this ? Thanks! Irek
Check out my software at: http://www.ireksoftware.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I found this problem too, you may want to edit your title to "Bug with Bulleting" or something similar.
Looks like it's a bug in MS's CRichEditCtrl. Haven't been able to figure out how to fix it yet. Any luck on your side?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is a bug in the RichEditCtrl. This bug is solved in RichEditCtrl version 2.0. In VC 6.0 the RichEditCtrl version 1.0 is still used by the resoure editor. If you change "RICHEDIT" manually into "RichEdit20A" in the rc file, version 2.0 will be used in your dialog and the problem disappears.
I have tested this with VC 7.0.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
//*************************************************************************************** // I want to draw the RichTextControl content in a specified rectangle on my printing page // (as i done with editbox control) using FormatRange function with the different // Font styles as in RichEditControl - HelpMe please!. // DrawRichText(CDC *pDC) -> could u solve the problem that i have in this function ?.. //*************************************************************************************** //The partial code
//RTCtrlPrint1View.h public: CRTCtrlPrint1Doc* GetDocument(); //My************************************* void RTCtrlCreate(); void DrawRichText(CDC *pDC); void DrawEditText(CDC *pDC);
CRichEditCtrl m_redit; CRect m_redRect;
CEdit m_edit; CRect m_edRect; UINT r; CFont font; //**************************************
//RTCtrlPrint1View.cpp void CRTCtrlPrint1View::OnInitialUpdate() { CScrollView::OnInitialUpdate();
/*B**********************************************/ //edith box displaytext font font.CreateFont(14,0,0,0,FW_NORMAL,FALSE,FALSE, 0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH|FF_MODERN,"Arial");
r=14; m_edRect = CRect(50*r,-100*r,240*r,-700*r); m_redRect = CRect(250*r,-100*r,750*r,-700*r);
CSize sizeTotal; sizeTotal.cx = 850*r; sizeTotal.cy = 1100*r; SetScrollSizes(MM_TWIPS, sizeTotal); //MM_TWIPS
RTCtrlCreate(); /*E**********************************************/ }
void CRTCtrlPrint1View::OnDraw(CDC* pDC) { CRTCtrlPrint1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc);
/*B**********************************************/ pDC->Rectangle(1*r,1*r,800*r,-1100*r);//Print Area Rect
if(pDC->IsPrinting()) { DrawEditText(pDC);//Simple Edit box text DrawRichText(pDC);//My RichEdit box text } /*E**********************************************/ }
#define IDC_REDIT 4001 //defining a resource ID #define IDC_EDIT 4002 //defining a resource ID
void CRTCtrlPrint1View::RTCtrlCreate() //creates both Rich edit & Edit Controls { /*B**********************************************/ CRect m_temp;
CClientDC dc(this); OnPrepareDC(&dc);
//creating edit box in scroll view m_temp = m_edRect; dc.LPtoDP(m_temp); m_edit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,m_temp,this,IDC_EDIT); m_edit.SetFont(&font,FALSE); m_edit.SetWindowText("Help Me! Thank u");
//creating rich edit box in scroll view m_temp = m_redRect; dc.LPtoDP(m_temp); m_redit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,m_temp,this,IDC_REDIT);
//writing some text in richtext control CString str; str="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang2057{\\fonttbl{\\f0\froman\\fprq2\\fcharset0 Times New Roman;}{\\f1\\fswiss\\fprq2\\fcharset0 System;}}{\\colortbl ;\\red255\\green0\\blue0;\\red51\\green153\\blue102;\\red0\\green0\\blue255;}\\viewkind4\\uc1\\pard\\cf1\\i\\f0\\fs24 ThankYou\ \\cf0\\i0 \\cf2\\b for\ \\cf0\\b0 \\cf3 Trying\ \\cf0 !\\b\\f1\\fs20 \\par }";
EDITSTREAM es; es.dwCookie = (DWORD)&str; es.pfnCallback = RichEditStreamInCallback; m_redit.StreamIn(SF_RTF,es);
/*E**********************************************/ }
void CRTCtrlPrint1View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { CScrollView::OnPrepareDC(pDC, pInfo);
/*B**********************************************/ // pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetMapMode(MM_TWIPS); /*E**********************************************/ }
void CRTCtrlPrint1View::DrawEditText(CDC *pDC) { /*B**********************************************/ CRect m_temp; m_temp = m_edRect;
CString str; m_edit.GetWindowText(str); pDC->SetBkMode(TRANSPARENT); pDC->Rectangle(m_temp); //Draws with Fonts as we wish pDC->DrawText(str,m_temp,DT_WORDBREAK|DT_EXPANDTABS|DT_NOPREFIX); /*E**********************************************/ }
//*************************************************************************************** // I want to draw the RichTextControl content in a specified rectangle on my printing page // (as i done with editbox control) using FormatRange function with the different // Font styles as in RichEditControl - HelpMe please!. // DrawRichText(CDC *pDC) -> could u solve the problem that i have in this function ?.. //*************************************************************************************** void CRTCtrlPrint1View::DrawRichText(CDC *pDC) { /*B**********************************************/ CRect m_temp; FORMATRANGE fmtRange; long lLineWidth;
m_temp = m_redRect; // pDC->LPtoDP(m_temp); pDC->Rectangle(m_temp);
lLineWidth = ::MulDiv(pDC->GetDeviceCaps(PHYSICALWIDTH), 1440, pDC->GetDeviceCaps(LOGPIXELSX));
fmtRange.hdc = pDC->m_hDC; fmtRange.hdcTarget = pDC->m_hDC; fmtRange.rc = m_temp; fmtRange.rcPage = m_temp; fmtRange.chrg.cpMin = 0; fmtRange.chrg.cpMax = -1;
m_redit.SetTargetDevice(pDC->m_hDC, lLineWidth); m_redit.FormatRange(&fmtRange, TRUE);
/*E**********************************************/ } any body brave..
Balaji
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,
not really the right forum, but perhaps here is an RTF expert 
I wanted to use the RTF/CRichEditCtrl as a kind of report system, where the reports are generated from templates of rtf files. A first simple solution would be to search and replace Tags within the RTF file with the computed values.
A better solution would be to use the field tag from the RTF specification directly. For example the author field from a word document would look like:
{\field{\*\fldinst { AUTHOR \\* MERGEFORMAT }}{\fldrslt {Dirk}}}
where fldinst is the specific field instruction and fldrslt is the latest evaluated result.
Unhappily the CRichEditCtrl does not evaluate internal fields (like author) either, and I couldn't find any Interface in the ITextDocument specification to access the fields of the document.
Does anybody know how to reevaluate the contents of fields programmatically? Something like a callback function with the fied instruction (fldinst) and the return value is the evaluated result? Another possibility would be to reparse the complete document again and aply the evaluated values into the result field (fldrslt) and then feed the document back to the Ctrl.
Any ideas / code?
Thanks
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
RTF documents can have informations that are not displayed like author information, version etc. Has anyone tried to add and retrieve for example author information to a RTF document? Also has anyone tried to add bitmaps to a RTF document?
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
NT4/VS.NET needs replacement in this fct:
// for (int i = 0; i <= sFontName.GetLength()-1; i++) // cf.szFaceName[i] = sFontName[i]; lstrcpy(cf.szFaceName,sFontName);
otherwise the szFaceName will keep letters in szFaceName that are not replaced, sometimes causing a crash!
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Yes, I just stumbled across that, too ... I did a slightly different fix, by adding the following after the for loop:
cf.szFaceName[sFontName.GetLength()] = '\0';
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
It should work just fine, as long as you supply a nul byte after the name of the font. My earlier posting showed how this was done, as did Anonymous' posting about the bug.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I am using richedit20.dll(version). Most of the features like multi undo and redo work but somehow the paste doesn't work. It cuts the text but doesn't paste it. If I cut the text from some other application and try paste, it works.When I look at the clipboard there is nothing in it. I am using CRichEditView. I tried GetPriorityClipboardFormat(), but it returns -1.
Thanks
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
|
|
To print directly from the control add the following method (from Al Williams website)
BOOL CAutoRichEditCtrl::Print(CString Title) { CDC ThePrintDC; //create a device context to use CPrintDialog PrintDialog(FALSE); //make a print dialog too if(PrintDialog.DoModal()==IDOK) //pressed the ok button on the print dialog? { ThePrintDC.Attach(PrintDialog.GetPrinterDC());//if so get settings } else return FALSE; //leave this procedure, before anything bad happens long CharRange=0; long LastChar=0;//will store document length DOCINFO di; //make a docinfo structure ::ZeroMemory(&di, sizeof(DOCINFO)); //need to be claer, so clear stuff from it di.cbSize=sizeof(DOCINFO); //set size member di.lpszDocName=Title;//set doc name, was passed via another funtion FORMATRANGE fr; //make a format range structure ::ZeroMemory(&fr, sizeof(FORMATRANGE));//clear stuff from it HDC hdc=ThePrintDC.GetSafeHdc(); //get handle to DC we are using fr.hdc=hdc; //Set meber in FormatRange struct fr.hdcTarget=hdc; //Set member in FormatRange struct //This bit here will get all the dimentions of the printer setup int nHorizRes = ThePrintDC.GetDeviceCaps(HORZRES), //width P in MM nVertRes = ThePrintDC.GetDeviceCaps(VERTRES), //hight in raster lines nLogPixelsX = ThePrintDC.GetDeviceCaps(LOGPIXELSX), //pixels per inch along x nLogPixelsY = ThePrintDC.GetDeviceCaps(LOGPIXELSY); //pixels per inch along y //set the printable area of printer in the FormatRange struct fr.rcPage.left = 0; //these 2 mean top left fr.rcPage.top = 0; fr.rcPage.right = (nHorizRes/nLogPixelsX) * 1440;//these 2 mean bottom right fr.rcPage.bottom = (nVertRes/nLogPixelsY) * 1440; //equation changes pixel to TWIPS // Set up some margins all around. Make them one inch //results vary on printers depending on setup fr.rc.left = fr.rcPage.left + 1440; // 1440 TWIPS = 1 inch. fr.rc.top = fr.rcPage.top + 1440; fr.rc.right = fr.rcPage.right - 1440; fr.rc.bottom = fr.rcPage.bottom - 1440; //select all text for printing CHARRANGE cr; cr.cpMin=0; cr.cpMax=-1;//-1 selects all fr.chrg=cr;//set this in FormatRange struct //get length of document, used for more than one page CharRange=GetTextLength(); int ErrorStatus=0;
//Start Printing //ThePrintDC.SetAbortProc(&AbortProc(hdc, )); //dont know how callbacks works yet ThePrintDC.StartDoc(&di); //start printing document do { ThePrintDC.StartPage(); //start the page LastChar = FormatRange( &fr, TRUE );//send text to DC, and record index //of last fitting char ErrorStatus=ThePrintDC.EndPage();//end this page, and record status cr.cpMin=LastChar;//Change charrange struct for next page cr.cpMax=CharRange; //using last char printed fr.chrg=cr; //set that in formatrange struct }while(LastChar==0); //while there is stuff to print ot there //is not an error(error is -No) //if there is an error or printing has finished //have to make sure AbortDoc is called instead of EndDoc if there has been a problem switch(ErrorStatus) { case SP_ERROR: { ThePrintDC.AbortDoc(); AfxMessageBox("There was a general printing error, please check printer is working properly, connected, on line etc.", MB_OK | MB_ICONEXCLAMATION); return FALSE; } case SP_APPABORT: { ThePrintDC.AbortDoc(); return FALSE; } case SP_USERABORT: { ThePrintDC.AbortDoc(); return FALSE; } case SP_OUTOFDISK: { ThePrintDC.AbortDoc(); AfxMessageBox("The print spooler is out of disk space, free up some disk space and try again.", MB_OK | MB_ICONEXCLAMATION); return FALSE; } case SP_OUTOFMEMORY: { ThePrintDC.AbortDoc(); AfxMessageBox("Your computer is out of memory, shut down some applications and/or some windows and try again.", MB_OK | MB_ICONEXCLAMATION); return FALSE; } default: { ThePrintDC.EndDoc(); return TRUE; } } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|