查找/替换对话框的使用
程序员文章站
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)保存工程并运行,运行结果如图: