过去我使用INI-Files来存储unicode文本,但现在我需要在可执行文件中存储unicode文本。我怎样才能做到这一点?
我想存储这些信件:
āčēūīšķļņž
答案 0 :(得分:3)
如果要保存Unicode INI文件,可以尝试以下代码。文件保存在UTF8 encoding。
另外,您可以查看this Unicode library,在那里您可以找到许多辅助函数。
uses IniFiles;
function WideStringToUTF8(const Value: WideString): AnsiString;
var
BufferLen: Integer;
begin
Result := '';
if Value <> '' then
begin
BufferLen := WideCharToMultiByte(CP_UTF8, 0, PWideChar(Value), -1, nil, 0, nil, nil);
SetLength(Result, BufferLen - 1);
if BufferLen > 1 then
WideCharToMultiByte(CP_UTF8, 0, PWideChar(Value), -1, PAnsiChar(Result), BufferLen - 1, nil, nil);
end;
end;
function UTF8ToWideString(const Value: AnsiString): WideString;
var
BufferLen: integer;
begin
Result := '';
if Value <> '' then
begin
BufferLen := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(Value), -1, nil, 0);
SetLength(Result, BufferLen - 1);
if BufferLen > 1 then
MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(Value), -1, PWideChar(Result), BufferLen - 1);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
IniFile: TIniFile;
const
UnicodeValue = WideString(#$0101#$010D#$0113#$016B#$012B#$0161);
begin
IniFile := TIniFile.Create('C:\test.ini');
try
IniFile.WriteString('Section', 'Key', WideStringToUTF8(UnicodeValue));
IniFile.UpdateFile;
finally
IniFile.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
IniFile: TIniFile;
UnicodeValue: WideString;
begin
IniFile := TIniFile.Create('C:\test.ini');
try
UnicodeValue := UTF8ToWideString(IniFile.ReadString('Section', 'Key', 'Default'));
MessageBoxW(Handle, PWideChar(UnicodeValue), 'Caption', 0);
finally
IniFile.Free;
end;
end;
在64位Windows 7 Enterprise SP 1上使用Delphi 2007
答案 1 :(得分:2)
如果您肯定需要使用Delphi 7,则有一些变体:
将字符串存储在链接到可执行文件的资源中。
将字符串存储在大备忘录或同一物品中,位于全局数据模块或任何其他可视或非可视组件上,并通过索引访问它。这是可能的,因为Delphi资源中的字符串以XML编码形式存储。例如。您的符号示例āčēūīšķļņž
将存储为āčēūīšķļņž
将XML编码或Base64编码的字符串存储在代码中的字符串常量中。
对于字符串转换,您可以使用EncdDecd.pas,xdom.pas或System.pas的某些函数,如UTF8Encode / UTF8Decode。
要在Delphi表单中显示和编辑Unicode字符串,您可以使用特殊的Unicode控件集,如TNT Unicode Controls或子类原始Delphi控件,并自己做一些其他的解决方法,如TntControls.pas中的注释摘录中所述。 (TNT Unicode控件的一部分):
Windows NT提供对本机Unicode窗口的支持。加上 对a的Unicode支持 TWinControl后代,覆盖CreateWindowHandle()并调用 CreateUnicodeHandle()。
这有效的一个主要原因是因为VCL仅使用ANSI 的版本 SendMessage() - SendMessageA()。如果你在一个上调用SendMessageA() UNICODE 窗口,Windows处理ANSI / UNICODE转换 自动。所以 例如,如果VCL使用发送WM_SETTEXT到窗口 SendMessageA, 即使目标窗口,Windows实际上期望一个PAnsiChar 是一个UNICODE 窗口。所以使用PChars来调用SendMessageA不会产生任何问题。
VCL中的问题与TControl.Perform()方法有关。 执行() 直接调用窗口过程并假定ANSI窗口。 这是一个 问题,例如,VCL调用Perform(WM_SETTEXT,...) 传入 PAnsiChar最终通过了劣势DefWindowProcW() 期待PWideChar。
这就是SubClassUnicodeControl()的原因。这个程序 将子类化 Windows WndProc和TWinControl.WindowProc指针。它会 确定是否 消息来自Windows或是否调用了WindowProc 直。然后它会 为Windows调用SendMessageA()以执行正确的转换 某些短信。
另一个问题与TWinControl.DoKeyPress()有关。它是 从WM_CHAR调用 信息。它将WideChar转换为AnsiChar,然后发送 由此产生的性格 DefWindowProc函数。为了避免这种情况,DefWindowProc是 子类也是。的WindowProc 将使ANSI处理代码的WM_CHAR消息安全 将char代码转换为 在传递之前#FF。它将原始的WideChar存储在 。未使用的TWMChar领域。 代码#FF在传递之前转换回WideChar DefWindowProc函数。
答案 2 :(得分:0)
待办事项
const MyString = WideString('Teksts latvie'#$0161'u valod'#$0101);
答案 3 :(得分:0)
很简单,这个想法是找到一个非可视的组件,该组件可以存储文本并将文本存储在那里。希望这种组件还可以为您提供编辑器,以便在设计时编辑文本。
有一个组件调用FormResource
可以做到这一点。我使用TUniScript
。我相信还有其他类似的组件。但是,我没有从标准库中找到可用的组件。
答案 4 :(得分:0)
Widestring(#$65E5#$672C)
的方法不起作用,因为 Delphi 7 只是不希望 #
超过一个字节,因此结果远远不是您在超过 255 或 $ 时所期望的FF。
另一种方法 WideChar($65E5)+ WideChar($672C)
可用于在您的源代码中存储单个 Unicode 代码点,当您知道需要在赋值开始时使用 Widestring
(也可以是空文字)以便编译器了解您想要哪种数据类型:
const
// Compiler error "Imcompatible types"
WONT_COMPILE: WideChar($65E5)+ WideChar($672C);
// 日本
NIPPON: Widestring('')+ WideChar($65E5)+ WideChar($672C);
看起来很麻烦,但在 Delphi 7 中肯定有你的 UTF-16 文本。
或者,将常量存储在 ASCII 安全的 UTF-8 中 - 这样您就可以轻松使用 #
。一个优点是,编写源代码的麻烦要少得多。一个缺点是,您永远不能直接使用常量,而必须先将其转换为 UTF-16:
const
// UTF-8 of the two graphemes 日 and 本, needing 3 bytes each
NIPPON: #$E6#$97#$A5#$E6#$9C#$AC;
var
sUtf16: Widestring;
begin
// Internally these are 2 WORDs: $65E5 and $672C
sUtf16:= UTF8ToWideString( NIPPON );