2012-12-10 24 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