How to copy RTF string to clipboard in delphi 2009?

Here is my code that worked in Delphi until 2009? It either ends up throwing a heap error on SetAsHandle . If I change it to use AnsiString as per the original, that is

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

      

and

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

      

then there is no error, but the clipboard is empty.

Complete code:

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


a source to share


1 answer


To quote from Wikipedia :

RTF is an 8-bit format. This would restrict it to ASCII, but RTF can encode non-ASCII characters using escape sequences. Character expressions are of two types: page screen escapes and Unicode escapes. In the code escape sequence, two hexadecimal digits after the apostrophe are used to denote a character taken from the Windows code page. For example, if control codes indicating Windows-1256 are present, \ c8 would encode the Arabic letter character (ุจ).

If Unicode escape is required, the control word \ u is used, followed by a 16-bit signed decimal integer indicating the Unicode code number. For non-Unicode programs, this must be followed by the closest representation of that character in the specified code page. For example, \ u1576? will give an Arabic literal character, indicating that older non-Unicode programs should do so as a question mark.



So, your idea to use AnsiString is good, but you will also need to replace all characters that are not ASCII and are not part of the current Ansi Windows code page with Unicode screens. Ideally, this should be a different function. Your code for writing data to the clipboard can remain the same, with the only change to use the Ansi string type.

0


a source







All Articles