4

Delphi 5 アプリケーションを Delphi XE3 に移行しています。コンパイル中にエラーが発生します。誰かがこれらを解決するのを手伝ってくれませんか。事前に助けてくれてありがとう。

  1. XE3で関数の定義を見つけることができませんOemToChar。その機能を Ctrl+Click すると、メッセージが表示されます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;
4

3 に答える 3

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のリッチテキスト形式のページで説明されています。それはあなたの練習問題として残しておきます!


さらに先に進む前に、MarcoCantùのホワイトペーパーであるDelphiとUnicodeを読む必要があります。

于 2012-12-10T21:46:09.350 に答える
4
  1. 「OemToChar()」は、IDE が言うように「Winapi.Windows.pas」で宣言されています。uses句に が含まれていることを確認するWinapi.WindowsWinapi、句に「Windows」が含まれている場合は、プロジェクト オプションのプロジェクトの「ユニット スコープ名」フィールドに含まれていることを確認しますuses(移行しているため、そうなる可能性があります)。

  2. D2009+ では、もはやではなく現在にOemToChar()マップされます。両方の関数の最初のパラメーターは. D2009+ では、現在ではなく現在にマップされるため、それに応じてコードを書き直す必要があります。たとえば、次のようになります。OemToCharW()OemToCharA()PAnsiCharPCharPWideCharPAnsiChar

    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. Char=WideChar文字範囲が Ansi 文字範囲よりもはるかに大きいため、コードを書き直す必要がある別のケースです。代わりに序数を使用します (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;
    
于 2012-12-10T21:56:35.627 に答える
1

Unicode については、すでに対処済みです。グーグルにもたくさんの記事があります。


また、クラス ヘルパーとレコード ヘルパーについても読むことをお勧めします。これは、廃止された関数をライブラリに再導入したり、コードベースの再作業を遅らせたりするのに役立つ可能性があります。

これは、次のようなエラーをオーバーライドするのにも役立つ場合があります

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

に関して-Delphiで5回OemToChar提供された便利なラッパーを使用することをお勧めします。その後、移行すると、コードにその問題が発生しなくなります。RxLibJedi 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);

私のプロジェクトでも同様のコードが機能し、レガシーバイナリデータを解析しています。

1 つのロケールだけに関心がある場合は、おそらくこれをハードコーディングできます。

 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
于 2012-12-11T11:19:06.697 に答える