1

Delphi XEでは、クリップボードからCF_UNICODETEXTデータをキャプチャしています。結果は、2つのヌルバイトで終了するストリームです。クリップボードにコピーされた実際の文字列を取得するには、nullを取り除く必要があります。

この似たような質問には、TMemoryStreamからDelphiのUnicode文字列に変換するための優れた方法が含まれています。

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

ただし、私の場合、これにより、末尾のnullを含む文字列が生成されます。サイズを制限することでそれを修正できます:

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

...しかし、これは醜い、「特別な場合」に感じます。これをコード化するためのよりクリーンな方法があるのではないかと思います。そうすれば、後でコードを見る人(私!)がすぐに「なぜ末尾の文字がストリームから削除されるのですか?」

編集:質問を先取りする1つの方法は、コメントを追加することです。しかし、それ以外は?

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 に答える