Delphi FireMonkeyを使用して、HTML形式の文字列をDelphiのクリップボードにコピーして、貼り付けた他のアプリケーションがHTMLとして表示できるようにする必要があります。
非表示のメモコンポーネントを介して単純なテキストをコピーしようとしていますが、機能しますが、単純なテキストとしてコピーされます。HTML形式のコピーが必要です。テキストとして持つと、リッチテキストプログラムに貼り付けると、フォーマットされたテキストではなく、すべてのHTMLタグが表示されます。
テキストをクリップボードにコピーするための私の現在のアプローチは次のとおりです。
procedure TForm1.Button1Click(Sender: TObject);
var
SourceText: string;
begin
SourceText := 'This is a <b>bold</b> html line';
//I can use TMemo to copy it to clipboard like:
Memo1.lines.Text := SourceText;
Memo1.SelectAll;
memo1.CopyToClipboard;
end;
しかし、問題は、クリップボードにコピーしたテキストをMicrosoft Wordで貼り付けると、次のように貼り付けられることです。
「これは<b>bold</b>
html行です」。私が欲しいとそれは次のようになるはずです:
これは太字のhtml行です
注: Windowsでどのように実行できるかについて他の説明を読みましたが、クロスプラットフォームアプリケーション用のFiremonkeyソリューションが必要です。どんな助けでも大歓迎です。
FireMonkeyを使用してクロスプラットフォームでクリップボードにデータをコピーするにはIFMXExtendedClipboardService
、プラットフォームサービスを呼び出して取得したインターフェイスを使用します。
var
Svc : IFMXExtendedClipboardService;
begin
if not TPlatformServices.Current.SupportsPlatformService(IFMXExtendedClipboardService, Svc) then
Exit; // Not clipboard supported
// Code using the interface
このインタフェースは、クリップボードから/へテキスト/画像を取得する/コピーする方法がありますSetText
、GetText
、SetImage
、GetImage
。
データの他の種類については、ユーザーがデータ・フォーマットを登録する必要があり、その後、書き込み/クリップボードから/にデータを読み込みます:RegisterCustomFormat
、IsCustomFormatRegistered
、UnregisterCustomFormat
、HasCustomFormat
、GetCustomFormat
、SetCustomFormat
。
あなたの質問では、HTML形式のデータをクリップボードにコピーしたいとします。これを変換して、HTML形式を登録し、データを使用してストリームを作成し、SetCustomFormatを呼び出して形式とストリームを渡すことができます。
上記のインターフェース方法を使用して、任意のフォーマットを使用し、クリップボードとの間で送信することができます。以下のコードは、ストリームstream
を取得し、次を使用してコンテンツをクリップボードにコピーしますClipFormat
。
if TPlatformServices.Current.SupportsPlatformService(
IFMXExtendedClipboardService, Svc) then begin
if not Svc.IsCustomFormatRegistered(ClipFormat) then
Svc.RegisterCustomFormat(ClipFormat);
Svc.SetCustomFormat(ClipFormat, Stream);
end;
フォーマットは一度だけ登録する必要があるため、複数回のIsCustomFormatRegistered
呼び出しを防ぐためにを呼び出しRegisterCustomFormat
ます。
形式の名前は単純な文字列であり、何でもかまいません。アプリケーションのコピーと貼り付けでは、形式名とデータ形式(データがストリームに書き込まれる方法)について合意する必要があります。
HTML形式のデータの書き込みは、スタイルが原因で難しい場合があります。完全なHTMLドキュメントの単純なコピーを作成するだけでは、スタイルが原因で正しくレンダリングされない可能性があります。
2つのアプリケーション間でクリップボードを介してデータを転送する場合は、何でもできます。ただし、アプリケーションと別のアプリケーション(質問でMicrosoft Wordについて言及した)の間でデータを転送することははるかに困難です。
Microsoft製品およびWindowsプラットフォーム上の他のすべての製品では、クリップボードのHTML形式についてここで説明します。
適切にフォーマットされた後の質問での例は、次のようになります。
Version:0.9
StartHTML:00000144
EndHTML:00000218
StartFragment:00000167
EndFragment:00000205
StartSelection:00000167
EndSelection:00000205
<!DOCTYPE><HTML><BODY><P>This is a <b>bold</b> html line</P></BODY></HTML>
実際の文字列は上記のとおりで、各行の終わりにCRLFがあります。フォーマット名は「HTMLフォーマット」です。
This is a <b>bold</b> html line
有効な完全なHTMLドキュメントを形成するには、文をHTMLタグで囲み、その前にいくつかのkeyword:value
ペアで構成されるヘッダーを付ける必要があることがわかります。文字列の場合、値はオフセットされます。キーワードは非常に自明です。文字列はUTF8であり、HTMLエンティティを使用して特殊文字を表す場合はANSIに縮小できます。
文字列全体を作成する関数を作成しました。
function FormatHtmlForClipboard(const HtmlSrc : UTF8String) : UTF8String;
const
Header = 'Version:0.9' + #13#10 +
'StartHTML:00000000' + #13#10 +
'EndHTML:00000000' + #13#10 +
'StartFragment:00000000' + #13#10 +
'EndFragment:00000000' + #13#10 +
'StartSelection:00000000' + #13#10 +
'EndSelection:00000000' + #13#10;
var
BodyStart : Integer;
BodyEnd : Integer;
HdrLen : Integer;
begin
Result := Header;
BodyStart := Pos('<BODY>', String(HtmlSrc));
if BodyStart <= 0 then
raise Exception.Create('<BODY> tag not found');
Inc(BodyStart, 6);
BodyEnd := Pos('</BODY>', String(HtmlSrc));
if BodyEnd <= 0 then
raise Exception.Create('</BODY> tag not found');
HdrLen := Length(Header) - 1;
WriteNumberIntoString(HdrLen, 'StartHTML:', Result);
WriteNumberIntoString(HdrLen + Length(HtmlSrc), 'EndHTML:', Result);
WriteNumberIntoString(HdrLen + BodyStart, 'StartFragment:', Result);
WriteNumberIntoString(HdrLen + BodyEnd, 'EndFragment:', Result);
WriteNumberIntoString(HdrLen + BodyStart, 'StartSelection:', Result);
WriteNumberIntoString(HdrLen + BodyEnd, 'EndSelection:', Result);
Result := Result + HtmlSrc;
end;
procedure WriteNumberIntoString(
N : Integer;
const At : UTF8String;
var S : UTF8String);
var
I : Integer;
V : UTF8String;
begin
I := Pos(At, S);
if I <= 0 then
Exit;
I := I + Length(At);
V := UTF8String(Format('%08.8d', [N]));
Move(V[1], S[I], Length(V));
end;
以上で、HTML形式のデータをクリップボードにコピーする関数は次のようになります。
procedure CopyHtmlToClipboard(const HtmlSrc : UTF8String);
var
Svc : IFMXExtendedClipboardService;
Stream : TStringStream;
HtmlData : UTF8String;
const
ClipFormat = 'HTML format'; // This is what Windows expect
// Maybe other platform want something else
begin
HtmlData := FormatHtmlForClipboard(HtmlSrc);
Stream := TStringStream.Create(HtmlData);
if TPlatformServices.Current.SupportsPlatformService(
IFMXExtendedClipboardService, Svc) then begin
if not Svc.IsCustomFormatRegistered(ClipFormat) then
Svc.RegisterCustomFormat(ClipFormat);
Svc.SetCustomFormat(ClipFormat, Stream);
end;
end;
次のような関数を使用する必要があります。
procedure TForm1.Button1Click(Sender: TObject);
begin
CopyHtmlToClipboard(
'<!DOCTYPE><HTML><BODY><P>' +
'This is a <b>bold</b> html line' + //<== Your actual HTML text
'</P></BODY></HTML>');
end;
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加