我正在尝试在Delphi 7中的RichEdit
控件上使用EM_SETTEXTMODE
。
只需创建一个新项目,添加TRichEdit
控件和TButton
控件,并将以下代码添加到按钮的点击处理程序中:
SendMessage(RichEdit1.Handle, WM_SETTEXT, 0, LPARAM(PChar('')));
Button1.Caption := IntToStr(SendMessage(RichEdit1.Handle, EM_GETTEXTMODE, 0, 0));
Button1.Caption := Button1.Caption + ' ' + IntToStr(SendMessage(RichEdit1.Handle, EM_SETTEXTMODE, TM_PLAINTEXT, 0));
Button1.Caption := Button1.Caption + ' ' + IntToStr(SendMessage(RichEdit1.Handle, EM_GETTEXTMODE, 0, 0));
单击按钮后,按钮的标题设置为38 0 38
,这意味着文本模式根本没有变化 - 最初是38
(TM_RICHTEXT or TM_SINGLELEVELUNDO or TM_MULTICODEPAGE
),然后是{{ 1}}成功(SETTEXTMODE
),但即便如此,它仍然是0
。
在使用文档建议的38
之前,RichEdit
的文本已被清除。
我尝试使用EM_SETTEXTMODE
设置不同的值,并始终保持EM_SETTEXTMODE
。
我注意到38
总是返回EM_SETTEXTMODE
(成功),即使0
控件在调用之前包含文本。
我尝试使用RichEdit
代替RichEdit1.Perform
- 没有区别。
我在这个问题的各个论坛上找到了几个主题,并且在任何论坛中都没有解决。
知道为什么这不起作用?
答案 0 :(得分:9)
较旧的Delphi版本加载位于RICHED32.DLL
的RichEdit控件。
较新的Delphi版本加载RICHED20.DLL
。
RICHED32.DLL
暴露了很多问题,比如你的问题。
该修复程序正在修改comctrls.pas,以便加载RICHED20.DLL
。这很可能是不够的,因为这个DLL和VCL代码可能存在兼容性问题。
查找TCustomRichEdit.CreateParams()
过程,它包含LoadLibrary调用。
我在Delphi XE中测试了你的代码并且它有效,所以你最好的选择是升级到更新的Delphi版本。
<强>更新强>
我使用Delphi 5进行了一些测试,似乎足以改变2个功能。 将Comctrls.Pas复制到您的项目中并执行以下修改:
1)在TCustomRichEdit.CreateParams()
中,更改
const
RichEditModuleName = 'RICHED32.DLL';
到
const
RichEditModuleName = 'RICHED20.DLL';
和
CreateSubClass(Params, 'RICHEDIT');
到
CreateSubClass(Params, 'RICHEDIT20A');
2)在程序TRichEditStrings.Insert()
中,更改
if RichEdit.SelStart <> (Selection.cpMax + Length(Str)) then
raise EOutOfResources.Create(sRichEditInsertError);
到
if RichEdit.SelStart <> (Selection.cpMax + Length(Str) - CountLineBreaks(Str)) then
raise EOutOfResources.Create(sRichEditInsertError);
CountLineBreaks/PosEx
的代码:
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
var
Tmp: PChar;
begin
Result := 0;
if (Offset > Cardinal(Length(S))) then exit;
if Offset = 1 then
Result := Pos(SubStr, S)
else
begin
Tmp := StrPos(PChar(@S[Offset]), PChar(SubStr));
if Tmp = nil then exit;
Result := Cardinal(Tmp - PChar(@S[Offset])) + Offset;
end;
end;
function CountLineBreaks(const S: string): Integer;
const
LB = #13#10;
var
P: Integer;
begin
Result := 0;
P := Pos(LB, S);
while P <> 0 do
begin
Inc(Result);
P := PosEx(LB, S, P + 2);
end;
end;
在Delphi5中这样做,我得到了正确的结果:
要记住的一件事是RichEdit 2.0用CR替换了CRLF对,因此其他问题可能会逐渐增加。如果你在路上遇到问题,请不要开枪......