如何实现编辑器一样的关键字着色功能,仅求思路,请大侠指点

解决方案 »

  1.   

    To U2M  呵呵,你说的也太简单点了吧!俺想不出来什么高效的方法,帮你UP了,呵呵呵呵!
      

  2.   

    多谢FrameSniper老兄仗义执言,唉,别跟他们生气,看起来简单的问题并不简单的道理他们看来是不懂啊
      

  3.   

    很复杂吗?以richedit为例1。取得光标的位置;
    2。当有字符插入或删除操作时候,取得光标左右两边的最近的字符串,当然是以空格符为准分开;
    3。将取得的两个字符串在关键字集合里匹配
    4。根据结果着色过程大概可以这样描述,关键是1、2
      

  4.   

    To U2M  呵呵,骂人?!!!算了,我怕你...我可不想犯在水圆犯的错误了!!!!
      

  5.   

    Just like VBscipt in html , there is a simple function
    replace(text,"str","<b>str</b>")
    so you can read "str" in text with bold style in browser.I think you may do something like it.
      

  6.   

    To  FrameSniper
    没有骂人的意思,大家都是常来之人,以后还要多多指教,别生气,大家都是朋友!
      

  7.   

    To SethDelphi  俺感觉你的想法很新奇,但有点不太明白,完全是感觉,可以把的方法说的详细点吗??!!  这种功能我以前也考虑过,但没有任何结果,所以严重关注!!!!!!!!
      

  8.   

    就是用delphi提供的brower控件做。这样控制起来还算容易,至少比richedit要容易。
      

  9.   

    没什么思路啊
    IF 关键字 THEN
    着色
      

  10.   

    楼主 : 这个东西我有个可行的思路。用勾子技术 ,监视Canvas的TextOut的调用,如果发现是自己的那个控件在调用TextOut,然后就判断是否是关键字,如果是关键字,那么就作相应的样式变化。
    据说:Delphi的代码编辑窗口就是这么作的。
      

  11.   

    呵呵,楼主说我乱说,5555
    给你一个例子:
    http://www.jizhimei.com/download/kbmacro.zip
      

  12.   

    kiboisme老兄,我说的不是你,我是说那些就简单的搞些if then就一位能解决问题的人,实在对不起
      

  13.   

    搂主看看我的想法:我在ONKEYDOWN的事件里处理,先遍历关键字表,然后根据关键字的长度,从当前光标位置向前搜索,如果匹配的话,就进行着色了!!!呵呵,有什么更好的建议清大家多多留言!!!!
      

  14.   

    关键字着色,楼上都说了,但真正的语法着色,还要涉及数值常量、字符串常量,多行注释,多行宏等等,比较复杂,可以下一个MWEdit或SynEdit,里面有源代码,参考参考
      

  15.   

    大家不妨考虑 kiboisme(还是铁棒.....针) 的想法,确实很有建设性。我正在考虑,希望大家不吝赐教另外,对此问题,讨论结束后,我还会再追加500分给大家,谢谢!
      

  16.   

    对YAMABACK(CODE,CODE,CODE……) 的补充:
    找关键字比较简单,设计一个好的算法即可;
    着色嘛,就是对这段字符的属性,比如color等设置。
      

  17.   

    hehe 
    要是老是操作数据库速度怎么办?
    海德用书祖阿
    呵呵
    慢慢想会有办法的
      

  18.   

    使用开源的SynEdit控件组,VCL的。http://sourceforge.net/projects/synedit/至于思路,你去看他源代码吧
      

  19.   

    监控,比如Memo中的输入,把当前值存入一个字符串变量中,再与事先定义的关键字比较,是,则将Memo中该字符串改色
      

  20.   

    Memo中无法将某个字符串改色。除非是用RichEdit。但是还是推荐使用SynEdit
      

  21.   

    用RICHEDIT,我做了使关键字大写黑体的东东,供参考:
    CONST
      maxk = 14;
      maxf = 8;
      maxf1 = 8;
      keyword: ARRAY[1..maxk] OF STRING = ('BEGIN', 'END', 'DECLARE', 'IF', 'THEN', 'ELSE', 'ENDIF', 'FOR', 'TO', 'DO', 'NEXT', 'EACH', 'SQL-', 'SOURCE');
      funword: ARRAY[1..maxf] OF STRING = ('AVG', 'SUM', 'CNT', 'MAX', 'MIN', 'MID{s;l}', 'VAL', 'MID{');
      funword1: ARRAY[1..maxf1] OF STRING = ('.AVG', '.SUM', '.CNT', '.MAX', '.MIN', '.MID{s;l}', '.VAL', '.MID{');
    IMPLEMENTATION
    {$R *.DFM}FUNCTION TForm1.foundstr(str: STRING; x: integer;
      a: ARRAY OF STRING): boolean;
    VAR
      i: integer;
    BEGIN
      FOR i := 0 TO x - 1 DO
        IF str = a[i] THEN
        BEGIN
          Result := true;
          Break;
        END
        ELSE
          Result := false; ///{endfor}
    END;PROCEDURE TForm1.FormCreate(Sender: TObject);
    BEGIN
      isent := false;
      RichEdit1.Focused;
    END;PROCEDURE TForm1.RichEdit1KeyPress(Sender: TObject; VAR Key: Char);
    BEGIN
      IF key IN ['.'] THEN
      BEGIN
        z := 1;
        isdd := true; // 是否是'.'
      END
      ELSE
      BEGIN
        z := 0;
        isdd := false;
      END;
      IF key IN [#13] THEN
      BEGIN
        isent := true; //是否是ENTER
      END;END;PROCEDURE TForm1.RichEdit1KeyUp(Sender: TObject; VAR Key: Word;
      Shift: TShiftState);
    VAR
      i, j, x, y, js, js1, js2, col, row, start, last, l1, l2: integer;
      str1, entstr, emp: STRING;
      bz, bz1, bz11: boolean;
    BEGIN
      start := RichEdit1.SelStart;
      last := RichEdit1.SelStart; //保留光标位置
      row := SendMessage(RichEdit1.Handle, EM_LINEFROMCHAR, -1, 0); //行
      col := RichEdit1.SelStart - SendMessage(RichEdit1.Handle, EM_LINEINDEX, -1, 0); //光标所在列位置
      entstr := RichEdit1.Lines[row - 1];
      l1 := length(entstr);
      l2 := l1 - length(TrimLeft(entstr));
      emp := ' ';
      IF isent THEN
        IF (col = 0) AND (row > 0) THEN
        BEGIN
          FOR i := 1 TO l2 DO
          BEGIN
            RichEdit1.SetSelTextBuf(pchar(emp));
            isent := false;
          END;
        END;
      IF col = 0 THEN exit;
      str := RichEdit1.Lines[row];
      x := col;
      js1 := 0;
      js := 1; //计数   下面循环中要大于保留字的最大长度
      WHILE (x > 0) AND ((str[x] <> ' ') AND (str[x - z] <> '.')) AND (js < 20) DO
      BEGIN
        inc(js);
        dec(x);
        inc(js1);
      END;
      js := 1;
      y := col;
      js2 := 0;
      WHILE (y <= Length(str)) AND ((str[y] <> ' ') AND (str[y] <> '.')) AND (js < 20) DO
      BEGIN
        inc(js);
        inc(y);
        inc(js2);
      END;
      str1 := UpperCase(trim(copy(str, x, y - x + z)));
      bz := foundstr(str1, maxk, keyword); //   检索字符串是否为关键字
      bz1 := foundstr(str1, maxf, funword); //  检索字符串是否为函数名
      bz11 := foundstr(str1, maxf1, funword1);
      ////////////////////////////
      IF bz THEN //bz为关键字标志。将关键字转变为黑体,大写
      BEGIN
        RichEdit1.SelStart := start - js1;
        RichEdit1.SelLength := length(str1);
        RichEdit1.SelAttributes.Style := [fsbold];
        RichEdit1.SetSelTextBuf(pchar(str1));
        RichEdit1.SelAttributes.Style := [];
      END; // {endif}
      IF bz1 THEN //bz1为函数标志。将函数名转变为大写
      BEGIN
        RichEdit1.SelStart := start - js1;
        RichEdit1.SelLength := length(str1);
        RichEdit1.SelAttributes.Style := [];
        RichEdit1.SetSelTextBuf(pchar(str1));
      END; // {endif}
      IF bz11 THEN // bz11为函数标志。将函数名转变为大写
      BEGIN
        RichEdit1.SelStart := start - js1 - 1;
        RichEdit1.SelLength := length(str1) + 1;
        RichEdit1.SelAttributes.Style := [];
        RichEdit1.SetSelTextBuf(pchar(str1));
      END;
      ////////////////////////////////////
      RichEdit1.SelStart := last;
      RichEdit1.SelAttributes.Style := [];
      RichEdit1.SelLength := 0;
      exit;
    END;PROCEDURE TForm1.N1Click(Sender: TObject);
    BEGIN
      Panel3.Visible := true;
      Edit1.SetFocus;
    END;PROCEDURE TForm1.Edit1KeyPress(Sender: TObject; VAR Key: Char);
    VAR
      LineIndex: integer;
    BEGIN
      IF key IN [#13] THEN
      BEGIN
        IF Edit1.Text = '' THEN
        BEGIN
          Panel3.Visible := false;
          RichEdit1.SetFocus;
          exit;
        END
        ELSE
        BEGIN
          LineIndex := StrToInt(Edit1.Text);
        END;
        IF LineIndex < 0 THEN
        BEGIN
          LineIndex := 0;
        END
        ELSE
          IF LineIndex > RichEdit1.Lines.Count - 1 THEN
          BEGIN
            LineIndex := RichEdit1.Lines.Count - 1;
          END;
        RichEdit1.SelStart := SendMessage(RichEdit1.Handle, EM_LINEINDEX, LineIndex, 0);
        RichEdit1.SelLength := Length(RichEdit1.Lines[LineIndex]);
        RichEdit1.SetFocus;
        Panel3.Visible := false;
      END
      ELSE
      BEGIN
        IF key IN [#27] THEN
        BEGIN
          Panel3.Visible := false;
          RichEdit1.SetFocus;
        END;
        IF NOT (key IN [#48..#57, #8, #13]) THEN
        BEGIN
          key := #0;
        END;
      END;
    END;
      

  22.   

    StringReplace function + RechEdit Control
      

  23.   

    用hook?没有那么夸张,只需要判断用户最后键入的字,向前取分隔符(空格、tab等),然后先后取分隔符,两个分隔符之间的字在关键字集中进行查找.
    注意:
    1。你可以在关键字集中使用查找指针,因为用户的输入单词查找是多级字典查找,这样移动指针比整个字匹配速度快;
    2。查找应该在用户keypress以后,而且注意用户可能在一串字中插入一个分隔符,这时需要判断分割后的两个字符串;
    3。如果关键字很长,你在匹配查找时亦可以用kls字符串匹配算法(好像是这个名字,数据结构的书上有介绍)
      

  24.   

    用hook?没有那么夸张,只需要判断用户最后键入的字,向前取分隔符(空格、tab等),然后先后取分隔符,两个分隔符之间的字在关键字集中进行查找.
    注意:
    1。你可以在关键字集中使用查找指针,因为用户的输入单词查找是多级字典查找,这样移动指针比整个字匹配速度快;
    2。查找应该在用户keypress以后,而且注意用户可能在一串字中插入一个分隔符,这时需要判断分割后的两个字符串;
    3。如果关键字很长,你在匹配查找时亦可以用kls字符串匹配算法(好像是这个名字,数据结构的书上有介绍)
      

  25.   

    定义一个关键字字符串数组KeyWord: array of strng;
    procedure Tform1.formkeypress(sender: Tobject; var key: char);
    var
      str: string;
      i: integer;
    beign
      if key=space then
      begin
        for i:=0 to keycount-1 do  //遍历数组;
        begin
          if str=keyword[i] then
          begin 
            对str着色;
            并把str替换到原来的输入位置;
            str:='';
          then;
        end;
      end
      else if key<>各种功能键 then
        str:=str+key;
    end;
       
    以上是我的思路及简单的代码,请不要仍鸡蛋,深表谢谢!!!