15,979
社区成员
发帖
与我相关
我的任务
分享
LRESULT CFMDIDEView::OnFindReplace(WPARAM wParam,LPARAM lParam) //wParam = 0替换 ,wParam = 1查找
{
CString strText,repText;
strText=m_DlgFind->m_strFindWord; // 要查找的字符串
CString str;
CRichEditCtrl & theEdit=GetRichEditCtrl(); // RICHEDIT控件中的总的字符串
theEdit.GetWindowText(str);
int len=strText.GetLength(); // 要查找的字符串长度
long index=0,end_index=0; // 索引的起始位置 及 结束位置, 从0开始
if (wParam) // 查找对话框
{
if (m_DlgFind == NULL) // 销毁对话框 首先检查是否撤销对话框,否则可能会先执行其他操作,然后再撤销
{
m_DlgFind->DestroyWindow();
m_DlgFind=NULL;
return 0;
}
if (m_DlgFind->m_bDirection) // 向下搜索
{
theEdit.GetSel(index,end_index); //得到查询的起始与结束位置 为半闭半开区域 [index,end_index)
index=str.Find(strText,end_index); // 从上次查询的结束位置处继续往下查询
if (index!=-1) //往下搜索时,找到所要查询的子字符串
{
theEdit.SetSel(index,index+len); // 为找到的子字符串 设置选择标记
theEdit.SetFocus(); // 在找到的子字符串上,设置焦点
}
else // 往下搜索时,未找到所要查找的子字符串
{
index=str.Find(strText,0); //从文件开始处,重新查找, 可以实现当搜索到文件末尾时,点查找下一个按钮时,可以从头重新查,从而实现循环功能
if (index==-1)
{
MessageBox(L"以查找完毕,无所查内容"); //若从开始处查找,仍然找不到,则说明无此查找内容
return 0;
}
theEdit.SetSel(index,index+len); // 若从开始处查找,查询到所查内容,则为其做标记
theEdit.SetFocus();
}
}
else // 向上搜索
{
theEdit.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; //转换成源串的末尾位置索引 反串的起始位置即为源串的末尾
}
theEdit.SetSel(end_index+1-len,end_index+1); // 由结尾位置 倒推源串,其中要包含结尾位置。 SETSEL 为【)区间,所以要使位置end_index 包含之中,范围必须是setsel(,end_index+1)
theEdit.SetFocus();
}
}
else // 替换对话框
{
}
}
void CFMDIDEView::FindText( LPCTSTR pszText,BOOL bWholeWord,BOOL bCaseSen,BOOL bUp )
{
CRichEditCtrl & theEdit=GetRichEditCtrl(); // RICHEDIT控件中的总的字符串
DWORD dwOptions = 0;
if (bWholeWord)
dwOptions |= FR_WHOLEWORD;
if (bCaseSen)
dwOptions |= FR_MATCHCASE;
if (!bUp)
dwOptions |= FR_DOWN;
CHARRANGE crCurSel;
theEdit.GetSel(crCurSel);
FINDTEXTEXW ftw;
ZeroMemory(&ftw,sizeof(FINDTEXTEXW));
if (bUp) //注意,如果是向上查找的话,FINDTEXTEXW 中的chrg 应该是倒序
{
ftw.chrg.cpMin = crCurSel.cpMin ;
ftw.chrg.cpMax = 0;
}
else
{
ftw.chrg.cpMin = crCurSel.cpMax;
ftw.chrg.cpMax = -1;
}
#ifdef _UNICODE
ftw.lpstrText = pszText;
#else
USES_CONVERSION;
ftw.lpstrText = A2W(pszText);
#endif
if( -1 == theEdit.SendMessage(EM_FINDTEXTEXW,dwOptions,(LPARAM)&ftw) )
{
CString strText;
strText.Format(_T("没有找到 \" %s \" "),pszText);
MessageBox(strText);
}
else
{
theEdit.SetSel(ftw.chrgText);
theEdit.SendMessage(EM_HIDESELECTION,0,0);
}
}
//装入rich edit version 2.0
if (LoadLibrary(_T("RICHED20.DLL")) == NULL)
{
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),
MB_OK | MB_ICONERROR);
PostMessage(WM_QUIT,0,0);
return FALSE;
}
m_strClass = RICHEDIT_CLASSA; //for 2.0 class
cs.style = cs.style & (~WS_VSCROLL);
AfxInitRichEdit2();
我用的是Unicode版本,2.0,那个版本才是最新最好用的呢
int nTemp = theEdit.LineIndex(nLine);
nTemp = theEdit.LineLength(nTemp)*16+32; //缓冲区必须足够大,否则读取中文时可能会有乱码
char *achLine = new char[nTemp];
//findString = theEdit.GetSelText(); //乱码
theEdit.GetSelText(achLine);//将上一句换成这样才能得正确的字符,否则就是乱码
CString findString;
CodeSwitchForMTW(achLine,findString);//多字节转宽字符
delete achLine;
这样处理得到了正确的字符,然而这个是转为Unicode后的字符,而在查找时位置就不对了