Delphi 带有Unicode主题的Indy消息

Delphi 带有Unicode主题的Indy消息,delphi,unicode,indy,Delphi,Unicode,Indy,我需要创建一个带有Unicode主题的IdMessage(例如“本語 - 测试“) 我试着用 Msg.Subject := UTF8Encode(subject); 其中,subject是包含上述文本的宽字符串 但当我查看编码的主题时(通过将消息保存到文件),它看起来是这样的: Subject: =?UTF-8?Q?=C3=A6=C5=93=C2=AC=C3=A8=C2=AA=C5=BE?= - test 而不是 Subject: =?UTF-8?Q?=E6=0C=AC=E8=AA=9E?=

我需要创建一个带有Unicode主题的IdMessage(例如“本語 - 测试“)

我试着用

Msg.Subject := UTF8Encode(subject);
其中,subject是包含上述文本的宽字符串 但当我查看编码的主题时(通过将消息保存到文件),它看起来是这样的:

Subject: =?UTF-8?Q?=C3=A6=C5=93=C2=AC=C3=A8=C2=AA=C5=BE?= - test
而不是

Subject: =?UTF-8?Q?=E6=0C=AC=E8=AA=9E?= - test
Outlook将其显示为“æœèè-测试”

有没有关于我错在哪里的指示


Delphi 2006(unicode以前的版本),Indy 10(源代码最近的版本)

在Delphi的unicode以前的版本中,所有内容都基于
Anistring
,您分配给
TIdMessage.Subject
属性的值(以及
TIdMessage
的任何其他
Anistring
属性)必须使用操作系统默认字符编码进行编码。而是将其编码为UTF-8,这将不起作用。这是因为
TIdMessage
将首先使用操作系统默认编码将
Subject
值解码为Unicode,然后使用
TIdMessage.oninitializeso
事件提供的编码参数对Unicode数据进行MIME编码,如果未分配事件处理程序,则为默认值(在本例中,这些参数是
CharSet=UTF-8
HeaderEncoding=QuotedPrintable
)。
TIdMessage
没有机制允许您指定分配给它的任何
数据的编码。因此,发送
值的唯一可能性是本語 - 使用
Subject
属性测试“
是将源
宽字符串
按原样分配给属性,并让RTL使用操作系统默认编码将数据转换为
ansisting

Msg.Subject := subject;
但是,如果操作系统不支持所使用的Unicode字符,则会丢失数据。在这种情况下,无法避免这种情况

另一种方法是将
Subject
属性设置为空字符串,然后改用
TIdMessage.ExtraHeaders
属性,以便您可以提供自己的标题值,该值将按原样放入电子邮件中。使用此方法,您可以调用Indy的
EncodeHeader()
直接执行功能。在Delphi的Unicode之前版本中,它有一个可选的
ASrcEncoding
参数,默认为操作系统默认编码(
TIdMessage
在编码头时当前不提供该参数的值):

这样,
EncodeHeader()
将能够避免冗余转换,因为它可以检测到源和目标字符编码都是UTF-8,因此只需按原样对源UTF-8数据进行MIME编码。更糟糕的情况是,即使它没有检测到字符编码相同,它也会使用UTF-8将源数据解码为Unicode,然后重新编码将其还原到UTF-8。这些是无损转换,因此不会丢失任何数据

仅供参考,您显示的Unicode字符的正确编码为:

Subject: =?UTF-8?Q?=E6=9C=AC=E8=AA=9E?= - test
不是


如您所示。请注意,在Delphi的Unicode之前版本中,第二个编码的八位字节是
9C
,而不是
0C
,,其中所有内容都基于
AnsiString
,即您分配给
TIdMessage.Subject
属性的值(以及
TIdMessage
的任何其他
ansisting
属性)必须使用OS默认字符编码进行编码。您将其编码为UTF-8,这将不起作用。这是因为
TIdMessage
将首先使用OS默认编码将
Subject
值解码为Unicode,然后使用
TIdMessage.On提供的编码参数对Unicode数据进行MIME编码初始化为
事件,如果未分配事件处理程序,则为默认值(在这种情况下,这些参数为
CharSet=UTF-8
HeaderEncoding=QuotedPrintable
).
TIdMessage
没有机制允许您指定分配给它的任何
数据的编码。因此,发送
值的唯一可能性是本語 - 使用
Subject
属性测试“
是将源
宽字符串
按原样分配给属性,并让RTL使用操作系统默认编码将数据转换为
ansisting

Msg.Subject := subject;
但是,如果操作系统不支持所使用的Unicode字符,则会丢失数据。在这种情况下,无法避免这种情况

另一种方法是将
Subject
属性设置为空字符串,然后改用
TIdMessage.ExtraHeaders
属性,以便您可以提供自己的标题值,该值将按原样放入电子邮件中。使用此方法,您可以调用Indy的
EncodeHeader()
直接执行功能。在Delphi的Unicode之前版本中,它有一个可选的
ASrcEncoding
参数,默认为操作系统默认编码(
TIdMessage
在编码头时当前不提供该参数的值):

这样,
EncodeHeader()
将能够避免冗余转换,因为它可以检测到源和目标字符编码都是UTF-8,因此只需按原样对源UTF-8数据进行MIME编码。更糟糕的情况是,即使它没有检测到字符编码相同,它也会使用UTF-8将源数据解码为Unicode,然后重新编码将其还原到UTF-8。这些是无损转换,因此不会丢失任何数据

仅供参考,您显示的Unicode字符的正确编码为:

Subject: =?UTF-8?Q?=E6=9C=AC=E8=AA=9E?= - test
不是

如您所示。请注意,第二个编码的八位字节是
9C
,而不是
0C