|
发表于 2010-8-27 23:06:37
|
显示全部楼层
獨樂樂何不眾樂樂 ?
Lazarus 0.9.28 在 LCLProc單元中提供了幾個與 UTF8 字串相關的函數,例如有 Utf8ToAnsi(), AnsiToUtf8, UTF8Length()、UTF8CharAt() 等等,在一定程度上可以給我們提供幫助 , 我自己也寫了一些公用函式, 來加強 UTF8 與 ANSI 字串編碼的處理
BUG (以下都是在 Lazarus 0.9.28 之 WIN32 版本下測試發現的, 其它平台如 Linux 版不一定會有相同狀況)
雖然 Lazarus 0.9.28 已全面使用 UTF8 編碼, 但仍有些函式取回的 String 仍為 ANSI String , 混合處理的情況下會造成許多困擾, 所以在此整理一下
▲ INI FILE
//TIniFile 物件字串的 "讀出值" 及 "讀出預設值" 仍為 ansi, 故要轉換
MyIni:TIniFile;
procedure TForm1.FormCreate(Sender: TObject);
begin
MyIni := TIniFile.Create(ChangeFileExt(Application.ExeName,'.ini'));
MyPath := ExtractFilePath(Application.ExeName);
MyPath:=ansitoutf8(MyPath); //改為 UTF8
MyList := TStringList.Create;
MyList.Clear;
tmp:=MyPath+' OSDB.FDB'; //路徑可能夾帶中文
FDB_FN:=ansitoutf8(MyIni.ReadString(' ARAMETER', 'FDB_FILENAME', utf8toansi(tmp)));
ShowMessage(FDB_FN);
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
MyIni.WriteString(' ARAMETER', 'FDB_FILENAME', utf8toansi(FDB_FN));
MyList.Free;
MyIni.Free;
end;
▲ ExtractFilePath() 函式 : 取出某檔案的所在路徑
我發現它取出路徑的字串仍是 ANSI String 編碼, 要與一般 String 變數 (default 是 UTF8 編碼) 做 "+" 號處理會有問題, 所以每次取出後要用 AnsiToUtf8() 轉成 UTF8 String
▲ FileExists() 函式 : 判斷檔案存不存在
if (FileExists(Utf8ToAnsi(SDB_FN))) then
begin
.....
end;
▲ TStringList 物件的主要屬性仍為 Ansi String
//以下為正確處理示範
procedure TForm1.Button1Click(Sender: TObject);
var TmpList: TStringList;
i:integer;
begin
TmpList := TStringList.Create;
TmpList.LoadFromFile(Utf8ToAnsi('C:\\新資料夾\\新增文字文件.txt'));
for i:=0 to TmpList.Count-1 do
begin
ShowMessage(AnsiToUtf8(TmpList.Strings));
end;
TmpList.SaveToFile(Utf8ToAnsi('C:\\新資料夾\\新增文字文件2.txt'));
TmpList.Free;
end;
▲ 某些控件 String 屬性需為 Ansi String
如 要設定資料庫控件 TDbf 的 TableName 屬性, 需傳入 Ansi String
My_Path:=ExtractFilePath(Application.ExeName); //ExtractFilePath() 取回的是 ANSI
Dbf1.TableName:=My_Path+'myTest.DBF'; //TDbf 的 TableName 可直接餵入 ANSI STRING
而指定另一種資料庫控件 SQLite3Connection1 的 DatabaseName 屬性 卻又須使用標準 UTF8 String
My_Path:=ExtractFilePath(Application.ExeName); //ExtractFilePath() 取回的是 ANSI
My_Path:=AnsiToUtf8(My_Path); //改為 UTF8
SQLite3Connection1.DatabaseName:=My_Path+'myTest.db'; //指定一個 DATABASE 要餵入 UTF8 STRING
所以以後若指定某控件的字串屬性, 明明是正確的字串內容, 但卻出現編譯錯誤或是控件無法正確動作, 可能就是 String 編碼問題 |
|