Как скопировать строку RTF в буфер обмена в Delphi 2009? - PullRequest
1 голос
/ 27 мая 2009

Вот мой код, который работал в Delphi pre 2009? Это либо приводит к тому, что выдается ошибка кучи 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 голосов
/ 28 мая 2009

Цитировать Википедия :

RTF - это 8-битный формат. Это ограничило бы его до ASCII, но RTF может кодировать символы за пределами ASCII с помощью escape-последовательностей. Экранирование символов бывает двух типов: экранирование кодовой страницы и экранирование Unicode. При экранировании кодовой страницы две шестнадцатеричные цифры после апострофа используются для обозначения символа, взятого из кодовой страницы Windows. Например, если присутствуют управляющие коды, указывающие Windows-1256, последовательность \ 'c8 будет кодировать арабскую букву beh (ب).

Если требуется экранирование Unicode, используется управляющее слово \ u, за которым следует 16-разрядное целое число со знаком, дающее номер кодовой точки Unicode. В интересах программ без поддержки Unicode, это должно сопровождаться ближайшим представлением этого символа в указанной кодовой странице. Например, \ u1576? выдаст арабскую букву beh, указав, что старые программы, которые не поддерживают Unicode, должны отображать его вместо знака вопроса.

Таким образом, ваша идея использования AnsiString хороша, но вам также необходимо заменить все символы, которые не являются ASCII и не являются частью текущей кодовой страницы Ansi Windows, на экранированные Unicode. В идеале это должна быть другая функция. Ваш код для записи данных в буфер обмена может остаться прежним, с единственным изменением для использования типа строки Ansi.

...