質問者
C#でピクチュアボックス内のイメージを他アプリへドラッグアンドドロップすること

質問
-
C#のWindowsアプリからドラッグアンドドロップすることにおいて。
テキストなどの例題はしばしば見かけますが、ピクチュアボックスのイメージを扱う例題をみかけることがありません。
ドロップ先のアプリはワード、エクセル、ワードパッド等です。
教科書の教える通り、
pictureBox1.doDragDrop(pictureBox1.image,AllowedEffects.Copy);
等とやります。イメージはBitmapオブジェクトを入れているつもりです。
問題:エクセルとワードパッドはドロップを受け付けてくれるのですが、ワードだけは受け付けてくれません。
解決方法が見つからず困り果てています。どなたかお知恵を拝借できませんでしょうか。
すべての返信
-
ダッチです。
ひろせわじん さんからの引用 問題:エクセルとワードパッドはドロップを受け付けてくれるのですが、ワードだけは受け付けてくれません。
解決方法が見つからず困り果てています。どなたかお知恵を拝借できませんでしょうか。
ワードとエクセルとではドラッグアンドドロップで受け取れるフォーマットが違うためにワードだけドロップできないのでしょう。
多分、ワードはメタファイルなどのみ受け付けているのではないでしょうか。(仕様が記載されている文書を見つけられません。)そのため、ドラッグアンドドロップで渡すオブジェクトをワードで受け取れるフォーマットに変換すれば可能だとは思うのですが、ちょっと私にはわかりません。
しかし、別解としてワードに画像ファイルのパスを渡すという方法があります。
ワードもエクセルと同じように受け取れれば一番いいんですけどね。
-
コメントありがとうございます。
ご参考までに、仕様が記述されている文書は以下のとおりです。
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.control.dodragdrop(VS.80).aspx
そこには以下の解説があります。
ドラッグ操作が別のプロセスのアプリケーションと相互運用する必要がある場合、データは、基本マネージ クラス (String、Bitmap、または Metafile)、あるいは ISerializable または IDataObject を実装するオブジェクトのいずれかである必要があります。
ところで、面白いことに(悔しいことに)、画像イメージを私のアプリからドラッグしてエクセルにドロップした後、それを引き続きワードにドラッグドロップはできるのです。ソフト素人の私には、エクセルがデータを少々良い方向に変形してくれるように見えます。
-
ドラッグアンドドロップの仕様書について、私はワードはこのフォーマットに対応しています。というのが記載されている文書が見つからないです。
といいたかったんですけど、ひろせわじん さんの示していただいた文書がワードにも当てはまりそうですね。
ありがとうございます。ひろせわじん さんからの引用 ところで、面白いことに(悔しいことに)、画像イメージを私のアプリからドラッグしてエクセルにドロップした後、それを引き続きワードにドラッグドロップはできるのです。ソフト素人の私には、エクセルがデータを少々良い方向に変形してくれるように見えます。 これは実際にやってみるといいですね。
pictureBox1.doDragDrop(pictureBox1.image,AllowedEffects.Copy);
このコードでドラッグアンドドロップしたときのフォーマットは下記のとおりでした。
(0): "WindowsForms10PersistentObject"
(1): "System.Drawing.Bitmap"
(2): "Bitmap"次にエクセルから画像をドラッグアンドドロップされたときのフォーマットは下記のとおりでした。
(0): "Office Drawing Drag-Drop Format"
(1): "Office Drawing Shape Format"
(2): "GIF"
(3): "Object Descriptor"
(4): "MetaFilePict"
(5): "EnhancedMetafile"
(6): "PNG+Office Art"
(7): "JFIF+Office Art"
(8): "GIF+Office Art"
(9): "PNG"
(10): "JFIF"
(11): "System.Drawing.Bitmap"
(12): "Bitmap"エクセルは良い方向というか様々なフォーマットに対応するようにやっているということですね。
-
しかし、単純な Bitmap を受け入れないとは考えられないなぁ。
もし引っかかるとしたら
- Alpha 値付きの Bitmap を使ってるならそれを止めてみる
- bit 数を変えてみる
なんて辺りですかね?
渋木さん、コメントありがとうございます。
VC#アプリ→エクセル→ワードの順序でドラッグドロップ出来ていますので、基本的に誤っているとは思っていないのですが。で、ビット数はさすがに問題ないと思います。Alpha値付きのBitmapって何でしょう?
それから、私はソフトに日が浅いのでBitmapの作り方を誤っているかもしれません。次の4ステップでpictureBox1のImageプロパテイを作っていますが、問題ないでしょうか?
①Bitmap bmp=new Bitmap(W,H);
②Graphics g=Graphics.FromImage(bmp);
③g.DrawLine( ) ; エトセトラ
④pictureBox1.Image=bmp;
-
私が行ったのはまず自分のアプリからエクセルにドラッグアンドドロップで画像を貼り付けます。
次に自分のアプリに対してエクセルからドラッグアンドドロップを行います。
その時フォームの DragEnter イベントでこのようなコードを記載し formats の中身をのぞいた結果を出力しただけです。
実際にやったのは VB ですが。
private void Form1_DragEnter(object sender, DragEventArgs e)
{
string[] formats = e.Data.GetFormats();
}同じようにしてワードから自分のアプリにやってみましたが、エクセルと同じ結果が得られました。
渋木宏明 さんからの引用 もし引っかかるとしたら
- Alpha 値付きの Bitmap を使ってるならそれを止めてみる
- bit 数を変えてみる
Bitmap を生成する際に PixelFormat を全て試してみましたが、ワードには一つも受け付けてくれませんでした。
エクセルへは正常に Bitmap を生成できた PixelFormat はほぼ全てドラッグアンドドロップで画像が貼りつきました。Bitmap をドラッグアンドドロップでワードに渡すのは無理なんでしょうかね。
-
ダッチ さんからの引用
Alpha値付きのBitmapって何でしょう?ビットマップを構成する各ピクセルの色情報である RGB 値だけでなく、透明度(=Alpha 値)も格納するタイプのビットマップです。
詳細は、PixelFormat について調べてみてください。
ダッチ さんからの引用
Bitmap を生成する際に PixelFormat を全て試してみましたが、ワードには一つも受け付けてくれませんでした。
エクセルへは正常に Bitmap を生成できた PixelFormat はほぼ全てドラッグアンドドロップで画像が貼りつきました。Bitmap をドラッグアンドドロップでワードに渡すのは無理なんでしょうかね。
ガイドラインを忘れてしまいましたが、「画像」をクリップボードに入れる際は Bitmap だけでなくメタファイルも入れなきゃでしたかねぇ。
それならまぁ、Word の挙動も間違っては居ないことになります。
-
渋木宏明 さんからの引用 ダッチ さんからの引用
Alpha値付きのBitmapって何でしょう?ビットマップを構成する各ピクセルの色情報である RGB 値だけでなく、透明度(=Alpha 値)も格納するタイプのビットマップです。
詳細は、PixelFormat について調べてみてください。
私の発言じゃないですよ。
質問者の ひろせわじん さんの発言です。渋木宏明 さんからの引用 ガイドラインを忘れてしまいましたが、「画像」をクリップボードに入れる際は Bitmap だけでなくメタファイルも入れなきゃでしたかねぇ。 PRB: クリップボードのメタファイルは、すべてのアプリケーションに表示されません。
この内容のことですよね。
同じようにしてドラッグアンドドロップする Image オブジェクト を「CF_ENHMETAFILE 形式」に変換できれば、多分成功するのではないか?
と思っているのですが、そのやり方が不明です。私にはこれ以上どうすることも出来ません。
-
勉強がてら、試してみました。
(1)ダッチさんのやり方でC#アプリから出発するとこのデータ形式とエクセルから戻ってくるときのデータ形式の確認。
→ダッチさんの結果でした。
(2)見よう見真似で、DataObjectクラスにエクセルから戻ってきたのと同じフォーマットを加える(setDataメソッド)ようなことを試みましたが、ワードもエクセルもドロップを受け付けてくれませんでした。
(3)当面の結論として、ダッチさんの言われるように「ワードはC#アプリから直接ビットマップ形式をドラッグアンドドロップされない」と思うことにしました。
(4)以前にご紹介のあった「ビットマップデータを任意のファイルへバッファ格納し、そのファイルパスをワードへドラッグドロップする」という手法を動作確認しました。中間のバッファメモリを使うというのがやや気持ち悪いですが、ユーザからみて同じ感覚で操作出来ますので、当面これでよしと満足することとしました。(実はこれもOffice2000では成功しなかったが、Office2002でやっと成功したというオチがありました。いやはやソフトはむつかしい)。
(5)私のC#ソフト力は、小学校(入門)~大学(プロ)に例えれば、おそらく初年を脱して2・3年生くらいかと思います。今後、中学生~高校初年くらいのレベルに到達したいなと、勉強します。みなさんありがとうございました。ひろせわじん