一个小问题,关于richedit的着色问题,各位来看看

liu9527 2005-04-15 09:50:16
我想在一个richedit中对文本内容进行着色处理,具体如同editplus,每行的开始显示行号,行号统一为灰色,其后的内容可能根据情况为不同的颜色;
对于小量的数据,处理起来没有问题,但对于大量的数据,可能只有5000行,那么处理起来速度就很慢;我在程序中的处理思路如下:
1;
richedit1.loadfromFile(file1);
for i:=0 to richedit.count-1 do
begin
//对每行进行着色处理,大致语句如下
richedit.SelAttributes.Color:=clBlue;
richedit.SelStart:=iPos;
richedit.SelLength:=iTxtLen

....
edn
2:
for i:=0 to stringlist.count-1 do
begin
richedit.lines.add(stringlist[i]);
//对每行进行着色处理,大致语句如下
richedit.SelAttributes.Color:=clBlue;
richedit.SelStart:=iPos;
richedit.SelLength:=iTxtLen
....
edn
现在发现问题的关键是在每行的数据加入及着色处理上,很费时间,请各位提供好的思路及算法?
...全文
191 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
liu9527 2005-04-21
  • 打赏
  • 举报
回复
即然引不起兴趣,那我就结贴了
liu9527 2005-04-20
  • 打赏
  • 举报
回复
写到线程里?什么意思,
对于显示部分,我试过在线程中显示,但没有什么大的改进,速度依然慢,
对于你的提议,能否给个明确的方向或是什么
liu9527 2005-04-18
  • 打赏
  • 举报
回复
目前问题没有找到好的方法,但我改进了程序中的一些处理步骤,现在速度还可以接受;
对于显示某行的问题,我没有找到方法,目前我的办法是从第一行起,计算每行的长度,以便定位,对于要设置颜色的行进行处理,其它的不进行处理.
纯冰糖 2005-04-18
  • 打赏
  • 举报
回复
写到线程里吧,需要处理一下刷新问题的
herman~~ 2005-04-16
  • 打赏
  • 举报
回复
关注
Heyongfeng 2005-04-16
  • 打赏
  • 举报
回复
关注
太空11 2005-04-16
  • 打赏
  • 举报
回复
帮顶。。。。。。。。
zhuangbx220 2005-04-15
  • 打赏
  • 举报
回复
private
{ Private declarations }
ClientHandle:integer;
FClientInstance, FPrevClientProc : TFarProc;
procedure ClientWndProc(var Message: TMessage);



procedure TForm1.ClientWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_VSCROLL:
begin { 干您的好事,处理WM_VSCROLL消息,垂直滚动条变化消息 }
Memo1.Lines.Add(format('x:%d y:%d wParam:%d lParam:%d',
[RichEdit1.CaretPos.X,RichEdit1.CaretPos.Y,Message.wParam,Message.lParam]));
//在这里着色,只处理显示的行,这样就快了^_^
end;
WM_HSCROLL:
begin { 干您的好事,处理WM_HSCROLL消息,水平滚动条变化消息 }
end;
end;
Message.Result:= CallWindowProc(FPrevClientProc, ClientHandle,
Message.Msg,Message.wParam,Message.lParam);
end;

ClientHandle:=RichEdit1.Handle;
FClientInstance := MakeObjectInstance(ClientWndProc);
FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));

end;
pengxuan 2005-04-15
  • 打赏
  • 举报
回复
帮楼主看了看还自己写了一个例子,想不出更好的办法来.待高手解决
飞天揽月 2005-04-15
  • 打赏
  • 举报
