秋·风

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

【原创】修复开源控件kcontrols不能在linux使用中文输入法的bug

2025-11-30:
修正后实则ibus和fcitx这2种输入法都可以正常输入中文

kcontrols这个控件TKMemo可以使用rich功能,但有个致命问题是在linux不能使用中文输入法。
今天尝试修复这个Bug。
打开kcontrols\source\kmemo.pas
添加红色代码:

{ @abstract(This file is part of the KControls component suite for Delphi and Lazarus.)
  @author(Tomas Krysl)

  Copyright (c) 2020 Tomas Krysl<BR><BR>

  <B>License:</B><BR>
  This code is licensed under BSD 3-Clause Clear License, see file License.txt or https://spdx.org/licenses/BSD-3-Clause-Clear.html.
}

{$ifdef LCLGTK2}
{$define WITH_GTK2_IM}
{$endif}

unit kmemo; // lowercase name because of Lazarus/Linux

{$include kcontrols.inc}
{$WEAKPACKAGEUNIT ON}

interface

在1817行添加红色代码行:
TKCustomMemo增加输入法消息处理:

procedure WMImeComposition (var Message: TLMessage); message LM_IM_COMPOSITION;

 

    procedure WMCut(var Msg: TLMessage); message LM_CUT;
  {$IFNDEF FPC}
    // no way to get filenames in Lazarus inside control (why??)
    procedure WMDropFiles(var Msg: TLMessage); message LM_DROPFILES;
  {$ENDIF}
    procedure WMEraseBkgnd(var Msg: TLMessage); message LM_ERASEBKGND;
    procedure WMGetDlgCode(var Msg: TLMNoParams); message LM_GETDLGCODE;
    procedure WMHScroll(var Msg: TLMHScroll); message LM_HSCROLL;
    procedure WMKillFocus(var Msg: TLMKillFocus); message LM_KILLFOCUS;
    procedure WMPaste(var Msg: TLMessage); message LM_PASTE;
    procedure WMSetFocus(var Msg: TLMSetFocus); message LM_SETFOCUS;
    procedure WMVScroll(var Msg: TLMVScroll); message LM_VSCROLL;
    {$ifdef LCLGTK2}
    procedure WMImeComposition (var Message: TLMessage); message LM_IM_COMPOSITION;
    {$endif}
  protected
    FCaretRect: TRect;
    FDragCurPos: TPoint;
    FDragMode: TKSizingGripPosition;
    FDragOrigRect: TRect;

在7121行添加红色代码:

procedure TKCustomMemo.WMVScroll(var Msg: TLMVScroll);
begin
  SafeSetFocus;
  Scroll(cScrollNoAction, Msg.ScrollCode, 0, Msg.Pos, eoScrollWindow in FOptions);
end;

{$ifdef LCLGTK2}
procedure TKCustomMemo.WMImeComposition (var Message: TLMessage);
var IMStr:string;
  i:integer;
begin
  if Message.WParam=GTK_IM_FLAG_COMMIT then
  begin
    IMStr:=UTF8Decode(pchar(Message.LParam)); //输入的中文字符
    if IMStr<>'' then
    begin
      for i:=1 to utf8length(IMStr) do
        InsertChar(SelEnd, utf8copy(IMStr,i,1));
    end;
  end;
  inherited;
end;
{$endif}
{ TKMemoBlock } constructor TKMemoBlock.Create; begin inherited; FOffset := CreateEmptyPoint; FDoubleClickState := mdblNone; FMouseCaptureWord := -1; FClickOnMouseUp := True; FOnClick := nil; FOnDblClick := nil; end;

修改后重新编译就可以在linux使用中文输入。

QQ_1764220945528

 

QQ_1764221067481

 

c2770cc8fc29aeff6d82412445534388

 

posted on 2025-11-27 13:27  秋·风  阅读(108)  评论(0)    收藏  举报