惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
博客园 - 司徒正美
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Hugging Face - Blog
Hugging Face - Blog
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
L
LangChain Blog
T
The Blog of Author Tim Ferriss
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ

博客园 - 秋·风

用lazarus编写的linux deb和windows打包工具源码已上传 修复lazarus datetimepicker控件在linux下拉不能选择日期的bug 用fpc trunk编译lazarus控件找不到TTimeZone 在银河麒麟v10操作系统应用程序执行遇到“权限不够”的提示 修复pl_cindy的Panel系列控件在gtk3出错的bug 龙芯 3A4000工具链的编译(mingw64) lazarus 4.8及之前的版本QT5中文输入多字词组时只输入前2个中文 lazarus trunk linux从2026.07.02开始,LCLWidgetType默认使用gtk3,怎样改回gtk2 【aarch64-win64】DonAlfredo终于修复fpc将TSmallPoint赋值为一个负数,并将TSmallPoint赋值给TPoint时得到一个655xx的数值的bug lazarus编译时提示链接出错的处理方法 mORMot2两个BUG 【aarch64-win64】发现fpc aarch64-win64 将TSmallPoint赋值为一个负数,并赋值给TPoint时得到一个655xx的数值的bug 修复aarch64 win64下lazarus不弹出SourceTabPopUpMenu fpc aarch64-win64版编译应用时遇到一个奇怪的bug 在windows 11 on arm64系统编译lazarus出错的处理方法 修复TDBMemo只读不能使用Ctrl+C复制文字的Bug freepascal打补丁后已支持windows 11 on arm64(lazarus aarch64 windows版也可以运行了) 查看libc.so.6的版本号 Lazarus移动版启动程序 fpc 3.2.2交叉编译i386-linux链接出错 lazarus鸿蒙开发13:使用鸿蒙原生API画图--lazarus侧关键代码 lazarus鸿蒙开发12:使用鸿蒙原生API画图--鸿蒙侧关键代码 lazarus鸿蒙开发11:使用鸿蒙原生接口画图 lazarus鸿蒙开发10:lazarus一键编译、打包助手 lazarus鸿蒙开发9:使用命令行编译DevEco Studio应用 lazarus鸿蒙开发8:在DevEco Studio的日志窗口显示日志信息 lazarus鸿蒙开发7:在 Windows 上为 OpenHarmony (LoongArch64) 编译 Qt 5.15.12 SDK 指南 lazarus鸿蒙开发6:鸿蒙project配置 lazarus鸿蒙开发5:编译ohos_hap_project lazarus鸿蒙开发4:编译OHOS_QT_Lazarus
修正lazarus在GTK3下的Synedit只能输入2个中文字符的Bug
秋·风 · 2026-08-14 · via 博客园 - 秋·风

近日在lazarus trunk使用GTK3时发现Synedit只能输入2个中文字符,经排查,找到了解决方法。
问题原因:
当中文输入时执行到DeliverIMCommit的:
UTF8Char := AStr;
AStr原来是正常的多字词组赋值给UTF8Char时变为最多2个中文,如:AStr:='中华人民共和国',赋值给UTF8Char后变为'中华#$E4';
排查发现
TUTF8Char的定义:

  TUTF8Char = String[7]; // UTF-8 character is at most 6 bytes plus a #0

就是这个定义决定了TUTF8Char不能保存多于两个中文。

procedure TGtk3Widget.DeliverIMCommit(const AStr: string);
var
  UTF8Char: TUTF8Char;
  CharMsg: TLMChar;
begin
  if (AStr = '') or not Assigned(LCLObject) then
    exit;

  {$IFDEF GTK3DEBUGKEYPRESS}
  writeln('TGtk3Widget.DeliverIMCommit ', dbgsName(LCLObject), ' str="', AStr, '"');
  {$ENDIF}
  UTF8Char := AStr;
  if LCLObject.IntfUTF8KeyPress(UTF8Char, 1, False) then
    exit;

  FillChar(CharMsg{%H-}, SizeOf(CharMsg), 0);
  CharMsg.Msg := CN_CHAR;
  CharMsg.CharCode := Word(AStr[1]);
  NotifyApplicationUserInput(LCLObject, PLMessage(@CharMsg)^);

  if DeliverMessage(CharMsg, True) <> 0 then
    exit;

  CharMsg.Msg := LM_CHAR;
  NotifyApplicationUserInput(LCLObject, PLMessage(@CharMsg)^);
  DeliverMessage(CharMsg, True);
end;

修复方法:
将输入的AStr字符逐个LCLObject.IntfUTF8KeyPress(UTF8Char, 1, False)就可以。
打开/lazarus/lcl/interfaces/gtk3/gtk3widgets.pas这个单元。
将procedure TGtk3Widget.DeliverIMCommit(const AStr: string)改为以下代码,然后重构lazarus就可以。

procedure TGtk3Widget.DeliverIMCommit(const AStr: string);
var
  UTF8Char: TUTF8Char;
  CharMsg: TLMChar;
  i:Integer;
begin
  if (AStr = '') or not Assigned(LCLObject) then
    exit;

  {$IFDEF GTK3DEBUGKEYPRESS}
  writeln('TGtk3Widget.DeliverIMCommit ', dbgsName(LCLObject), ' str="', AStr, '"');
  {$ENDIF}

  for i:=1 to UTF8Length(AStr)  do
  begin
    UTF8Char:=utf8Copy(AStr,i,1);
    if LCLObject.IntfUTF8KeyPress(UTF8Char, 1, False) then
      Continue;

    FillChar(CharMsg{%H-}, SizeOf(CharMsg), 0);
    CharMsg.Msg := CN_CHAR;
    CharMsg.CharCode := ord(UTF8Char[1]);
    NotifyApplicationUserInput(LCLObject, PLMessage(@CharMsg)^);

    DeliverMessage(CharMsg, True);

    CharMsg.Msg := LM_CHAR;
    NotifyApplicationUserInput(LCLObject, PLMessage(@CharMsg)^);
    DeliverMessage(CharMsg, True);
  end;
end; 

 修复前:

image

 修复后:

557d2800f6242b3b1c3602d1b887c3a7