OpenOffice COM Automation:クリップボードコンテンツの読み取り

パート1(最後ではなく)


長い間、私にとって、OpenOfficeはそれ自体のものでした。 pythonとbasicによって完全に自動化されていることは知っていましたが、PHPには適切なツールが見つかりませんでした。 偶然、OpenOfficeのこのような興味深い機能を発見しました。それは、Windowsクリップボードのコンテンツにアクセスすることです。 それから、PHP言語のバッファ内のテキストを処理する簡単なCLIスクリプトを書く機能が本当に不足していました。 そのため、WindowsからWindowsを使用してオープンオフィスを操作する方法を徹底的に把握することにしました。


ここに解決策があります


<?php // PHP OpenOffice:   COM- $oo = new COM("com.sun.star.ServiceManager"); $clipboard = $oo->CreateInstance( "com.sun.star.datatransfer.clipboard.SystemClipboard"); $converter = $oo->CreateInstance("com.sun.star.script.Converter"); $contents = $clipboard->getContents(); $flavors = $contents->getTransferDataFlavors(); $result = false; foreach ($flavors as $mm) { $mime = $mm->MimeType; // echo "$mime\r\n"; // DEBUG if ($mime=="text/plain;charset=utf-16") { $data = $contents->getTransferData($mm); // "com.sun.star.uno.TypeClass.STRING" ==> 12 $result = $converter->convertToSimpleType($data, 12); break; } } echo $result; 


すべての仕組み


最初に、バッファコンポーネント"com.sun.star.datatransfer.clipboard.SystemClipboard"を直接作成するために機能しないため、バッファおよびコンバータコンポーネントを接続するために必要なサービスマネージャコンポーネント"com.sun.star.ServiceManager"が作成され"com.sun.star.datatransfer.clipboard.SystemClipboard" 。 マネージャーはUNOインターフェイス関数への呼び出しをディスパッチする責任があります。 その結果、より高い「インスタンス」へのCreateInstance()リクエストに応じて、必要なCOMコンポーネントの本格的なインスタンスを取得します。
バッファーの内容は、 getContents()メソッドによって取得されます。 このコンテンツは非常に巧妙に配置され、いくつかの異なる形式(味と色)で表示されます。 形式フレーバーの完全なセットはgetTransferDataFlavors()メソッドgetTransferDataFlavors()ます。 その結果、 foreach (..as..)で要素をforeach (..as..)できる複合オブジェクトができました。

また、各要素自体もlessになります。 MimeTypeプロパティは、コンテンツのタイプを決定します。 このタイプのコンテンツは、通常の文字列として返されます。 "text/plain;charset=utf-16"のみ興味があり"text/plain;charset=utf-16"

ポータブルバッファデータ自体を取得するには、 getTransferData()メソッドが必要です。

そして、ここで最初の不幸が私たちを待っています:


単純なテキスト値であるMimeTypeとは異なり、メソッドの結果は文字列として表示されず(その後iconv()関数によって目的のエンコーディングにトランスコードされる可能性があります)、 バリアント型として表示されます。 。

これはおそらく、テキストコンテンツに加えて、バッファーに画像、音楽、およびその他のマルチメディアを含めることができ、文字列として出力することが必ずしも適切ではないためです。

変換


この問題は、マネージャーによって作成される特別なコンバーターコンポーネント"com.sun.star.script.Converter"によって解決されます。

コンバーターには、バリアント値を単純型convertToSimpleType()に変換するメソッドがあります。このメソッドは、バリアント自体にフィードし、通常の行に対応する「マジック」定数12"com.sun.star.uno.TypeClass.STRING" )を渡します。

しかし、ここに2つ目の問題があります。


その結果、 Windows-1251でエンコードされた文字列が生成され、元の文字が(Unicodeエンコードで)歪んだり失われたりする可能性があります。

免責事項


私の意見では、解決策は非常にエレガントであることが判明しましたが、実際のプログラミングの達人から反対の反応を得ることが期待されています。バッファからテキストを読み取るだけのオフィスCOMオートメーション。

一般的に、このトピックの場所はQ&Aブログにあるべきであり、その内容は「完全な」記事のサイズに人為的に膨らまされました。

残念ながら、Habra-Sandboxインターフェースでは、投稿の公開に優先ブログを指定する方法はありません。
また、 読み取り専用アカウントからは、Habrauserの誰かに直接Q&Aブログに質問を投稿するよう求める手紙を書く方法はありません。

質問自体は次のとおりです。


1. Windowsクリップボードのコンテンツにアクセスする他の方法はありますか? 問題を解決するためのいくつかの異なる方法の選択肢と、システムにインストールされている特定の追加ソフトウェアに応じて、利用可能な任意の方法でバッファーの内容に自動的にアクセスする機能の選択肢が読者に提供された場合、記事はより興味深いものになります。 つまり、ある種のクロスプラットフォーム(必要に応じて、「クロスオフィス」)を提供することです。

2.さて、私たちはどういうわけかバッファの読み方を学びましたが、このバッファに何かを書き込むにはどうすればいいのでしょうか? 私はすぐに、バッファに書き込むという決定がそれほどエレガントで透明に見えないことを警告する必要があります。 少なくとも、この問題の解決策を「循環」させることはできませんでした。 そして、もちろん、本格的な記事では、逆の操作の説明が存在することが必要です。 繰り返しになりますが、私はまずテキストバッファーの内容読み取る必要があることを繰り返しますが、 Windows-1251のエンコードは私の食欲と完全に一致していました。

3.バッファのテキストコンテンツですべてが明確な場合、 グラフィックスはどうですか? たとえば、バッファのグラフィックコンテンツをGD2オブジェクトの形式で取得し、さらに、バッファに直接「描画」できるようにします。つまり、バッファのコンテンツをGD2オブジェクトの状態と同期できるようにします。 Windows 98の時代でさえ、友人の1人が、再生モードでMedia PlayerからコピーしたFILMをクリップボードからMsPaintに貼り付けることで、私に永続的な印象を与えた方法を覚えています。 開いているドローイングの背景に動いている画像を見たとき、私はただショックを受けました。 当時、私はまだWindowsがどのように機能するかについてよく理解していなかったので、これを本当の魔法だと思っていました。

PS


もちろん、任意のタイプのコンテンツへのユニバーサルな読み取り/書き込みアクセスについて説明している場合、この記事はより便利です。たとえば、特定のタイプのコンテンツを対応する形式のファイルにエクスポートできます。

このトピックがまだHabraサンドボックスから抜けられない場合は、この記事の興味のある読者からQ&Aブログに転送されたこれらすべての質問に対する回答、または少なくともこれらの質問自体に対するコメントへのコメントを見つけてください。

インスピレーションの信頼できる情報源へのリンクを提供しなかったことを告白し、このコメントがコメントで補われることを願っています。

Source: https://habr.com/ru/post/J133990/


All Articles