我正在尝试将一些旧的Delphi 7代码转换为Delphi 2010

function AnsiToDOS(S: String): String;
begin
  SetLength(Result, Length(S));
  if S <> '' then begin
     CharToOEM(PChar(S), PChar(Result));
  end;
end;

我在行中收到“不兼容的类型:'Char'和'AnsiChar'”错误:

在以下位置找到CharToOEM(外部User32函数)

Windows.pas单元

我可以以某种方式重写此AnsiToDos函数,还是需要编写自己的CharToOEM例程?

最佳答案

在Unicode Delphi中,CharToOem映射到具有以下签名的Unicode版本CharToOemW:

function CharToOem(Source: PWideChar; Dest: PAnsiChar): BOOL; stdcall;

因此,您需要提供一个ANSI输出缓冲区,但是您的代码提供了一个Unicode输出缓冲区。

自然的转换是切换到AnsiString返回值。同时,将该函数重命名为StringToOem以更好地反射(reflect)其功能。
function StringToOem(const S: String): AnsiString;
begin
  SetLength(Result, Length(S));
  if S <> '' then begin
    CharToOem(PChar(S), PAnsiChar(Result));
  end;
end;

一种替代方法是就地转换为OEM,但是为此,您需要传递ANSI字符串并显式调用API调用的ANSI版本。
function AnsiStringToOem(const S: AnsiString): AnsiString;
begin
  Result := S;
  UniqueString(Result);
  if S <> '' then begin
    CharToOemA(PAnsiChar(Result), PAnsiChar(Result));
  end;
end;

我不得不评论说,令我惊讶的是,OEM字符集仍在现代中被积极使用。我以为它已经走了恐龙的路!

10-06 09:12