过去我使用 INI-Files 来存储 unicode 文本,但现在我需要将 unicode 文本存储在可执行文件中。我怎样才能做到这一点?
我想存储这些字母:
āčēūīšķļņž
过去我使用 INI-Files 来存储 unicode 文本,但现在我需要将 unicode 文本存储在可执行文件中。我怎样才能做到这一点?
我想存储这些字母:
āčēūīšķļņž
如果要保存 Unicode INI 文件,则可以尝试以下代码。这些文件以UTF8 编码保存。
你也可以看看这个 Unicode 库,在那里你可以找到很多帮助函数。
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
如果您确实需要使用 Delphi 7,则有一些变体:
将字符串存储在链接到可执行文件的资源中。
将字符串存储在大备忘录或相同的东西中,位于全局数据模块或任何其他可视或非可视组件上,并通过索引访问它。这是可能的,因为 Delphi 资源中的字符串以 XML 编码的形式存储。例如,您的符号示例āčēūīšķļņž
将存储为āčēūīšķļņž
将 XML 编码或 Base64 编码的字符串存储在代码中的字符串常量中。
对于字符串转换,您可以使用 EncdDecd.pas、xdom.pas 或 System.pas 的一些函数,如 UTF8Encode/UTF8Decode。
要在 Delphi 表单中显示和编辑 Unicode 字符串,您可以使用特殊的 Unicode 控件集,如TNT Unicode 控件或子类原始 Delphi 控件,并自行执行一些其他解决方法,如 TntControls.pas(TNT Unicode 的一部分)中注释的摘录中所述控制):
Windows NT 提供对本地 Unicode 窗口的支持。要将 Unicode 支持添加到 TWinControl 后代,请覆盖 CreateWindowHandle() 并调用 CreateUnicodeHandle()。
这样做的一个主要原因是因为 VCL 只使用 ANSI 版本的 SendMessage()——SendMessageA()。如果在 UNICODE 窗口上调用 SendMessageA(),Windows 会自动处理 ANSI/UNICODE 转换。例如,如果 VCL 使用 SendMessageA 将 WM_SETTEXT 发送到一个窗口,即使目标窗口是一个 UNICODE 窗口,Windows 实际上也需要一个 PAnsiChar。因此,使用 PChars 调用 SendMessageA 不会导致任何问题。
VCL 中的一个问题与 TControl.Perform() 方法有关。Perform() 直接调用窗口过程并假定一个 ANSI 窗口。例如,如果 VCL 调用 Perform(WM_SETTEXT, ...) 传入一个 PAnsiChar,该 PAnsiChar 最终被传递到需要一个 PWideChar 的 DefWindowProcW(),就会出现问题。
这就是 SubClassUnicodeControl() 的原因。此过程将子类化 Windows WndProc 和 TWinControl.WindowProc 指针。它将确定消息是来自 Windows 还是直接调用了 WindowProc。然后它将调用 Windows 的 SendMessageA() 以对某些文本消息执行正确的转换。
另一个问题与 TWinControl.DoKeyPress() 有关。它是从 WM_CHAR 消息中调用的。它将 WideChar 转换为 AnsiChar,并将生成的字符发送到 DefWindowProc。为了避免这种情况,DefWindowProc 也是子类化的。WindowProc 将通过在传递之前将 char 代码转换为 #FF 来使 WM_CHAR 消息对 ANSI 处理代码安全。它将原始 WideChar 存储在 TWMChar 的 .Unused 字段中。代码#FF 在传递到 DefWindowProc 之前被转换回 WideChar。
做
const MyString = WideString('Teksts latvie'#$0161'u valod'#$0101);
很简单,想法是找到一个非可视组件,它可以存储文本并将您的文本存储在那里。希望这样的组件还可以为您提供一个编辑器来在设计时编辑文本。
有一个组件调用FormResource
可以做到这一点。我用TUniScript
. 我相信还有其他类似的组件。但是,我没有从标准库中找到可用的组件。
该方法Widestring(#$65E5#$672C)
不起作用,因为 Delphi 7 只是不希望#
.
另一种方法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 文本。
或者,将常量存储在 UTF-8 中,这是 ASCII 安全的 - 这样您就可以#
轻松使用。一个优点是,在源代码中编写起来不那么麻烦。一个缺点是,您永远不能直接使用该常量,而必须先将其转换为 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 );