MSDN上的解释:
class CFindReplaceDialog : public CCommonDialog
CFindReplaceDialog objects are modeless, allowing users to interact with other windows while they are on
screen.
There are two kinds of CFindReplaceDialog objects: Find dialog boxes and Find/Replace dialog boxes.
Although the dialog boxes allow the user to input search and search/replace strings, they do not perform any of
the searching or replacing functions. You must add these to the application.
To construct a CFindReplaceDialog object, use the provided constructor (which has no arguments).
Since this is a modeless dialog box, allocate the object on the heap using the new operator, rather than on the stack.
CFindReplaceDialog对象是非模态的,允许用户与屏幕上的窗口进行交互
有两种CFindReplaceDialog对象:查找对话框和 查找/替换对话框
尽管对话框允许用户输入查找/替换对话框,它们并不进行查找或替换,必须在应用中添加相关代码。
以下为构造查找/替换对话框步骤:
1) 初始化
假如工程是基于对话框的, 则在‘ 工程Dlg.cpp’ 中添加一个指针全局变量、BOOL类型变量find、自定义的一个消息
定义变量及注册消息
CFindReplaceDialog *findReplaceDlg; // 用以指向对话框资源
BOOL find; // 用以确定是查找对话框,还是查找/替换对话框
static UINT WM_FINDMESSAGE=RegisterWindowMessage(FINDMSGSTRING);// 定义的新消息,执行查找/替换对话框时发送该消息
在工程DLG.h中 给对话框添加一消息响应函数
CLASS 工程Dlg: public CDialog
{
public:
afx_msg long OnFindReplace(WPARAM wParam,LPARAM lParam);
CRichEditCtrl m_RichEdit; // 在RichEdit控件中 实现查找替换功能
}
同时,在‘工程Dlg.cpp’ 中添加消息函数映射
ON_REGISTERED_MESSAGE(WM_FINDMESSAGE,OnFindReplace)
2) 构造查找/替换对话框
因为它是非模态的,所以必须用new操作符把它放于堆而不能放于栈中
点击对话框的查找按钮,添加如下代码:(工程名称为Hello2)
void Chello2Dlg::OnBnClickedFind() { if (!findReplaceDlg) // 判断是否已经创建过 { findReplaceDlg=new CFindReplaceDialog; // 为对话框指针赋值 findReplaceDlg->Create(TRUE,NULL); // 建立一查找对话框 findReplaceDlg->ShowWindow(SW_SHOW); // 显示 “查找”对话框 find=TRUE; } m_RichEdit.SetSel(0,0); //设定选择文本的初始位置 }
点击替换按钮,添加如下代码:
void Chello2Dlg::OnBnClickedReplace() { if (!findReplaceDlg) { findReplaceDlg=new CFindReplaceDialog; findReplaceDlg->Create(FALSE,NULL); // 替换对话框 findReplaceDlg->ShowWindow(SW_SHOW); //显示 find=FALSE; // FALSE 表明为替换对话框 } //这里不要置文本选择初始位置 因为要替换的是查找到的当前位置 }
在DLG.cpp中添加消息响应函数OnFindReplace(WPARAM wParam, LPARAM lParam)
long Chello2Dlg::OnFindReplace(WPARAM wParam,LPARAM lParam)
{
CString strText,repText;
strText=findReplaceDlg->GetFindString(); // 要查找的字符串
CString str; // RICHEDIT控件中的总的字符串
m_RichEdit.GetWindowText(str);
int len=strText.GetLength(); // 要查找的字符串长度
long index=0,end_index=0; // 索引的起始位置 及 结束位置, 从0开始
if (find) // 查找对话框
{
if (findReplaceDlg->IsTerminating()) // 销毁对话框 首先检查是否撤销对话框,否则可能会先执行其他操作,然后再撤销
{
findReplaceDlg->DestroyWindow();
findReplaceDlg=NULL;
return 0;
}
if (findReplaceDlg->SearchDown()) // 向下搜索
{
m_RichEdit.GetSel(index,end_index); //得到查询的起始与结束位置 为半闭半开区域 [index,end_index)
index=str.Find(strText,end_index); // 从上次查询的结束位置处继续往下查询
if (index!=-1) //往下搜索时,找到所要查询的子字符串
{
m_RichEdit.SetSel(index,index+len); // 为找到的子字符串 设置选择标记
m_RichEdit.SetFocus(); // 在找到的子字符串上,设置焦点
}
else // 往下搜索时,未找到所要查找的子字符串
{
index=str.Find(strText,0); //从文件开始处,重新查找, 可以实现当搜索到文件末尾时,点查找下一个按钮时,可以从头重新查,从而实现循环功能
if (index==-1)
{
MessageBox(L"以查找完毕,无所查内容"); //若从开始处查找,仍然找不到,则说明无此查找内容
return 0;
}
m_RichEdit.SetSel(index,index+len); // 若从开始处查找,查询到所查内容,则为其做标记
m_RichEdit.SetFocus();
}
}
else // 向上搜索
{
m_RichEdit.GetSel(index,end_index); // 得到当前选择文本的始末位置
CString strReverse=str.MakeReverse(); // 对控件中的文字进行反转
CString strTextReverse=strText.MakeReverse(); // 对查找串的文字进行反转
index=strReverse.Find(strTextReverse,str.GetLength()-index); 从反串中往下查找 查找的起点位置索引为 ID=STR.Length-index-1的前一位,即从源串开始位置的前一位搜索 ,不能从源串开始位置处搜索,因为若仅单个字符时,总是查询到这个位置,不会再往前查询了
if (index!=-1)
{
end_index=str.GetLength()-index-1; // 源串与反串index 的关系 反串的起始位置即为源串的末尾
}
else
{
index=strReverse.Find(strTextReverse,0);
if (index==-1)
{
MessageBox(L"以查找完毕,无所查内容"); //若从开始处查找,仍然找不到,则说明无此查找内容
return 0;
}
end_index=str.GetLength()-index-1; //转换成源串的末尾位置索引 反串的起始位置即为源串的末尾
}
m_RichEdit.SetSel(end_index+1-len,end_index+1); // 由结尾位置 倒推源串,其中要包含结尾位置。 SETSEL 为【)区间,所以要使位置end_index 包含之中,范围必须是setsel(,end_index+1)
m_RichEdit.SetFocus();
}
}
else // 替换对话框
{
if (findReplaceDlg->IsTerminating()) // 首先判断是否 销毁对话框
{
findReplaceDlg->DestroyWindow();
findReplaceDlg=NULL;
return 0;
}
if (findReplaceDlg->FindNext())
{
m_RichEdit.GetSel(index,end_index);
index=str.Find(strText,end_index);
if (index!=-1)
{
m_RichEdit.SetSel(index,index+len);
m_RichEdit.SetFocus();
}
else
{
index=str.Find(strText,0);
if (index==-1)
{
MessageBox(L"以查找完毕,无所查内容");
}
m_RichEdit.SetSel(index,index+len);
m_RichEdit.SetFocus();
}
}
if (findReplaceDlg->ReplaceCurrent())
{
index=str.Find(strText,0);
if (index==-1)
{
MessageBox(L"以查找完毕,无所查内容");
}
else
{
m_RichEdit.GetSel(index,end_index);
CString sub_left,sub_mid,sub_ringht;
sub_left=str.Left(index);
sub_mid=str.Mid(index,end_index-index);
if (sub_mid!=strText) // 判断当前选择文本 是否为查找文本
{
MessageBox(L"请重新搜索") ;
return 0;
}
sub_ringht=str.Right(str.GetLength()-1-end_index+1); // 右边串包含end_index这个位置的字符
repText=findReplaceDlg->GetReplaceString();
str=sub_left+repText+sub_ringht;
m_RichEdit.SetWindowText(str);
}
}
if (findReplaceDlg->ReplaceAll())
{
int num=0;
CString mssag;
repText=findReplaceDlg->GetReplaceString();
len=repText.GetLength();
num=str.Replace(strText,repText);
m_RichEdit.SetWindowText(str);
mssag.Format(L"已经完成所有替换,共替换%d处",num);
MessageBox(mssag);
}
}
}
参考资料:
http://bk.chinaar.com/index.php?doc-view-76
http://book.csdn.net/bookfiles/565/10056518722.shtml
http://book.51cto.com/art/200810/92630.htm
http://www.codeproject.com/KB/dialog/cfindreplacedialog.aspx
http://blog.sina.com.cn/s/blog_6171ceb30100ex1d.html
http://www.vckbase.com/study/article/vc_chap/chap5_6.htm
如果此文对您有所帮助,还望点击一下以下网站:
360导航
2345导航
古典小说网,本人的网站