2012-03-13 11 views
6

Sto cercando di convertire qualche vecchio codice Delphi 7 a Delphi 2010Porting unicode Delphi: tipi incompatibili: errore 'Char' e 'AnsiChar' con funzioni Win32 come CharToOEM?

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

mi vengono i "tipi incompatibili: 'Char' e 'ANSIChar'" errore alla riga:

CharToOEM (User32 esterna la funzione) in

Windows.pas unità

Posso riscrivere questa funzione AnsiToDos in qualche modo, o devo scrivere la mia propria routine CharToOEM?

+0

La funzione [CharToOEM] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647473 % 28v = vs.85% 29.aspx) è [Banned] (http://msdn.microsoft.com/en-us/library/bb288454.aspx) per microsoft invece utilizzare [WideCharToMultiByte] (http: // msdn. microsoft.com/en-us/library/windows/desktop/dd374130%28v=vs.85%29.aspx). – RRUZ

+0

@RRUZ Un sacco di quelle funzioni vietate sono perfettamente ragionevoli da usare. –

+1

@DavidHeffernan preferisco seguire le raccomandazioni MSDN (quando è possibile). – RRUZ

risposta

6

In Unicode Delphi, CharToOem mappe al sito Unicode CharToOemW che ha la seguente firma:

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

Quindi è necessario fornire un buffer di output ANSI, ma il codice fornisce un buffer di uscita Unicode.

La conversione naturale consiste nel passaggio a un valore di ritorno AnsiString. Allo stesso tempo, rinominata la funzione come StringToOem per riflettere meglio ciò che fa.

function StringToOem(const S: String): AnsiString; 
begin 
    SetLength(Result, Length(S)); 
    if S <> '' then begin 
    CharToOem(PChar(S), PAnsiChar(Result)); 
    end; 
end; 

Un'alternativa sarebbe quella di convertire in OEM in atto, ma per questo è necessario passare in una stringa ANSI e chiamare la versione ANSI della chiamata API in modo esplicito.

function AnsiStringToOem(const S: AnsiString): AnsiString; 
begin 
    Result := S; 
    UniqueString(Result); 
    if S <> '' then begin 
    CharToOemA(PAnsiChar(Result), PAnsiChar(Result)); 
    end; 
end; 

Devo commentare che sono sorpreso di vedere il set di caratteri OEM ancora utilizzato attivamente nei giorni moderni. Pensavo che fosse andata alla maniera dei dinosauri!

+3

Se stai modificando le stringhe sul posto, non dimenticare di chiamare prima "UniqueString". – hvd

+0

@hvd grazie, mi sono perso! –

+0

Da quando le console diventano dinosauri? – OnTheFly

-1

Il più semplice sarà (in C++ Builder):

typedef AnsiStringT<850> OEMString; 
AnsiString (or String) aStr = L"my ansi text"; 
OEMString oStr = aStr; // convert 
cout << oStr.c_str() << endl;