Search code examples
delphistringwidestring

Is it necessary to convert string to WideString in Delphi?


I found a Windows API function that performs "natural comparison" of strings. It is defined as follows:

int StrCmpLogicalW(
    LPCWSTR psz1,
    LPCWSTR psz2
);

To use it in Delphi, I declared it this way:

interface
  function StrCmpLogicalW(psz1, psz2: PWideChar): integer; stdcall;

implementation
  function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';

Because it compares Unicode strings, I'm not sure how to call it when I want to compare ANSI strings. It seems to be enough to cast strings to WideString and then to PWideChar, however, I have no idea whether this approach is correct:

function AnsiNaturalCompareText(const S1, S2: string): integer;
begin
  Result := StrCmpLogicalW(PWideChar(WideString(S1)), PWideChar(WideString(S2)));
end;

I know very little about character encoding so this is the reason of my question. Is this function OK or should I first convert both the compared strings somehow?


Solution

  • Keep in mind that casting a string to a WideString will convert it using default system codepage which may or may not be what you need. Typically, you'd want to use current user's locale.

    From WCharFromChar in System.pas:

    Result := MultiByteToWideChar(DefaultSystemCodePage, 0, CharSource, SrcBytes,
      WCharDest, DestChars);
    

    You can change DefaultSystemCodePage by calling SetMultiByteConversionCodePage.