2

我使用此过程将密钥枚举到 Delphi 7 中的 TNTListView (UNICODE)

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;

我看到大多数列表视图项都被修剪了!但是,如果我在消息框中显示缓冲区,它会以正确的长度显示完整的字符串。这是列表视图的错误还是我错过了 NULL CHAR(甚至 2)之类的东西?

感谢帮助。

编辑:我刚刚注意到,当我将 Buffer 转换为宽字符串时,它被修剪成一半。

EDIT2:列表视图中没有错误。WideString Cast 以某种方式破坏了字符串和/或没有检测到 NULL CHAR(s)。

4

1 回答 1

4

你是对的 - 在 Unicode 之前的 Delphi 中强制array of WideCharWideString字符串长度减半。

在 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.

于 2012-09-26T08:08:02.593 回答