gpt4 book ai didi

delphi - 为什么 EM_SETTEXTMODE 不起作用?

转载 作者:行者123 更新时间:2023-12-03 15:07:33 25 4
gpt4 key购买 nike

我正在尝试使用 EM_SETTEXTMODE在 Delphi 7 中的 RichEdit 控件上。

只需创建一个新项目,添加一个 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 或 TM_SINGLELEVELUNDO 或 TM_MULTICODEPAGE),然后 SETTEXTMODE 成功(0),但即使之后它仍然是 38

按照文档的建议,在使用 EM_SETTEXTMODE 之前先清除 RichEdit 的文本。

我尝试使用 EM_SETTEXTMODE 设置不同的值,但它始终保持 38

我注意到 EM_SETTEXTMODE 始终返回 0(成功),即使 RichEdit 控件在调用之前包含文本。

我尝试使用 RichEdit1.Perform 而不是 SendMessage - 没有区别。

我在各个论坛中找到了有关此问题的多个主题,但其中任何一个都没有解决该问题。

知道为什么这不起作用吗?

最佳答案

较旧的 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中这样做,我得到了正确的结果:

Delphi5

需要记住的一件事是,RichEdit 2.0 将 CRLF 对替换为 CR,因此可能会出现其他问题。如果您在路上遇到问题,请不要向我开枪...

关于delphi - 为什么 EM_SETTEXTMODE 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21711022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com