这是我的代码在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.
答案 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字符串类型。