如何在delphi 2009中将RTF字符串复制到剪贴板?

时间:2009-05-27 11:12:45

标签: delphi winapi delphi-2009 clipboard

这是我的代码在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.

1 个答案:

答案 0 :(得分:0)

引用Wikipedia

  

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

     

如果需要Unicode转义,则使用控制字\ u,然后使用16位带符号十进制整数,给出Unicode代码点编号。为了没有Unicode支持的程序的好处,必须在指定的代码页中跟随此字符的最近表示。例如,\ u1576?会给出阿拉伯字母beh,指明没有Unicode支持的旧程序应该将其作为问号呈现。

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