首先声明:1、我的程序必需要用RichEdit,不能用Memo 2、程序要一行一行的向RichEdit里添加文本。 我写的程序突然遇到一个问题,那就是RichEdit遇到希腊字母、俄文字母都会出现“RichEdit line insertion error”这样的错误。演示程序代码如下: procedure TForm1.Button2Click(Sender: TObject); var i:integer; begin for i:=0 to RichEdit2.Lines.Count-1 do RichEdit1.Lines.Add(RichEdit2.lines.Strings[i]); end;RichEdit2里面有下面内容: aaa β bbb程序运行到β就出错,换成其他希腊字母也一样错误,如:αβγδεζηθι请高手指教,在线等待
目前看到的信息是 --------------------------- Debugger Exception Notification --------------------------- Project Project1.exe raised exception class EOutOfResources with message 'RichEdit line insertion error'. Process stopped. Use Step or Run to continue. --------------------------- OK Help --------------------------- 这个是语言方面的异常(Language Exceptions),目前尚未找到原因,其实这个异常可以屏蔽 procedure TForm1.Button2Click(Sender: TObject); var i:integer; begin try for i:=0 to RichEdit2.Lines.Count-1 do RichEdit1.Lines.Add(RichEdit2.lines.Strings[i]); except end; 如果找不出原因用这个屏蔽一下也可以救急的,这是一个很好的问题,本人收藏之 end;
呵呵,关注。 顺便加问一个问题,RichEdit的FindText函数不知道是不是不太支持中文,我用其查找中文字符时,有时成功,有时不成功,测试了很久都找不到原因,请问大侠们用FindText有什么注意事项?另外,我是用HELP中的代码进行测试的。procedure TForm1.Button1Click(Sender: TObject);begin FindDialog1.Position := Point(RichEdit1.Left + RichEdit1.Width, RichEdit1.Top); FindDialog1.Execute; end;procedure TForm1.FindDialog1Find(Sender: TObject); var FoundAt: LongInt; StartPos, ToEnd: Integer; begin with RichEdit1 do begin { begin the search after the current selection if there is one } { otherwise, begin at the start of the text } if SelLength <> 0 then StartPos := SelStart + SelLength else StartPos := 0; { ToEnd is the length from StartPos to the end of the text in the rich edit control } ToEnd := Length(Text) - StartPos; FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd, [stMatchCase]); if FoundAt <> -1 then begin SetFocus; SelStart := FoundAt; SelLength := Length(FindDialog1.FindText); end; end; end;先谢了!
这些RichEdit的问题与程序没有关系,是这个VCL控件的原因 怎么解决呢? 就楼上的问题可以先判断一下操作系统的版本,然后根据不同的版本进行FindText操作 或者在Win2000下这样做if FoundAt <> -1 then begin SetFocus; SelStart := FoundAt - 2;//这是VCL的Bug if SelStart < 0 then SelStart := 0;// SelLength := Length(FindDialog1.FindText); end;
如果SelStart 你允许< 0 ,可以先设一临时的变量进行操作 iTemp := FoundAt - 2; if itemp = 0 then itemp := 0; SelStart := iTemp;
procedure TRichEditStrings.Insert(Index: Integer; const S: string); var L: Integer; Selection: TCharRange; Fmt: PChar; Str: string; begin if Index >= 0 then begin Selection.cpMin := SendMessage(RichEdit.Handle, EM_LINEINDEX, Index, 0); if Selection.cpMin >= 0 then Fmt := '%s'#13#10 else begin Selection.cpMin := SendMessage(RichEdit.Handle, EM_LINEINDEX, Index - 1, 0); if Selection.cpMin < 0 then Exit; L := SendMessage(RichEdit.Handle, EM_LINELENGTH, Selection.cpMin, 0); if L = 0 then Exit; Inc(Selection.cpMin, L); Fmt := #13#10'%s'; end; Selection.cpMax := Selection.cpMin; SendMessage(RichEdit.Handle, EM_EXSETSEL, 0, Longint(@Selection)); Str := Format(Fmt, [S]); SendMessage(RichEdit.Handle, EM_REPLACESEL, 0, LongInt(PChar(Str))); if RichEdit.SelStart <> (Selection.cpMax + Length(Str)) then raise EOutOfResources.Create(sRichEditInsertError); //<<<<<<<<<<<<<<<<<<<<这里跳出的错误 end; end;RichEdit1.0的问题 用RichEdit2.0可以解决//////////// //如下代码是通过修改内存代码跳转,实现 //在Delphi6+Win2K调试通过 Exit; //<--相当于在此加Exit; if RichEdit.SelStart <> (Selection.cpMax + Length(Str)) then raise EOutOfResources.Create(sRichEditInsertError); //<<<<<<<<<<<<<<<<<<<<这里跳出的procedure TForm1.Button1Click(Sender: TObject); begin RichEdit1.Lines.Add('β'); end;procedure TForm1.FormCreate(Sender: TObject); const vJnzCode: array[0..1] of Byte = ($75, $1F); //JNZ $1F var vPointer: Integer; vProcess: THandle; vNumberOfBytesRead: DWORD; vOldProtect: DWORD; begin Pointer(vPointer) := RichEdit1.Lines.ClassType; Inc(vPointer, $3FB); vProcess := OpenProcess(PROCESS_ALL_ACCESS, True, GetCurrentProcessId); try VirtualProtectEx(vProcess, Pointer(vPointer), SizeOf(vJnzCode), PAGE_EXECUTE_READWRITE, @vOldProtect); WriteProcessMemory(vProcess, Pointer(vPointer), @vJnzCode[0], SizeOf(vJnzCode), vNumberOfBytesRead); VirtualProtectEx(vProcess, Pointer(vPointer), SizeOf(vJnzCode), vOldProtect, @vOldProtect); finally CloseHandle(vProcess); end; end;
2、程序要一行一行的向RichEdit里添加文本。
我写的程序突然遇到一个问题,那就是RichEdit遇到希腊字母、俄文字母都会出现“RichEdit line insertion error”这样的错误。演示程序代码如下:
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
for i:=0 to RichEdit2.Lines.Count-1 do
RichEdit1.Lines.Add(RichEdit2.lines.Strings[i]);
end;RichEdit2里面有下面内容:
aaa
β
bbb程序运行到β就出错,换成其他希腊字母也一样错误,如:αβγδεζηθι请高手指教,在线等待
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EOutOfResources with message 'RichEdit line insertion error'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
这个是语言方面的异常(Language Exceptions),目前尚未找到原因,其实这个异常可以屏蔽
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
try
for i:=0 to RichEdit2.Lines.Count-1 do
RichEdit1.Lines.Add(RichEdit2.lines.Strings[i]);
except
end;
如果找不出原因用这个屏蔽一下也可以救急的,这是一个很好的问题,本人收藏之
end;
顺便加问一个问题,RichEdit的FindText函数不知道是不是不太支持中文,我用其查找中文字符时,有时成功,有时不成功,测试了很久都找不到原因,请问大侠们用FindText有什么注意事项?另外,我是用HELP中的代码进行测试的。procedure TForm1.Button1Click(Sender: TObject);begin
FindDialog1.Position := Point(RichEdit1.Left + RichEdit1.Width, RichEdit1.Top);
FindDialog1.Execute;
end;procedure TForm1.FindDialog1Find(Sender: TObject);
var
FoundAt: LongInt;
StartPos, ToEnd: Integer;
begin
with RichEdit1 do
begin
{ begin the search after the current selection if there is one }
{ otherwise, begin at the start of the text }
if SelLength <> 0 then StartPos := SelStart + SelLength
else StartPos := 0; { ToEnd is the length from StartPos to the end of the text in the rich edit control } ToEnd := Length(Text) - StartPos; FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd, [stMatchCase]);
if FoundAt <> -1 then
begin
SetFocus;
SelStart := FoundAt;
SelLength := Length(FindDialog1.FindText);
end;
end;
end;先谢了!
怎么解决呢?
就楼上的问题可以先判断一下操作系统的版本,然后根据不同的版本进行FindText操作
或者在Win2000下这样做if FoundAt <> -1 then
begin
SetFocus;
SelStart := FoundAt - 2;//这是VCL的Bug
if SelStart < 0 then SelStart := 0;//
SelLength := Length(FindDialog1.FindText);
end;
iTemp := FoundAt - 2;
if itemp = 0 then itemp := 0;
SelStart := iTemp;
var
L: Integer;
Selection: TCharRange;
Fmt: PChar;
Str: string;
begin
if Index >= 0 then
begin
Selection.cpMin := SendMessage(RichEdit.Handle, EM_LINEINDEX, Index, 0);
if Selection.cpMin >= 0 then Fmt := '%s'#13#10
else begin
Selection.cpMin :=
SendMessage(RichEdit.Handle, EM_LINEINDEX, Index - 1, 0);
if Selection.cpMin < 0 then Exit;
L := SendMessage(RichEdit.Handle, EM_LINELENGTH, Selection.cpMin, 0);
if L = 0 then Exit;
Inc(Selection.cpMin, L);
Fmt := #13#10'%s';
end;
Selection.cpMax := Selection.cpMin;
SendMessage(RichEdit.Handle, EM_EXSETSEL, 0, Longint(@Selection));
Str := Format(Fmt, [S]);
SendMessage(RichEdit.Handle, EM_REPLACESEL, 0, LongInt(PChar(Str)));
if RichEdit.SelStart <> (Selection.cpMax + Length(Str)) then
raise EOutOfResources.Create(sRichEditInsertError); //<<<<<<<<<<<<<<<<<<<<这里跳出的错误
end;
end;RichEdit1.0的问题
用RichEdit2.0可以解决////////////
//如下代码是通过修改内存代码跳转,实现
//在Delphi6+Win2K调试通过
Exit; //<--相当于在此加Exit;
if RichEdit.SelStart <> (Selection.cpMax + Length(Str)) then
raise EOutOfResources.Create(sRichEditInsertError); //<<<<<<<<<<<<<<<<<<<<这里跳出的procedure TForm1.Button1Click(Sender: TObject);
begin
RichEdit1.Lines.Add('β');
end;procedure TForm1.FormCreate(Sender: TObject);
const
vJnzCode: array[0..1] of Byte = ($75, $1F); //JNZ $1F
var
vPointer: Integer;
vProcess: THandle;
vNumberOfBytesRead: DWORD;
vOldProtect: DWORD;
begin
Pointer(vPointer) := RichEdit1.Lines.ClassType;
Inc(vPointer, $3FB); vProcess := OpenProcess(PROCESS_ALL_ACCESS, True, GetCurrentProcessId);
try
VirtualProtectEx(vProcess, Pointer(vPointer), SizeOf(vJnzCode),
PAGE_EXECUTE_READWRITE, @vOldProtect);
WriteProcessMemory(vProcess, Pointer(vPointer), @vJnzCode[0],
SizeOf(vJnzCode), vNumberOfBytesRead);
VirtualProtectEx(vProcess, Pointer(vPointer),
SizeOf(vJnzCode), vOldProtect, @vOldProtect);
finally
CloseHandle(vProcess);
end;
end;
高手就是高手
多谢。
其他版本可能偏移不一样,可以在CPU调试窗体里查看代码的地址,根据RichEdit1.Lines.ClassType的地址算出来