












近日在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;
修复前:

修复后:

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。