回复
参考]
随着网络的深入应用,各种软件都增加了一些网络功能,常用的文本编辑器也出现了这样的一种功能,当你把一个网址输入完毕后,网址由黑色变成了带下划线的宝蓝色,点击之后,你的缺省Web浏览器将会被启动,显示出该URL所标识的网站内容;而如果你输入的是“mailto:webmaster@yesky.com”那么你的缺省电子邮件程序将被打开,这样你就能通过一个使用文本编辑器来发送电子邮件了。
  这个看似神奇的功能,不需用第三方VCL组件就能搞定(据网上的“大牛”们说,第三方组件用多了,大脑会因长期得不到思考而逐渐退化成大猩猩的程度,所以尽量少用)。TRichEidt是Delphi提供的一个非常有用的VCL组件(你可以在Delphi的组件面板的Win32标签页中找到它),它提供了一个文本编辑程序的大部分的功能,甚至还可以对段落进行格式化、改变文本的颜色,这样一来,你完全可以用它制作一个类似Windows操作系统自带的写字板程序,这次我们靠的就是它。

  要实现超级链接的功能,首先必须解决如何在TRichRdit中对URL、Mailto等进行检测的问题,还是以实例开始吧,新建一个Delphi工程,在空白的Form上摆放两个TRichRdit组件,组件的名字就用缺省的名字RichEdit1和RichRdit2,对URL的感知功能的实现思路是:

  1、发送一个消息(EM_GETEVENTMASK)给RichEdit组件,获取事件模板(EventMask),它将会指定哪一个消息通知(notification)将被发送到给父窗口。

  2、发送一个包含ENM_LINK标志的EM_SETEVENTMASK消息给EichEdit,ENM_LINK将被包含在Mask中,当鼠标单击ULR时EN_LINK消息将被发送。

  3、发送EM_AUTOURLDETECT消息给RichEdit,EM_AUTOURLDETECT消息将会自动检测URL。
然后,我们来解决URL高亮显示的问题。

  在我们刚刚建立的程序中找到RichEdit1组件,进入它的OnCreate事件,在该事件中加入一个自定义的InitRichEditURLDetection过程,以便能够在程序启动时就触发它;RichEdit2组件的OnCreate事件则不加入InitRichEditURLDetection过程,让两者比较一下效果,代码如下所示:

//这个是我们自定义的InitRichEditURLDetection过程
//它是最关键的一步
procedure TForm1.InitRichEditURLDetection(RE: TRichEdit);
 var
  mask: Word;
 begin
  mask := SendMessage(RE.Handle, EM_GETEVENTMASK, 0, 0);
  SendMessage(RE.Handle, EM_SETEVENTMASK, 0, mask or ENM_LINK);
  SendMessage(RE.Handle, EM_AUTOURLDETECT, Integer(True), 0);
 end;
 //这是FormCreate事件,它加入了我们自定义的过程
 //使得程序一运行就出现我们想要实现的效果
 procedure TForm1.FormCreate(Sender: TObject);
  var
   s: string;
  begin
   InitRichEditURLDetection(RichEdit1);

   s:='http://www.yesky.com' + #13#10 +
   'mailto:software@chinabyte.com';
   RichEdit1.Text := s;

   s:= 'http://www.yesky.com' + #13#10 +
   'mailto:software@chinabyte.com';
   RichEdit2.Text := s
end;

  最后我们来实现鼠标单击后自动调用浏览器或邮件程序的功能,我们用覆盖(Override)Form的WndProc方法来捕获EN_LINK消息,然后我们用ShellExecute过程来启动缺省的浏览器,代码如下所示:

//Form的WndProc过程
procedure TForm1.WndProc(var Msg: TMessage);
 var
  p: TENLink;
  sURL: string;
  CE : TRichEdit;
 begin
  if (Msg.Msg = WM_NOTIFY) then
  begin
   if (PNMHDR(Msg.lParam).code = EN_LINK) then
   begin
    p := TENLink(Pointer(TWMNotify(Msg).NMHdr)^);
    if (p.Msg = WM_LBUTTONDOWN) then
    begin
    try
     CE := TRichEdit(Form1.ActiveControl);
     SendMessage(CE.Handle, EM_EXSETSEL, 0, Longint(@(p.chrg)));
     sURL := CE.SelText;
     ShellExecute(Handle, 'open', PChar(sURL), 0, 0, SW_SHOWNORMAL);
    except
    end;
   end;
  end;
 end;
 inherited;
end;

  主要的代码都列出来了,最后程序的效果如下图,由两个Richedit的比较不难看出区别。在看到别人程序中的一些技术亮点的时候,不妨多思考一下如何用现有的组件来解决,这也是一个提高水平的好机会,一味等待第三方VCL组件,可能真的会使你成为一只大猩猩的。
liu9527 2005-04-15
  • 打赏
  • 举报
回复
zhuangbx220(星),谢谢你的方法

如何为richedit的某一行指定颜色,比如,我现在有一个列表,值为某一行什么颜色,某一行什么颜色,如何根据列表指定richedit某一地的颜色?

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