1

这是我在 2009 年之前在 Delphi 中工作的代码?它要么最终在SetAsHandle上引发堆错误。如果我将其更改为按原件使用 AnsiString,即

procedure RTFtoClipboard(txt: string; rtf: AnsiString);

Data := GlobalAlloc(GHND or GMEM_SHARE, Length(rtf)*SizeOf(AnsiChar) + 1);

那么没有错误,但剪贴板是空的。

完整代码:

unit uClipbrd;

interface

procedure RTFtoClipboard(txt: string; rtf: string);

implementation

uses
  Clipbrd, Windows, SysUtils, uStdDialogs;
VAR
  CF_RTF : Word = 0;

//------------------------------------------------------------------------------
procedure RTFtoClipboard(txt: string; rtf: string);
var
  Data: Cardinal;
begin
  with Clipboard do
  begin
    Data := GlobalAlloc(GHND or GMEM_SHARE, Length(rtf)*SizeOf(Char) + 1);
    if Data <> 0 then
      try
        StrPCopy(GlobalLock(Data), rtf);
        GlobalUnlock(Data);
        Open;
        try
          AsText := txt;
          SetAsHandle(CF_RTF, Data);
        finally
          Close;
        end;
      except
        GlobalFree(Data);
        ErrorDlg('Unable to copy the selected RTF text');
      end
    else
      ErrorDlg('Global Alloc failed during Copy to Clipboard!');
  end;
end;

initialization
  CF_RTF := RegisterClipboardFormat('Rich Text Format');
  if CF_RTF = 0 then
    raise Exception.Create('Unable to register the Rich Text clipboard format!');
end.
4

1 回答 1

0

引用维基百科

RTF 是一种 8 位格式。这会将其限制为 ASCII,但 RTF 可以通过转义序列对 ASCII 以外的字符进行编码。字符转义有两种类型:代码页转义和 Unicode 转义。在代码页转义中,撇号后面的两个十六进制数字用于表示取自 Windows 代码页的字符。例如,如果存在指定 Windows-1256 的控制代码,则序列 \'c8 将对阿拉伯字母 beh (ب) 进行编码。

如果需要 Unicode 转义,则使用控制字 \u,后跟一个 16 位有符号十进制整数,给出 Unicode 代码点编号。对于不支持 Unicode 的程序,它后面必须跟在指定代码页中该字符的最接近的表示。例如,\u1576? 将给出阿拉伯字母 beh,指定不支持 Unicode 的旧程序应将其呈现为问号。

因此,您使用 AnsiString 的想法很好,但您还需要用 Unicode 转义符替换所有非 ASCII 且不属于当前 Ansi Windows 代码页的字符。理想情况下,这应该是另一个功能。您将数据写入剪贴板的代码可以保持不变,唯一的变化是使用 Ansi 字符串类型。

于 2009-05-27T20:10:39.127 回答