在Delphi中将widechar代码点的十六进制字符串表示转换为widechar

在Delphi中将widechar代码点的十六进制字符串表示转换为widechar,delphi,delphi-10.4-sydney,widechar,Delphi,Delphi 10.4 Sydney,Widechar,我无法将编辑框中的文本转换为WideChar。这在用于打印表情符号的代码中使用 如果我像下面这样手动设置WideChar值,它就会工作 Emoji[1] := WideChar($D83D); Emoji[2] := WideChar($DC4D); 但是我希望能够通过编辑框设置十六进制代码,如下所示 StringToWideChar(edit1.text, @wc1, Length(edit1.text)); StringToWideChar(edit2.text, @wc2, Length

我无法将编辑框中的文本转换为WideChar。这在用于打印表情符号的代码中使用

如果我像下面这样手动设置WideChar值,它就会工作

Emoji[1] := WideChar($D83D);
Emoji[2] := WideChar($DC4D);
但是我希望能够通过编辑框设置十六进制代码,如下所示

StringToWideChar(edit1.text, @wc1, Length(edit1.text));
StringToWideChar(edit2.text, @wc2, Length(edit2.text));
Emoji[1] := wc1;
Emoji[2] := wc2;
wc1和wc2定义为WideChar。编辑框包含的值与上面硬编码的值相同。该代码导致输出为空,因此转换有问题


我做错了什么?感谢您的帮助。

您不能将字符串“$D83D”解释为文本,而必须将其解析为整数

首先,您需要从编辑框中获取文本。这是
Edit1.Text
。然后需要将其转换为整数。例如,您可以使用
strotint
TryStrToInt
。然后您只需将该整数重新解释(强制转换)为
Char

程序TForm1.Edit1Change(发送方:TObject);
变量
编码单位:整数;
开始
如果TryStrToInt(Edit1.Text,CodeUnit)和InRange(CodeUnit,0,$FFFF),则
标签1.标题:=字符(代码单位)
其他的
标签1.标题:='';
结束;

在这里,作为奖励,我还使用
InRange
(我的意思是,用户可以在理论上键入
123456789
)验证假定的codeunit是实际的16位无符号整数。Delphi的
strotint
函数支持使用美元符号表示法的十六进制。

为什么不直接在
TEdit
中键入实际的表情符号,然后按原样使用其
文本?不会做你认为它会做的事。它用于将
字符串
转换为等效长度的
WideChar[]
缓冲区(即,最初用于将
AnsiString
转换为
PWideChar
,现在只是一个普通副本)。它并不意味着将整个
字符串
分割成单个
WideChar
.10.4,因此Andreas的代码(使用Remy的编辑)可以正常工作<代码>表情符号[1]:=char(stroint(edit1.text))为什么对每个UTF-16代码单元使用单独的
TEdit
?为什么不使用单个
TEdit
来输入整个码点?如果您不想让用户输入实际的表情符号,那么至少输入其代码点值(即,
'$1F44D'
),然后您可以使用
stroint()
将其转换为整数,然后使用或将其转换为正确的
字符串
。谢谢您的提示。使用整个代码点并使用ConvertFromUtf32进行转换是更干净、更简单的代码。从技术上讲,这根本不适用于代码点,而是适用于代码单元。这是一个重要的区别。U+1F44D(@RemyLebeau:为什么您更喜欢
Char
而不是
Chr
?首先,因为
Chr()
文档中提到。其次,因为
Chr(X)当
X
128..255
时,不能保证总是返回值为
X
Char
,而
Char(X)
是保证的。@RemyLebeau:你能举一个Delphi 2009+代码的例子吗?在这个例子中,
Chr
Char
在给定一个
0..$FFFF
范围内的整数时不会产生相同的结果。我部分同意你的两个理由,但只是部分同意(这并不是说你不能使用
Chr
,实际上我认为我从来没有见过区别)。例如,我见过
Chr(128)
可能返回
Char($20AC)
0x80
在某些字符集中是欧元符号)。而
Char(128)
总是
Char($80)