我想使用VCL和Delphi 10+在TEditTMemo控件中看到彩色表情符号。

能做到吗

输入的文字:

👨🏼‍🎤👩🏾‍👩🏼‍👧🏻‍👦🏿

我所看到的:

windows - TEdit可以显示颜色表情符号吗?-LMLPHP

我想看的是:

windows - TEdit可以显示颜色表情符号吗?-LMLPHP

最佳答案

您的问题使我感到好奇,所以尝试了一下,结果如下:

用一般的绘制彩色字体

显然,FMX在更高版本中开箱即用地支持此功能,但在西雅图(我恰好有)不支持。我不知道VCL是否也在您的版本中开箱即用地支持它,但是如果不支持,则可以使用Direct2D。诀窍是使用D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT选项绘制文本。

在Seattle(10)中,未定义此常数,并且-不幸的是-未在默认的TCanvas兼容函数中使用此常数。但是您可以自己调用DrawText或其他函数之一并指定选项。

常规结构基于this Embarcadero docwiki。其余部分是从TDirect2DCanvas结合DrawText documentation来窥视的。

uses Vcl.Direct2D, Winapi.D2D1;

{$R *.dfm}

procedure TForm1.FormPaint(Sender: TObject);
const
  str: string = 'xyz👨🏼‍🎤👩🏾‍👩🏼‍👧🏻‍👦🏿';
  D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT = 4;
var
  c: TDirect2DCanvas;
  r: D2D_RECT_F;
begin
  c := TDirect2DCanvas.Create(Canvas.Handle, Rect(0, 0, 100, 100));
  c.BeginDraw;
  try

    r.left := 0;
    r.top := 0;
    r.right := 100;
    r.bottom := 50;

    // Brush determines the font color.
    c.Brush.Color := clBlack;

    c.RenderTarget.DrawText(
      PWideChar(str), Length(Str), c.Font.Handle, r, c.Brush.Handle,
      D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
  finally
    c.EndDraw;
    c.Free;
  end;
end;

这小段代码以相当丑陋的方式工作(就文本的位置而言),但是您也可以浏览TDirect2DCanvas,并复制其文本方法之一的实现,以创建一种以特定方式输出文本的函数,你要。之后,将其应用于您自己的TGraphicControl或TCustomControl后代以创建支持表情符号的标签应该相当容易。

在TEdit中这样做

在TEdit中进行管理比较困难,因为绘制文本(和表情符号)是由控件本身处理的。应该可以创建一个TEdit后代,并且/或者将其 Hook 到WM_PAINT消息中,并使用相同的技巧来绘制文本,但是我不确定这样做的效果如何。

我给了它一个快速的镜头,但实际上并不能很好地工作,特别是在编辑时。因此,我做了TEdit的后代。聚焦后,它将以正常方式绘制文本,彩色的表情符号将为黑白,并分为两个字符(表情符号和颜色组合字符)。当编辑失去焦点时,自定义绘画代码将接管工作,在这种情况下效果很好。也许您可以尝试对其进行抛光,以使其在编辑时也能正常工作,但是随后您必须考虑滚动,将插入符号和其他内容定位。对于TMemo的后代来说,这将更加困难。希望您现在对彩色显示器感到满意。 :-)
type
  TMyEdit = class(Vcl.StdCtrls.TEdit)
  protected
    procedure PaintWindow(DC: HDC); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

uses Vcl.Direct2D, Winapi.D2D1;

{$R *.dfm}

const
  D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT = 4;

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;
  DoubleBuffered := True;
end;

procedure TMyEdit.PaintWindow(DC: HDC);
var
  c: TDirect2DCanvas;
  r: D2D_RECT_F;
begin
  // Default drawing when focused. Otherwise do the custom draw.
  if Focused then
  begin
    Inherited;
    Exit;
  end;

  c := TDirect2DCanvas.Create(dc, ClientRect);
  c.BeginDraw;
  try

    r.left := ClientRect.Left;
    r.top := ClientRect.Top;
    r.right := ClientRect.Right;
    r.bottom := ClientRect.Bottom;

    // Basic font properties
    c.Font.Assign(Font);
    // Brush determines the font color.
    c.Brush.Color := Font.Color;

    c.RenderTarget.DrawText(
      PWideChar(Text), Length(Text), c.Font.Handle, r, c.Brush.Handle,
      D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT);
  finally
    c.EndDraw;
    c.Free;
  end;
end;

关于windows - TEdit可以显示颜色表情符号吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55447701/

10-11 02:45
查看更多