如何实现编辑器一样的关键字着色功能,仅求思路,请大侠指点
解决方案 »
- 在delphi中操作SQLSERVER数据恢复出错
- quickreport做的报表运行时改变字体碰到的问题
- 如何得到全屏最大化?最好是比例缩放。
- delphi版的斑竹是不是腦子壞掉了, 把“基礎類” 都刪掉了, 你看哪個版沒有“基礎類”的?
- 一个很奇怪的jpg 文件从库中取出的显示的问题,不知道其他朋友是否碰到过。
- 读取IMAGE类型的字段速度非常缓慢?(附代码)(
- deleterecords的用法????
- Flash控件大小问题?
- 如何取得应用软件的焦点!就像汉王笔一样!
- 如何判断结点在TTreeView处于第几级子层中?
- DBGrid在没有链接数据库的情况下能否进行手工编辑?
- 如何屏蔽双击放大窗体????
2。当有字符插入或删除操作时候,取得光标左右两边的最近的字符串,当然是以空格符为准分开;
3。将取得的两个字符串在关键字集合里匹配
4。根据结果着色过程大概可以这样描述,关键是1、2
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.
没有骂人的意思,大家都是常来之人,以后还要多多指教,别生气,大家都是朋友!
IF 关键字 THEN
着色
据说:Delphi的代码编辑窗口就是这么作的。
给你一个例子:
http://www.jizhimei.com/download/kbmacro.zip
找关键字比较简单,设计一个好的算法即可;
着色嘛,就是对这段字符的属性,比如color等设置。
要是老是操作数据库速度怎么办?
海德用书祖阿
呵呵
慢慢想会有办法的
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;
注意:
1。你可以在关键字集中使用查找指针,因为用户的输入单词查找是多级字典查找,这样移动指针比整个字匹配速度快;
2。查找应该在用户keypress以后,而且注意用户可能在一串字中插入一个分隔符,这时需要判断分割后的两个字符串;
3。如果关键字很长,你在匹配查找时亦可以用kls字符串匹配算法(好像是这个名字,数据结构的书上有介绍)
注意:
1。你可以在关键字集中使用查找指针,因为用户的输入单词查找是多级字典查找,这样移动指针比整个字匹配速度快;
2。查找应该在用户keypress以后,而且注意用户可能在一串字中插入一个分隔符,这时需要判断分割后的两个字符串;
3。如果关键字很长,你在匹配查找时亦可以用kls字符串匹配算法(好像是这个名字,数据结构的书上有介绍)
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;
以上是我的思路及简单的代码,请不要仍鸡蛋,深表谢谢!!!