查找/替换对话框CFindReplaceDialog

 

      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导航        

   古典小说网,本人的网站

你可能感兴趣的:(MFC)