1

在 Delphi XE 中,我正在从剪贴板中捕获 CF_UNICODETEXT 数据。结果是一个以两个空字节结束的流。要获取复制到剪贴板的实际字符串,我需要去除空值。

这个类似的问题包含一个从 TMemoryStream 转换为 Delphi 的 unicode 字符串的好方法:

function MemoryStreamToString(M: TMemoryStream): string;
begin
  SetString(Result, M.Memory, M.Size div SizeOf(Char));
end;

然而,在我的情况下,这将产生一个包含尾随空值的字符串。我可以通过限制大小来解决这个问题:

function ClipboardMemoryStreamToString(M: TMemoryStream): string;
begin
  SetString(Result, M.Memory, (M.Size - SizeOf(Char)) div SizeOf(Char));
end;

...但这感觉很难看,“特殊情况”。我想知道是否有一种更简洁的方式来编写代码,这样以后查看代码的任何人(我!)都不会立即问“为什么从流中删除尾随字符?”

编辑:先发制人的问题的一种方法是添加评论。但是,除此之外呢?

4

2 回答 2

5

有什么问题Clipboard.AsText?它为您完成所有工作,无需流、戳字节、处理空终止符等。

至于您提出的确切问题,我会简单地写:

SetString(Result, M.Memory, M.Size div SizeOf(Result[1]) - 1);
于 2011-01-19T18:02:03.403 回答
2

如果您以 CF_UNICODETEXT 为目标,则需要专门指定unicode字符串:

// For old Delphi versions
{$IFNDEF UNICODE}
type
  UnicodeString = WideString;
{$ENDIF}

// For CF_TEXT
function MemoryStreamToAnsiString(M: TMemoryStream): AnsiString;
begin
  SetString(Result, M.Memory, M.Size);
  if (Result <> '') and (Result[Length(Result)] = #0) then
    SetLength(Result, Length(Result) - 1);
end;

// For CF_UNICODETEXT
function MemoryStreamToUnicodeString(M: TMemoryStream): UnicodeString;
begin
  SetString(Result, M.Memory, M.Size div SizeOf(WideChar));
  if (Result <> '') and (Result[Length(Result)] = #0) then
    SetLength(Result, Length(Result) - 1);
end;

// I'm not sure that you should use this form
function MemoryStreamToString(M: TMemoryStream): String;
begin
  SetString(Result, M.Memory, M.Size div SizeOf(Char));
  if (Result <> '') and (Result[Length(Result)] = #0) then
    SetLength(Result, Length(Result) - 1);
end;

如果您 100% 确定该字符串是以零结尾的,那么:

// For CF_TEXT
function MemoryStreamToAnsiString(M: TMemoryStream): AnsiString;
begin
  SetString(Result, M.Memory, M.Size - 1);
end;

// For CF_UNICODETEXT
function MemoryStreamToUnicodeString(M: TMemoryStream): UnicodeString;
begin
  SetString(Result, M.Memory, (M.Size div SizeOf(WideChar)) - 1);
end;

function MemoryStreamToString(M: TMemoryStream): String;
begin
  SetString(Result, M.Memory, (M.Size div SizeOf(Char)) - 1);
end;
于 2011-01-20T00:06:10.470 回答