简体   繁体   English

如何修复Delphi XE3迁移错误?

[英]How to fix Delphi XE3 migration errors?

I am migrating my Delphi 5 application to Delphi XE3. 我正在将我的Delphi 5应用程序迁移到Delphi XE3。 I am getting some erros while compiling it. 我在编译时得到了一些错误。 Can someone please help me to resolve these. 有人可以帮我解决这些问题。 Thanks for help in advance. 提前感谢您的帮助。

  1. I am not able to find defination of function OemToChar in XE3. 我无法在XE3中找到函数OemToChar的定义。 When I Ctrl+Click on that function it shows message Unable to locate 'WinAPI.Windows.pas' . 当我按Ctrl +单击该功能时,它显示消息Unable to locate 'WinAPI.Windows.pas' I am not able to open any delphi component file. 我无法打开任何delphi组件文件。 What is the location of windows.pas located on the system ? windows.pas位于系统上的位置是什么? or How to resolve it ? 或者如何解决?

  2. Incompatiable Types: 'PAnsiChar' and 'PWideChar' in below function on line with OemToChar(p1, p2) . 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. Getting error 'Low Bound Exceeds High Bound' in following code. 在以下代码中获取错误'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;

Your OemToAnsi function should look like this: 您的OemToAnsi函数应如下所示:

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

But perhaps you'd be better with 但也许你会更好

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

As for your StrToRichText , that looks more difficult. 至于你的StrToRichText ,看起来更难。 It clearly only accepts ANSI input. 它显然只接受ANSI输入。 If you want to stick with ANSI then just change the declaration to 如果你想坚持使用ANSI,那么只需将声明更改为

function StrToRichText(const Str: AnsiString): AnsiString;

RTF is encoded with 7 bit ASCII. RTF使用7位ASCII编码。 To make that function work with Unicode input you'd need to escape any characters with ordinal >= 128. The escaping is described, for example, on the Wikipedia Rich Text Format page. 要使该函数与Unicode输入一起使用,您需要使用ordinal> = 128转义任何字符。例如,在Wikipedia 富文本格式页面上描述了转义。 I'll leave that as an exercise for you! 我会把它作为锻炼给你!


Before you go much further you need to read Marco Cantù's white paper: Delphi and Unicode . 在你走得更远之前,你需要阅读MarcoCantù的白皮书: Delphi和Unicode

  1. 'OemToChar()' is declared in 'Winapi.Windows.pas', just like the IDE says. 'OemToChar()'在'Winapi.Windows.pas'中声明,就像IDE所说的那样。 Make sure your uses clause includes Winapi.Windows , or that Winapi is inluded in your Project's "Unit Scope Names" field in the Project Options if the uses clause includes 'Windows' instead (which it likely does since you are migrating). 确保您的uses子句包含Winapi.Windows ,或者如果uses子句包含'Windows'(自迁移后它可能会执行),则Winapi将包含在项目选项的“单元范围名称”字段中。

  2. In D2009+, OemToChar() maps to OemToCharW() now, not to OemToCharA() anymore. 在D2009 +, OemToChar()映射到OemToCharW()现在,不OemToCharA()了。 The first parameter of both functions is a PAnsiChar . 两个函数的第一个参数是PAnsiChar In D2009+, PChar maps to PWideChar now, not to PAnsiChar anymore, so you need to re-write your code accordingly, eg: 在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; 

    However, you should re-think why you still need to deal with OEM strings in the first place. 但是,您应该重新考虑为什么您仍然需要首先处理OEM字符串。 They don't make as much sense in a Unicode world, and they are rarely even used in an Ansi world. 它们在Unicode世界中没有多大意义,甚至在Ansi世界中也很少使用它们。

  3. Another case where you need to re-write the code to account for Char=WideChar now, since character ranges are much larger than Ansi character ranges. 另一种情况是你需要重新编写代码来解释Char=WideChar ,因为字符范围远大于Ansi字符范围。 You I would use ordinals instead (you should also take UTF-16 surrogates into account properly, but I will leave that as an exercise for you), eg: 你我会使用序数代替(你也应该正确地考虑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; 

About Unicode you're already been addressed. 关于Unicode,你已经被解决了。 There is also a lot of articles in google. 谷歌也有很多文章。


I also suggest you to read about class helpers and record helpers - that might help you with re-introducing some obsoleted functions in libraries, and delaying re-working of the codebase. 我还建议您阅读有关类帮助程序和记录帮助程序的内容 - 这可能有助于您在库中重新引入一些过时的函数,并延迟重新编写代码库。

That also might help you to override errors like 这也可以帮助你覆盖像

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

Regarding OemToChar - i guest t you'd better use convenient wrappers, that were given in RxLib in Delphi 5 times, then you'd migrate to Jedi Code Library and your code would just not have that problem. 关于OemToChar - i guest,你最好使用方便的包装器,这是在Delphi RxLib提供的5次,然后你将迁移到Jedi Code Library ,你的代码就没有那个问题了。

However now you're at XEn - you can perfectly live without that. 但是现在你在XEn - 没有那个你就可以完美地生活。
http://docwiki.embarcadero.com/Libraries/XE2/en/System.SetCodePage 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);

Similar code works in my project, where i parse legacy binary data. 类似的代码在我的项目中工作,我解析传统的二进制数据。

If you only care about one single locale, then you probably can hardcode this. 如果您只关心一个区域设置,那么您可能会对此进行硬编码。

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM