FastReport 4.7x 中文介面的問題及解法

最近全球受到金融海嘯的影響,我也無法倖免於難,腦袋昏昏沉沉,做起事來也懶懶散散。這樣也不是辦法,突然想起不知那位先哲說的,可以拿數學來訓練腦力,所以隨手抓起一本《組合數學》的書來看,效果如何?就不言而喻了。幸運的是,病情雖沒轉好,但也沒有變差,腦袋瓜當然也沒變得更聰明。上個禮拜,有朋友來電問我用 Delphi 寫報表程式的問題,主要是 Codegear 出 Delphi 2009 這個版本,早期使用報表元件 FastReport 3.x 的版本也隨之更新,然而在 FastReport 3.x 毫無問題的中文介面,更換 FastReport 4 卻變成亂碼,因此希望我協助找出問題和解決的辦法。

有事做總是好的,所以我就爽快的答應下來。為了診斷問題,所以必須先找到所需的工具,CodegearDelphi 2009 的測試版提供下載,當然少不了要填寫資料,下載《Delphi and C++Builder 2009 Trial with ISO》的檔案約 1.9 G。至於 FastReport 4.x 也可以到 Fast Report Inc. 的網站下載測試版,目前最新的版本是 FastReport 4.7x,由於我前後下載了幾次,每次最後的 x 數字都不同,然而截至目前為止,我發現 FastReport 4.7x 版都未解決中文介面顯示的問題。

我把 Delphi 2009 和 FastReport 4.7x 依先後安裝完畢。在安裝過程中,FastReport 會詢問所要安裝的語言別,但安裝之後,我發現並沒有什麼作用,可能只是安裝過程用來顯示繁體中文而已。因此,為了能在 Delphi 程式執行期間顯示報表的中文介面,還必須運用 FastReport 4.7x 的 Recompile Wizard(重新編譯精靈),把語言轉換成繁體中文。


完成這項工作之後,就可以執行 Delphi 的 IDE 環境,我隨便找個 FastReport 所提供的範例來測試(像是 PrintTable 這個專案),並且執行。當開啟 FastReport 的預覽列印時,果然中文字不是缺字,就是呈現亂碼。結果如下圖所示:


究其原因,首先是 FastReport 4 的資源編譯器 frcc.exe 發生了問題。為什麼做此判斷?我發現經由 frcc.exe 所轉換的 Delphi 檔案(frxrcClass.pas、frxrcDesgn.pas、frxrcExports.pas 及 frxrcInsp.pas)一打開全是亂碼(如下圖所示),想必是 frcc.exe 把中文字轉換成 Ascii 碼,才會造成這樣的結果。再加上 FastReport 4.5 (含)以上的版本,一改以往處理多國語言字元集的方式,改採 UTF-8 的格式,並以 XML 來儲存介面字元的資源;於是,當程式經由 Delphi 把這些字元加以編譯過後,執行期間載入資源字串流時,並沒有把這些字元根據 UTF-8 的格式再加以轉換,就變成這樣的結局。


由於跟這幾個資源檔有關的,就只有 frxRes.pas 這支程式(可以從上圖中的 uses frxRes; 這行看到端倪),同時,像 frxrcClass.pas 這些資源檔初始化(initialization),也就只有一行程式碼:

initialization
frxResources.AddXML(resXML);
因此可以斷言問題就出在 frxResources 物件的 AddXML 這個方法。於是我向朋友要 frxRes.pas 這段程式碼,原程式碼如下:「
procedure TfrxResources.AddXML(const Str: AnsiString);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create(Str);
LoadFromStream(Stream);
Stream.Free;
end;
」我建議把這段程式改成:「
procedure TfrxResources.AddXML(const Str: AnsiString);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create(UTF8Encode(String(str)));
LoadFromStream(Stream);
Stream.Free;
end;
」變動的這段程式碼,其目的在於先把 AnsiString 的字串轉換成 UTF-8 的字串後,再建立並載入字串流。另外,也必須把 frxrcClass.pas、frxrcDesgn.pas、frxrcExports.pas 和 frxrcInsp.pas 這四個資源檔變更成正常的中文字(如果有 UltraEdit 可以直接把檔案從 Ascii 轉換成 UTF-8,但是仍有一些中文字被截斷,須手動修正的),修改完成後複製到 FastReport 的程式庫資料夾內(像是 LibD12 或 Source)。接著再利用 FastReport 4.7x 的 Recompile Wizard,選擇「Recompile all packages」重新編譯。


最後,重新執行先前的範例檔,此時中文顯示應該就會如下圖一樣正常。

留言

huwk寫道…
^^ 謝謝.省去自己摸索的時間
Jerry寫道…
我測試,看了FastReport 4.7x,最新版的
已經改成如下程式碼,不過還是會呈現亂碼?
Stream := TStringStream.Create({$IFDEF Delphi12}'', TEncoding.UTF8{$ELSE}Str{$ENDIF});
Eden寫道…
作者已經移除這則留言。

這個網誌中的熱門文章

langue ou langage

Pattren:樣式、模式或範式

似水流年(Year Flowing Like Water)