2012-12-10 35 views
4

我正在將Delphi 5應用程序遷移到Delphi XE3。我在編譯時遇到了一些錯誤。有人可以幫助我解決這些問題嗎?提前感謝您的幫助。如何解決Delphi XE3遷移錯誤?

  1. 我無法在XE3中找到函數OemToChar的定義。當我按Ctrl +點擊該功能時,它顯示消息Unable to locate 'WinAPI.Windows.pas'。我無法打開任何delphi組件文件。系統上windows.pas的位置是什麼?或如何解決它?

  2. Incompatiable Types: 'PAnsiChar' and 'PWideChar'以下功能符合OemToChar(p1, p2)

function OemToAnsi(const Str: string): string; 
var 
    p1, 
    p2: PChar; 
begin 
    p1 := PChar(Str); 
    p2 := StrNew(p1); 
    OemToChar(p1, p2); 
    Result := StrPas(p2); 
    StrDispose(p2); 
end; 
  1. 得到錯誤'Low Bound Exceeds High Bound'在下面的代碼。

function StrToRichText(const Str: string): string; 
var 
    i: integer; 
begin 
    Result := ''; 
    for i := 1 to Length(Str) do 
    begin 
    case Str[i] of 
     #128 .. #255 : 
     Result := Result + '\''' + LowerCase(IntToHex(Ord(Str[i]), 2)); 
     '\','{','}': 
     Result := Result + '\' + Str[i]; 
    else 
     Result := Result + Str[i]; 
    end; 
    end; 
end; 

回答

7

OemToAnsi功能應該是這樣的:

function OemToAnsi(const Str: AnsiString): AnsiString; 
begin 
    SetLength(Result, Length(Str)); 
    OemToCharA(PAnsiChar(Str), PAnsiChar(Result)); 
end; 

但是,也許你會與

function OemToWide(const Str: AnsiString): string; 
begin 
    SetLength(Result, Length(Str)); 
    OemToChar(PAnsiChar(Str), PChar(Result)); 
end; 

至於更好的爲您StrToRichText,這看起來更加困難。它顯然只接受ANSI輸入。如果你想堅持ANSI,那麼只需將聲明更改爲

function StrToRichText(const Str: AnsiString): AnsiString; 

RTF用7位ASCII編碼。爲了使該功能可以使用Unicode輸入,您需要轉義序號> = 128的任何字符。例如,在Wikipedia Rich Text Format頁面中描述了轉義。我會把它作爲一個練習給你!


之前,你走得更遠,你需要閱讀馬可坎圖的白皮書:Delphi and Unicode

+0

謝謝大衛。以上所有錯誤都解決了我肯定會閱讀那篇論文。 – Nalu

4
  1. ''OemToChar()'在'Winapi.Windows.pas'中聲明,就像IDE所說的一樣。確保您的uses子句包含Winapi.Windows,或者Winapi包含在項目選項的項目「單元範圍名稱」字段中,如果uses子句包含「Windows」而不是(因爲您正在遷移它可能會這樣做)。

  2. 在D2009 +中,OemToChar()現在映射到OemToCharW(),而不是OemToCharA()了。這兩個函數的第一個參數是PAnsiChar。在D2009 +,PChar映射到PWideChar現在,不要PAnsiChar了,所以需要相應地重新寫你的代碼,例如:

    function OemToAnsi(const Str: AnsiString): string; 
    var 
        S: String; 
    begin 
        SetLength(S, Length(Str)); 
        OemToChar(PAnsiChar(Str), PChar(S)); 
        Result := PChar(S); 
    end; 
    

    然而,你應該重新思考爲什麼你仍然需要處理OEM串首先。它們在Unicode世界中沒有多少意義,甚至很少用在Ansi世界中。

  3. 另一種情況下,由於字符範圍比Ansi字符範圍大得多,所以您現在需要重新編寫代碼以解釋Char=WideChar。你我會用序數,而不是(你也應該採取UTF-16替代品考慮正確的,但我會離開,作爲一個練習吧),例如:

    function StrToRichText(const Str: string): string; 
    var 
        i: integer; 
    begin 
        Result := ''; 
        for i := 1 to Length(Str) do 
        begin    
        case Ord(Str[i]) of 
         128..255: 
         Result := Result + '\''' + LowerCase(IntToHex(Ord(Str[i]), 2)); 
         Ord('\'), Ord('{'), Ord('}'): 
         Result := Result + '\' + Str[i]; 
        else 
         Result := Result + Str[i]; 
        end; 
        end; 
    end; 
    
+0

是結果:= PChar(S)需要嗎?輸出可以是比輸入更短的字符串嗎? –

+0

Winapi包含在項目選項中的「單元範圍名稱」字段中,但我仍然無法打開任何文件。 (需要任何的微調環境設置? – Nalu

+1

聲音像IDE的庫路徑配置不正確 –

1

關於Unicode的你已經去過解決。谷歌還有很多文章。


我也建議你閱讀有關類幫手和助手記錄 - 這可能會幫助你重新引入庫中一些過時的功能和延緩代碼庫的重新工作。

這也可以幫助你重寫這樣的錯誤

var r: TRect; 
.... 
    with r do begin 
.... 
    B := IntersetRect(A1, A2); 
.... 
    end; 

關於OemToChar - 我來賓T優最好用方便的包裝,分別給予在RxLib在Delphi 5次,然後你」 d遷移到Jedi Code Library,你的代碼就不會有這個問題。

但是現在你在XEn--你完全可以沒有這種生活。
http://docwiki.embarcadero.com/Libraries/XE2/en/System.SetCodePage

var sa, so: RawByteString; 
.... 
    sa := source; SetCodePage(sa, GetACP(), true); 
    so := sa;  SetCodePage(so, GetOEMCP(), true); 

類似的代碼可在我的項目,我在那裏解析傳統的二進制數據。

如果你只關心一個單一的區域設置,那麼你可能會硬編碼這個。

var sa: AnsiString[1251]; so: AnsiString[866]; su: UnicodeString; 
.... 
    sa := source; 
.... 
    su := sa; // Win32: MultiByteToWideCharBuf - official Microsoft way 
    so := su; // Win32: WideCharToMultiByteBuf - official Microsoft way 
.... 
    so := sa; // double conversion in one step 
    // did not tested, but should work accorrding to doc. 
    // looks like obsolete Win16 OemToChar 
    // and like codepage-to-codepage direct transcoding 
    //  routines from JCL.SF.NET