2

この手順を使用して、キーを Delphi 7 の TNTListView (UNICODE) に ENUM します。

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) のようなものがありませんか?

手伝ってくれてありがとう。

編集: バッファをワイド文字列にキャストすると、バッファが半分にトリミングされることに気付きました。

EDIT2: リストビューにバグはありません。WideString キャストは何らかの方法で文字列を分割するか、NULL CHAR を検出しません。

4

1 に答える 1

4

その通りです。Unicode 以前の Delphi では、文字列の長さを半分にキャストarray of WideCharします。WideString

Delphi 2007 でテスト済み:

var
  A: array of WideChar;

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

デバッガーの CPU ウィンドウで上記のコードを簡単に確認すると、型キャストarray of WideChar->WideStringがデータ変換を行わないことがわかります。内部 WideString 形式は、Delphi 文字列または dynarray がlengthを格納するのと同じ場所に文字列サイズ(つまり、バイト数)を格納します。その結果、型キャストは文字列の長さを半分にします。

于 2012-09-26T08:08:02.593 に答える