首先,非常感谢~~~
最好是这方面的资料或源代码。
谢谢!!
我这里有点类似的资料,你看看有没有用。
方法一、
这段代码能查找关键字并着色,但注释不好办
void TfrmMain::SearchKeyWord(AnsiString sFindtext)
{
//如果为空,则返回
if(sFindtext.IsEmpty())
return;
if(txtQuery->Text.IsEmpty())
return;
int FoundAt,StartPos,ToEnd;
//得到搜索起点位置
while(FoundAt != -1)
{
StartPos = txtQuery->SelStart + txtQuery->SelLength;
//得到搜索终点位置
ToEnd = txtQuery->Text.Length() - StartPos;
//得到焦点
txtQuery->SetFocus();
//搜索
FoundAt = txtQuery->FindText(sFindtext,StartPos,ToEnd,TSearchTypes() << stMatchCase);
//得到焦点
txtQuery->SetFocus();
txtQuery->SelStart = FoundAt;
txtQuery->SelLength = sFindtext.Length();
txtQuery->SelAttributes->Color = clNavy;
txtQuery->SelStart = FoundAt + sFindtext.Length();
}
}
方法二、我在大文本测试的时候,速度还不是太理想,你自己再加加工吧。
void TfrmMain::SearchAllKeyWord(TRichEdit *FindTxt)
{
AnsiString sFileContent = FindTxt->Text;
AnsiString NewWord,OldWord;
int Startnums = 0;
unsigned long iFileLen,StartPos,EndPos;
bool SingerComment = false,MutliComment = false,SingeString = false;
//文件长度不能超过 unsigned long定义的长度
iFileLen = sFileContent.Length();
char cWord[31];
for(unsigned long i=1;i<=iFileLen;i++)
{
if(!SingerComment && !MutliComment) //如果不是注释状态,就检查是否开始注释
if(i+1<=iFileLen)
if(sFileContent[i] == / && sFileContent[i+1] == /) //如果单行注释开始
{
StartPos = i; //记录注释开始位置
SingerComment = true; //记录注释标志为真
continue; //不再进行别的检查
}
if(SingerComment) //如果是单行注释状态,就检查是否开始注释结束
{
if(sFileContent[i] == \n || sFileContent[i] == \r) //如果单行注释结束
{
EndPos = i - 1; //记录注释结束位置
SingerComment = false; //记录注释标志为假,非注释状态
FindTxt->SelStart = StartPos - 1; //着色
FindTxt->SelLength = EndPos - StartPos + 1;
FindTxt->SelAttributes->Style = FindTxt->SelAttributes->Style << fsItalic;
FindTxt->SelAttributes->Color = clGreen;
}
continue; //不进行以下操作
}
if(!MutliComment) //如果不是多行注释状态,就检查是否开始注释
if(i+1<=iFileLen)
if(sFileContent[i] == / && sFileContent[i+1] == *) //如果注释开始
{
StartPos = i; //记录注释开始位置
MutliComment = true; //记录注释标志为真
continue; //不再进行别的检查
}
if(MutliComment) //如果是多行注释状态,就检查是否开始注释结束
{
if(i+1<=iFileLen)
if(sFileContent[i] == * && sFileContent[i+1] == /) //如果多行注释结束
{
EndPos = i + 1; //记录注释结束位置
MutliComment = false; //记录注释标志为假,非注释状态
FindTxt->SelStart = StartPos - 1; //着色
FindTxt->SelLength = EndPos - StartPos + 1;
FindTxt->SelAttributes->Style = FindTxt->SelAttributes->Style << fsItalic;
FindTxt->SelAttributes->Color = clGreen;
i++;
}
continue; //不进行以下操作
}
if(!SingeString) //如果不是字符串
if(sFileContent[i] == 39) //如果字符串开始
{
StartPos = i; //记录字符串开始位置
SingeString = true; //记录字符串标志为真
continue; //不再进行别的检查
}
if(SingeString)
{ //如果是字符串,就检查是否结束
if(sFileContent[i] == 39) //结束
{
EndPos = i + 1; //记录字符串结束位置
SingeString = false; //记录字符串标志为假,非字符串状态
FindTxt->SelStart = StartPos - 1; //着色
FindTxt->SelLength = EndPos - StartPos + 1;
FindTxt->SelAttributes->Color = clTeal;
}
continue;
} //不进行以下操作
//数字
if(sFileContent[i] >= 48 && sFileContent[i] <= 57) //数字
{
FindTxt->SelStart = i - 1; //着色
FindTxt->SelLength = 1;
FindTxt->SelAttributes->Color = clBlue;
}
//检查关键字,假定关键字是字母或下划线或#或$或数字
if(sFileContent[i] >= 97 && sFileContent[i] <= 122 || sFileContent[i] >= 65 && sFileContent[i] <= 90 \
|| sFileContent[i] == 95 || sFileContent[i] == 35 || sFileContent[i] == 36 \
|| sFileContent[i] >= 48 && sFileContent[i] <= 57) //字母或下划线或#或$或数字
//检查关键字,假定关键字长度不会超过30个字符,如果大于30个,取前30个
{
if(Startnums<30)
cWord[Startnums] = sFileContent[i];
Startnums++;
}
else //假如不是字母或下划线或#或$或数字,则假定取一个单词取完成
{
if(Startnums > 1) //如果取到的字符长度大于1,认为是单词,否则,可能是符号或空格,不参加比对
{
if(Startnums<31) //在取到的单词后并一个结束符号
cWord[Startnums]=\0;
NewWord = cWord;
NewWord = NewWord.UpperCase().Trim(); //得到取到的单词
for(int j = 0;j<1000;j++) //和关键字列表比对,其中KeyWord[1000][30]是一个关键字数组,由用户初试化
{
OldWord = KeyWord[j];
if(OldWord.IsEmpty()) //如果关键字比对完了
break;
OldWord = OldWord.UpperCase().Trim();
if(NewWord == OldWord) //如果是关键字,着色并退出比对
{
FindTxt->SelStart = i - Startnums - 1;
FindTxt->SelLength = Startnums;
FindTxt->SelAttributes->Style = FindTxt->SelAttributes->Style << fsBold;
FindTxt->SelAttributes->Color = clNavy;
break;
}
}
}
Startnums=0;
}
}
}
----------------------
以上部分,还有可以加速的地方,如比对关键字的地方。可以用更好的哈希算法
原理,先选择加亮的字符,然后设置RichEdit1->SelAttributes下的属性。比如,需要将
RichEdit1的第10到第16个字符加亮,使用下面的代码:
int nStart, nLength;
//保存当前选择的字符的位置和长度
nStart = RichEdit1->SelStart;
nLength = RichEdit1->SelLength;
RichEdit1->SelStart = 10;
RichEdit1->SelLength = 7;
RichEdit1->SelAttributes->Color = clBlue;
RichEdit1->SelAttributes->Style = TFontStyles()<<fsBold;
//恢复之前的选择的字符
RichEdit1->SelStart = nStart;
RichEdit1->SelLength = nLength;
study && talk
我以前也曾经想做过语法高亮,
但发现只是用Trichedit是比较麻烦的,
一般优秀的语法高亮控件都是整个richedit重写的,
有解决的一种捷径:就是只高亮用户看得到的区域!
但是对于注释的确很难解决,而且还有很多其他要求,
如续行符号
最后我觉得如果是编写语法高亮来练一练编程是可以的,
但是要编出来用就不建议了,因为网上有很多好的控件啦
‘软件’页面里有这样的控件。
http://www.csdn.net/cnshare/soft/4/4604.shtm