Microsoft Officeでコピーした図をPictureBoxに表示するクリップボードのメタファイルを取得するMicrosoft Office Word、Excel、Power Pointなどで作成した図をクリップボードにコピーした時、このデータを拡張メタファイル形式として以下のような方法でデータを取得しようとしてもうまくいきません。 [VB.NET] Dim data As IDataObject = Clipboard.GetDataObject() 'クリップボードにあるデータが拡張メタファイル形式か調べる If data.GetDataPresent(DataFormats.EnhancedMetafile) Then '拡張メタファイル形式でデータを取得する PictureBox1.Image = _ CType(data.GetData(DataFormats.EnhancedMetafile), Image) End If [C#] IDataObject data = Clipboard.GetDataObject(); //クリップボードにあるデータが拡張メタファイル形式か調べる if (data.GetDataPresent(DataFormats.EnhancedMetafile)) { //拡張メタファイル形式でデータを取得する PictureBox1.Image = (Image) data.GetData(DataFormats.EnhancedMetafile); } .NET Frameworkの機能だけでは残念ながらクリップボードのメタファイルデータは取得できないようです(.NET Framework 1.1現在)。しかし、Microsoft Officeからクリップボードにコピーされたデータは、EnhancedMetafile形式の他に、Office Drawing Shape Format、MetaFilePict、PNG+Office Art、JFIF+Office Art、GIF+Office Art、PNG、JFIF、GIF、ActiveClipboard、HTML Format形式に関連付けられており、このうち、HTML Format以外はMemoryStreamオブジェクトとしてデータを取得できます。つまり、Microsoft Officeでコピーした図を、PNG形式等でデータを取得することは可能です。 次のサンプルでは、フォームにピクチャボックス"PictureBox1"があり、このPictureBox1にクリップボードにコピーされた図を表示しています。 [VB.NET] Dim data As IDataObject = Clipboard.GetDataObject() 'クリップボードにあるデータがPNG形式か調べる If data.GetDataPresent("PNG") Then 'PNG形式でデータをMemoryStreamとして取得する Dim ms As MemoryStream = CType(data.GetData("PNG"), MemoryStream) 'Imageオブジェクトに変換する PictureBox1.Image = Image.FromStream(ms) End If [C#] IDataObject data = Clipboard.GetDataObject(); //クリップボードにあるデータがPNG形式か調べる if (data.GetDataPresent("PNG")) { //PNG形式でデータをMemoryStreamとして取得する MemoryStream ms = (MemoryStream) data.GetData("PNG"); //Imageオブジェクトに変換する PictureBox1.Image = Image.FromStream(ms); } "PNG"以外の形式を試してみたところ、上記のコードで"PNG"の部分を以下の文字列に変更した場合にのみ成功するようです。 "PNG+Office Art" クリップボードのメタファイルを取得するクリップボードのメタファイルデータをメタファイルとして取得するには、Win32 APIを使うしかないようです(.NET Framework 1.1現在)。この方法は、「Windows Forms FAQ - 37.5 How can I programmatically create a bitmap?」で紹介されています。 以下にWin32 APIを使用してクリップボードのメタファイルデータを取得するコードを紹介します。 [VB.NET] 'Imports System.Runtime.InteropServices Const CF_ENHMETAFILE As Integer = 14 <DllImport("user32.dll")> _ Private Shared Function OpenClipboard( _ ByVal hWndNewOwner As IntPtr) As Boolean End Function <DllImport("user32.dll")> _ Private Shared Function IsClipboardFormatAvailable( _ ByVal wFormat As Integer) As Integer End Function <DllImport("user32.dll")> _ Private Shared Function GetClipboardData( _ ByVal wFormat As Integer) As IntPtr End Function <DllImport("user32.dll")> _ Private Shared Function CloseClipboard() As Integer End Function ''' <summary> ''' クリップボードのメタファイル形式のデータを取得する ''' </summary> ''' <param name="hWnd">ウィンドウのハンドル</param> ''' <returns>取得したデータ</returns> Public Shared Function GetEnhMetafileOnClipboard( _ ByVal hWnd As IntPtr) As System.Drawing.Imaging.Metafile Dim meta As System.Drawing.Imaging.Metafile = Nothing If OpenClipboard(hWnd) Then Try If IsClipboardFormatAvailable(CF_ENHMETAFILE) <> 0 Then Dim hmeta As IntPtr = GetClipboardData(CF_ENHMETAFILE) meta = New System.Drawing.Imaging.Metafile(hmeta, True) End If Finally CloseClipboard() End Try End If Return meta End Function [C#] //using System.Runtime.InteropServices; private const int CF_ENHMETAFILE = 14; [DllImport("user32.dll")] private static extern bool OpenClipboard(IntPtr hWndNewOwner); [DllImport("user32.dll")] private static extern int IsClipboardFormatAvailable(int wFormat); [DllImport("user32.dll")] private static extern IntPtr GetClipboardData(int wFormat); [DllImport("user32.dll")] private static extern int CloseClipboard(); /// <summary> /// クリップボードのメタファイル形式のデータを取得する /// </summary> /// <param name="hWnd">ウィンドウのハンドル</param> /// <returns>取得したデータ</returns> public static System.Drawing.Imaging.Metafile GetEnhMetafileOnClipboard(IntPtr hWnd) { System.Drawing.Imaging.Metafile meta = null; if (OpenClipboard(hWnd)) { try { if (IsClipboardFormatAvailable(CF_ENHMETAFILE) != 0) { IntPtr hmeta = GetClipboardData(CF_ENHMETAFILE); meta = new System.Drawing.Imaging.Metafile(hmeta, true); } } finally { CloseClipboard(); } } return meta; } このGetEnhMetafileOnClipboardメソッドを使うには、C#では PictureBox1.Image = GetEnhMetafileOnClipboard(this.Handle); VB.NETでは PictureBox1.Image = GetEnhMetafileOnClipboard(Me.Handle) のようにします。
(この記事は、「.NETプログラミング研究 第38号」で紹介したものを基にしています。) 注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。
|
|
Copyright 2002-2008 DOBON!. All rights reserved.
|