2012-03-13 13 views
6

Próbuję przekonwertować niektóre starego kodu Delphi 7 do Delphi 2010Delphi unicode porting: Niekompatybilne typy: błąd "Char" i "AnsiChar" z funkcjami Win32 jak CharToOEM?

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

uzyskać "niezgodne typy: 'char' i 'AnsiChar'" błąd w linii:

CharToOEM (zewnętrzny User32 funkcja) stwierdzono w

jednostki

Windows.pas

mogę przepisać tej funkcji AnsiToDos jakoś, albo muszę napisać własny rutynowych CharToOEM?

+0

Funkcja [CharToOEM] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647473 % 28v = vs.85% 29.aspx) jest [Banned] (http://msdn.microsoft.com/en-us/library/bb288454.aspx) dla Microsoft zamiast używać [WideCharToMultiByte] (http: // msdn. microsoft.com/en-us/library/windows/desktop/dd374130%28v=vs.85%29.aspx). – RRUZ

+0

@RRUZ Wiele z tych zabronionych funkcji jest całkowicie uzasadnionych w użyciu. –

+1

@DavidHeffernan Wolę przestrzegać zaleceń MSDN (jeśli jest to możliwe). – RRUZ

Odpowiedz

6

W Delphi Unicode CharToOem mapy do wersji Unicode CharToOemW który posiada następujący podpis:

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

Więc trzeba dostarczyć bufor wyjściowy ANSI ale kod stanowi bufor wyjściowy Unicode.

Naturalną konwersją jest przełączenie na wartość zwracaną AnsiString. W tym samym czasie zmieniono nazwę na StringToOem, aby lepiej odzwierciedlała to, co robi.

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

Alternatywą byłoby przekonwertować do OEM na swoim miejscu, ale do tego trzeba przejść w ciąg znaków ANSI i wywołać wersji ANSI wywołania API wyraźnie.

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

Muszę wypowiedzieć się, że jestem zaskoczony, że zestaw znaków OEM nadal jest aktywnie wykorzystywany we współczesnym świecie. Myślałem, że odstąpił od dinozaurów!

+3

Jeśli modyfikujesz ciągi w miejscu, nie zapomnij najpierw wywołać 'UniqueString'. – hvd

+0

@hvd dzięki, tęskniłem za tym! –

+0

Od kiedy konsole stały się dinozaurami? – OnTheFly

-1

Najprostszym będzie (w C++ Builder)

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