Getting the Find and Replace Dialogs to work in a CRichEditCtrl
I need to get the Find and Replace Dialogs to work in an application that uses CEditCtrl (not CEditView). In CEditView, the Find and Replace Dialogs are installed as part of the class, but not so in CEditCtrl. You apparently have to implement these dialogs yourself. Since they are part of the Common Dialogs, this should not be too difficult.
Searching MSD for: Find and Replace Dialog Boxes
I came up with what at first seemed like the answer to my problem.
You create and display a Find dialog box by initializing a FINDREPLACE structure and passing the structure to the FindText function. The following illustration shows a typical Find dialog box.
OK, let's give it my best shot:
Code:
/// You create and display a Find dialog box by initializing a FINDREPLACE
/// structure and passing the structure to the FindText function.
void CMyRichEditCtrlClass::OnEditFind()
{
FINDREPLACE fr;
/*
fr.Flags;
fr.hInstance;
fr.hwndOwner;
fr.ICustData;
fr.lpfnHook;
fr.lpstrFindWhat;
fr.lpstrReplaceWith;
fr.lpTemplateName;
fr.lStructSize;
fr.wFindWhatLen;
fr.wReplaceWithLen;
*/
//m_RichEdit.FindTextA(DWORD dwFlags, FINDTEXTTEXA *pFindText) const;
//FINDTEXTEXA ftx;
//ftx.chrg; // CARRANGE
//ftx.chrgText;
//ftx.lpstrText; // LPCSTR
//ftx.chrgText = (LPCSTR)"portola";
//m_RichEdit.FindTextA(FR_WHOLEWORD, &ftx);
char buf[256];
CHARRANGE chrg;
chrg.cpMax = -1;
chrg.cpMin = 0;
FINDTEXTEXA ftx;
ftx.chrg = chrg;
ftx.chrgText = chrg;
ftx.lpstrText = (LPCSTR)buf;
// Find and Replace Dialog Boxes
// http://msdn.microsoft.com/en-us/library/ms646956(VS.85).aspx
// You create and display a Find dialog box by initializing a FINDREPLACE structure
// and passing the structure to the FindText function.
long res = m_RichEdit.FindTextA(FR_WHOLEWORD, &ftx);
if(res == 0)
{
DWORD dw = CommDlgExtendedError();
TRACE1("CommDlgExtendedError = %0.0f\n", dw);
}
}
Well, if this code worked, I wouldn't be here now, would I? In fact, it crashes in a most unseemly manner, never even getting to the error analysis, much less bringing up a modeless Find dialog.
Obviously, I could reengineer both Find and Replace dialogs, but this seems like alot of work since they are both apparently built into the SDK framework somewhere. And using CRichEditView is out of the question.
Does anyone know how to get this to work?
Last edited by Mike Pliam; November 19th, 2009 at 11:48 PM.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
Sorry, I couldn't understand what you need and what you did:
FINDTEXTEX structure is used for Rich edit controls, not for Edit controls
What is the type of m_RichEdit in your code snippet?
To use Find and Replace dialogs in other than CRichEditCtrl classes you should use FINDREPLACE structure and FINDMSGSTRING Registered Message as it described in MSDN article you referred to
The m_RichEdit is a CRichEditCtrl member of CMainFrame. Most of the usual functionality such as cut, copy, paste, etc have been easy to facilitate. For example, all one needs is:
Code:
m_RichEdit.Cut();
But not so easy with Find and Replace. That's my problem.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
Victor,
Sorry if my explanation of the problem was vague.
If you go to most text editing applications Edit menu, you will usually find an Undo, Redo,Cut, Copy, Past, Delete, Select All, Find, and Replace menu options. I wish to facilitate the Find and Replace menu options in the application that is described above. The problem is to bring up the necessary dialogs. I do not know how to do that.
Let's say that I click on the Edit/Find option of the application main menu. That selection will be wired to a method such as OnEditFind that immediately brings up a modeless Find Dialog (which exists in the Common Dialogs framework).
Code:
void CMainFrame::OnEditFind()
{
// I cant get the dialog to come up from here !!!
}
And the same holds true for the OnEditReplace() method.
The reason for trapping the res == 0 (or NULL) is to trap the error which MSDN resides in CommDlgExtendedError() function.
I don't know how to make the problem much clearer.
Last edited by Mike Pliam; November 20th, 2009 at 04:17 PM.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
Why do you explicitly call the "A" functions (ie. FindTextA)?
My VS 2005 compiler will often add the 'A' or 'W' to a function, depending upon whether I am in Unicode or Multibyte mode. At first, I thought this was a bit odd, and others here have asked that same question. But after having to convert some applications to Unicode from Multibyte, and vice versa, I thought it might be a good idea not to fight it. This seems to me to be particularly helpful when using framework structs, some of which are designated 'A' or 'W' to help keep matters straight. As far as actual compilation, it apparently makes no difference, provided the suffix matches the character set that one is using.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
Originally Posted by Mike Pliam
My VS 2005 compiler will often add the 'A' or 'W' to a function, depending upon whether I am in Unicode or Multibyte mode. At first, I thought this was a bit odd, and others here have asked that same question. But after having to convert some applications to Unicode from Multibyte, and vice versa, I thought it might be a good idea not to fight it. This seems to me to be particularly helpful when using framework structs, some of which are designated 'A' or 'W' to help keep matters straight. As far as actual compilation, it apparently makes no difference, provided the suffix matches the character set that one is using.
The bottom line is that these extensions shouldn't end up in your code. The compiler #ifdefs will resolve these to the A and W extensions, but if you are adding these yourselves, you are doing it wrong.
I mention this because you could be seeing a mismatch of ANSI vs. UNICODE and that may be leading to your problem.
In general (even though I see a lot of people do it), you won't want to explicitly call CStringA or W, any A or W api's, structures, etc. directly. Sure, there might be a rare case that this needs to be done, but if you are coding this way all the time, it's an invitation to trouble, IMO.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
Thanks for the advice Arjay. But I think we've gotten a bit off track here. I still have not figured out how to get the Find and Replace dialogs to work from my code. Any help greatly appreciated.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
Originally Posted by Mike Pliam
Thanks for the advice Arjay. But I think we've gotten a bit off track here. I still have not figured out how to get the Find and Replace dialogs to work from my code. Any help greatly appreciated.
I'm not sure it's off track. You could have a character mismatch, so that's why you are running into trouble. I would start by removing the 'A' function and structure references.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
To repeat the above without the 'A' suffix, here's my attempt to replace
text in a CRichEditCtrl derived edit box:
Code:
// see: http://msdn.microsoft.com/en-us/library/ms646835(VS.85).aspx
void CMainFrame::OnEditReplace()
{
// You create and display a Find dialog box by initializing a FINDREPLACE structure
// and passing the structure to the FindText function. The following illustration shows
// a typical Find dialog box.
FINDREPLACE fr;
/*
fr.Flags;
fr.hInstance;
fr.hwndOwner;
fr.ICustData;
fr.lpfnHook;
fr.lpstrFindWhat;
fr.lpstrReplaceWith;
fr.lpTemplateName;
fr.lStructSize;
fr.wFindWhatLen;
fr.wReplaceWithLen;
*/
FINDTEXTEX ftx;
ftx.chrg;
ftx.chrgText;
ftx.lpstrText;
//CReplaceDialog dlg;
//dlg.DoModal();
//m_RichEdit.ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo=0);
//long m_RichEdit.GetSelText(LPSTR lpBuf)const;
//CString m_RichEdit.GetSelText();
//CString csSelText = m_RichEdit.GetSelText();
CString csNewText = "portola";
m_RichEdit.ReplaceSel(csNewText, TRUE );
}
Notice that I have set the csNewText to 'portola' (which is the first thing that popped into my head and has no significance). Now, when I load text into the CEditCtrl derived window, then highlight a particular section of text, then select Edit/Replace, voila, the highlighted section is replaced by the word 'portola'. So that part works. But that is not the point. What I wish is to bring up a Replace dialog in order to refine the replacement. But no dialog comes up, despite MSDN promises to the contrary.
So I don't really believe that the 'A' suffix has anything to do with it.
Last edited by Mike Pliam; November 23rd, 2009 at 06:45 PM.
Re: Getting the Find and Replace Dialogs to work in a CRichEditCtrl
I should add that this doesnt work at all and I have a feeling that it is because I have not filled out the struct properly:
Code:
/// You create and display a Find dialog box by initializing a FINDREPLACE
/// structure and passing the structure to the FindText function. The following
/// illustration shows a typical Find dialog box.
void CMainFrame::OnEditFind()
{
FINDREPLACE fr;
/*
fr.Flags;
fr.hInstance;
fr.hwndOwner;
fr.ICustData;
fr.lpfnHook;
fr.lpstrFindWhat;
fr.lpstrReplaceWith;
fr.lpTemplateName;
fr.lStructSize;
fr.wFindWhatLen;
fr.wReplaceWithLen;
*/
char buf[256];
strcpy_s(buf, 256, "summary");
CHARRANGE chrg;
chrg.cpMax = -1;
chrg.cpMin = 0;
FINDTEXTEX ftx;
ftx.chrg = chrg;
ftx.chrgText = chrg;
ftx.lpstrText = (LPCSTR)buf;
//ftx.lpstrText = "summary";
// Find and Replace Dialog Boxes
// http://msdn.microsoft.com/en-us/library/ms646956(VS.85).aspx
// You create and display a Find dialog box by initializing a FINDREPLACE structure
// and passing the structure to the FindText function. The following illustration shows
// a typical Find dialog box.
long res = m_RichEdit.FindText(FR_WHOLEWORD, &ftx);
if(res == 0)
{
DWORD dw = CommDlgExtendedError();
TRACE1("CommDlgExtendedError = %0.0f\n", dw);
}
}
Perhaps someone could help me to fill out the FINDREPLACE struct members so that passing it to FindText will make MSDN's promises a reality. Honestly, I am not trying to get you to do my work for me, but I have searched for the template name to fill in fr.lpTemplateName without success (looked all through afxdlg.h and googled). This might be a big part of the solution if I could nail down the dialog template.
Last edited by Mike Pliam; November 23rd, 2009 at 07:04 PM.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.