【问题标题】:Typecasting WideString breaks array of widechar类型转换 WideString 会破坏宽字符数组
【发布时间】:2012-09-26 06:33:41
【问题描述】:

我在 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)。

【问题讨论】:

  • 我相信有一个 maxlength 属性。
  • (BuffSize * 2) -> (BuffSize * SizeOf(WideChar))(BuffSize * SizeOf(@Buffer[0]))
  • WideString 是围绕 Microsoft COM/OLE BSTR 类型的变形器。它可能像其他 C 字符串一样是零结尾的。
  • 它是零结尾的。我只是不知道你最后需要两个 NULLCHARS(因为 UNICODE)还是只需要一个。
  • 最后只需要一个空字符,就像任何其他字符串一样。字符是两个字节宽,但凳子只有一个字符。

标签: delphi-7 delphi


【解决方案1】:

你是对的 - 将 array of WideChar 转换为 WideString 将前 Unicode Delphi 中的字符串长度减半。

在 Delphi 2007 上测试:

var
  A: array of WideChar;

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

在调试器 CPU 窗口中快速查看上述代码表明,类型转换 array of WideChar-> WideString 不会导致任何数据转换; internal WideString format 将字符串 size(即字节数)存储在 Delphi 字符串或 dynarrays 存储 length 的相同位置。结果,类型转换将字符串长度减半。

【讨论】:

  • 做什么 ShowMessage(IntToStr(Length(WideString(PWidechar(A))))); ?
  • 显示字符串长度 - 还有什么?如果你的意思是你在转换后只得到一个以零结尾的 PWideChar - 不,WideString 有一个像 Delphi 字符串一样的长度字段
  • 哪个? 2 还是 4? PWideChar 中间类型转换是否修复分裂?
  • SetLength(A, 4);分配宽字符(4 x 2 字节)大小的 4 倍,总共 8 个字节,但在 StringFormat 中它只有 4 个可打印的 UNICODE 字符。
  • 如果 RTL 真的有这个问题,那么使用SetString() 将数组复制到WideString 中,例如:var W: WideString; SetString(W, @A[0], Length(A));
猜你喜欢
  • 2013-06-29
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多