Ben
Ben

Reputation: 3440

Typecasting WideString breaks array of widechar

I use this procedure to ENUM the keys into a TNTListView (UNICODE) in Delphi 7

procedure TForm1.TntButton1Click(Sender: TObject);
var
 k        : HKEY;
 Buffer   : array of widechar;
 i        : Integer;
 iRes     : Integer;
 BuffSize : DWORD;
 item     : TTNTListItem;
 WS       : WideString;
begin
 if RegOpenKeyExW (HKEY_CURRENT_USER, 'Software', 0, KEY_READ, K) = ERROR_SUCCESS then begin
  try
    i := 0;
    BuffSize := 1;
    while true do begin
      SetLength (Buffer, BuffSize);
      iRes := RegEnumKeyW(k, I, @Buffer[0], BuffSize);
      if iRes = 259 then break;
      if iRes = 234 then begin
        inc (BuffSize);
        continue;
      end;
      messageboxw (0, @Buffer[0], '', 0);
      item := TNTListView1.Items.Add;
      item.Caption := WideString (Buffer); // BREAKS IT
      { SOLUTION }
      SetLength (WS, BuffSize - 1);
      CopyMemory (@WS[1], @Buffer[0], (BuffSize * 2));
      { .... }
      inc (i);
      BuffSize := 1;
    end;
  finally
    RegCloseKey (k);
    SetLength (Buffer, 0);
  end;
 end;
end;

I see that most of the listviewitems are trimmed! However if I show the Buffer in the messagebox it shows the complete string in the right length. Is this a Bug of the listview or am I missing something like a NULL CHAR (or even 2)?

Thanks for help.

EDIT: I just noticed that the Buffer get's trimmed into half when I cast it to a widestring.

EDIT2: No bug in the listview. The WideString Cast breaks the string somehow and / or doesn't detect the NULL CHAR(s).

Upvotes: 2

Views: 2606

Answers (1)

kludg
kludg

Reputation: 27493

You are right - casting array of WideChar to WideString halves the string length in pre-Unicode Delphi's.

Tested on Delphi 2007:

var
  A: array of WideChar;

begin
  SetLength(A, 4);
  ShowMessage(IntToStr(Length(WideString(A)))); // 2
end;

A quick view on the above code in debugger CPU window shows that typecasting array of WideChar-> WideString does not result in any data conversion; internal WideString format stores the string size (i.e. the number of bytes) in the same place where Delphi strings or dynarrays store length. As a result typecasting halves string length.

Upvotes: 4

Related Questions