欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

查找/替换对话框的使用

程序员文章站 2022-07-14 11:25:12
...

注:在Windows通用对话框中,查找/替换对话框比较特殊,是一个非模态对话框。查找/替换对话框本身没有查找/替换功能,它只是为我们提供了一个接收用户要求的接口,使我们知道了何种查找/替换的要求,真正的查找/替换工作需要另外编程实现。

(1)新建一个基于对话框的MFC应用程序FindReplaceDialogTest,删除对话框中原有控件。
打开FindReplaceDialogTestDlg.cpp文件,在开头定义几个全局变量:

CFindReplaceDialog* gpFindReplaceDlg = NULL; //指向查找对话框或替换对话框
BOOL gbLastCase = FALSE; //记录上一次的大小写情况
int gpos = 0,gcurpos; //gpos是查找索引;gcurpos是当前索引 
CString gstrEdit,gstrLast; //gstrEdit存放上一次编辑框中的正文内容;gstrLast存放上一次查找框中的内容

(2)切换到资源视图,打开对话框,添加一个编辑框,用来显示正文内容,设置编辑框的Want Return和Multiline属性为True,为其添加控件变量m_edt和值变量m_strEdit。添加一个按钮“显示查找对话框”,并添加按钮单击事件处理代码:

void CFindReplaceDialogTestDlg::OnBnClickedButton1()  //显示查找对话框
{
	// TODO: 在此添加控件通知处理程序代码
	if (!gpFindReplaceDlg)
	{
		gpFindReplaceDlg = new CFindReplaceDialog(); //开辟空间
		gpFindReplaceDlg->Create(true, NULL, NULL, FR_DOWN, this);  //创建查找对话框
	}
	gpos = 0;//初始化搜索索引值
	gpFindReplaceDlg->ShowWindow(SW_SHOW);    //显示对话框
}

(3)再添加一个按钮“显示替换对话框”,添加按钮单击事件处理代码:

void CFindReplaceDialogTestDlg::OnBnClickedButton2() //显示替换对话框
{
	// TODO: 在此添加控件通知处理程序代码
	if (!gpFindReplaceDlg)
	{
		gpFindReplaceDlg = new CFindReplaceDialog(); //开辟空间
		gpFindReplaceDlg->Create(false, m_FindString, m_ReplaceString, FR_DOWN, this);// 创建替换对话框
	}
	gpos = 0;//初始化搜索索引值
	gpFindReplaceDlg->ShowWindow(SW_SHOW);    //显示对话框
}

(4)在FindReplaceDialogTestDlg.h文件CFindReplaceDialogTestDlg类中增加以下代码:

CString m_FindString, m_ReplaceString;

(5)打开FindReplaceDialogTestDlg.h文件,定义一个全局变量:

static UINT WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING); //注册消息

(6)添加消息处理函数,在头文件FindReplaceDialogTestDlg.h中声明函数,定位到DECLARE_MESSAGE_MAP()前面添加:

afx_msg LONG OnFindReplace(WPARAM wParam, LPARAM lParam);

(7)再打开FindReplaceDialogTestDlg.cpp,添加函数:

LONG CFindReplaceDialogTestDlg::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
	BOOL bCase = gpFindReplaceDlg->MatchCase();
	BOOL bDown = gpFindReplaceDlg->SearchDown();
	CString strRawFind;


	//判断是否关闭查找替换对话框  
	if (gpFindReplaceDlg->IsTerminating())
	{
		gpFindReplaceDlg = NULL;
		return 0;
	}
	//获取需要查找的文本  
	CString strFind = gpFindReplaceDlg->GetFindString();
	int lenStrFind = strFind.GetLength();
	//获取需要替换所查找的文本的文本  
	CString strReplace = gpFindReplaceDlg->GetReplaceString();
	int lenStrReplace = strReplace.GetLength();
	CString strEdit;

	m_edt.GetWindowText(strEdit); //获取查找/替换对话框上的查找框中的字符串

	if(gbLastCase != bCase)//大小写状态发生了变化,准备重新开始搜索
	{
		gbLastCase = bCase; //保持本次大小写状态
		if (bDown)
			gpos = 0;
		else
			gpos = strEdit.GetLength() - 1;
	}
	
	if (gstrEdit.Compare(strEdit) != 0)//如果用户修改了正文内容,则索引要初始化
	{
		gstrEdit = strEdit; //保存本次正文内容
		if (bDown)
			gpos = 0;
		else
			gpos = strEdit.GetLength() - 1;
	}
	if (gstrLast.Compare(strFind) != 0)//如果用户修改了查找框中的内容,则索引要初始化
	{
		gstrLast = strFind; //保存本次查找框中的内容
		if (bDown)
			gpos = 0;
		else
			gpos = strEdit.GetLength() - 1;
	}

	strRawFind = strFind;
	if (!bCase) //如果不区分大小写,则都转成大写
	{
		strEdit.MakeUpper(); //转换成大写
		strFind.MakeUpper(); //转换成大写
	}

	
	if (gpFindReplaceDlg->FindNext()) //查找下一个
	{
		if (bDown) //如果是向下搜索
		{
			if (gpos == strEdit.GetLength() - 1)
			{
				MessageBox(_T("已经向下查找到文件结尾,但没找到"), _T("查找替换"), MB_OK | MB_ICONINFORMATION);
				goto end;
			}
			gpos = strEdit.Find(strFind, gpos); //在正文字符串中查找
			if (gpos == -1)
			{
				gpos = strEdit.GetLength() - 1;
				MessageBox(_T("无法找到: ") + strRawFind);
			}
			else
			{
				m_edt.SetFocus();
				m_edt.SetSel(gpos, gpos + lenStrFind);
				gcurpos = gpos; 
				gpos = gpos + lenStrFind; //更新索引,准备下一次查找
			}
		}
		else //如果是向上搜索
		{

			if (gpos == 0)
			{
				MessageBox(_T("已经向上查找到文件开头,但没找到"), _T("查找替换"), MB_OK | MB_ICONINFORMATION);
				goto end;
			}
			wstring str = strEdit.GetBuffer(0);
			gpos = str.find_last_of(strFind, gpos); //find_last_of是反向找
			strEdit.ReleaseBuffer();
			if (gpos == -1)
			{
				gpos = 0;
				MessageBox(_T("无法找到: ") + strRawFind);
			}
			else
			{
				m_edt.SetFocus();
				m_edt.SetSel(gpos, gpos + lenStrFind);
				gcurpos = gpos;
				gpos = gpos - lenStrFind; //向后更新索引
			}
		}
		
	}
	//处理替代
	if (gpFindReplaceDlg->ReplaceCurrent()) //是否按下“替代”按钮
	{
		if (gcurpos >= 0)
		{
			m_edt.SetFocus();
			m_edt.SetSel(gcurpos, gcurpos + lenStrFind);
			m_edt.ReplaceSel(strReplace);
			m_edt.SetSel(gcurpos, gcurpos + lenStrReplace);
			gpos = gcurpos + lenStrReplace;
		}
	}
	//处理替代全部 
	if (gpFindReplaceDlg->ReplaceAll())  //是否按下“替代全部”按钮
	{
		UpdateData(TRUE);
		m_strEdit.Replace(strFind, strReplace); //开始替代
		UpdateData(FALSE);
	}
end:

	return 0;
}

(8)在开头添加代码:

#include <string>
using namespace std;

(9)保存工程并运行,运行结果如图:
查找/替换对话框的使用
查找/替换对话框的使用
查找/替换对话框的使用