|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Framework2 Clipboard bitmap problem solvedold workaround of using the ocx's EditCopy method to copy the chart image to the clipboard, then use the Clipboard.GetDataObject method to get the image from the clipboard using code like the following: Dim iData As System.Windows.Forms.IDataObject = Clipboard.GetDataObject() If (iData.GetDataPresent(DataFormats.Bitmap)) Then Try Dim Img As Image = CType(iData.GetData(DataFormats.Bitmap), Bitmap) Dim lMargin As Single = e.MarginBounds.Left Dim tMargin As Single = e.MarginBounds.Top e.Graphics.DrawImage(Img, lMargin, tMargin) Dim myRect As New Rectangle(lMargin, tMargin, Img.Width + 20, Img.Height) e.Graphics.DrawRectangle(Pens.Black, myRect) Catch ex As Exception PostError(ex) End Try End If In Vs2005, this fails miserably with a Fatal Engine Error,l in spite of forcing the program to be <STAThread> with the appropriate attribute on the Sub Main() as specified in the MSDN on the clipboard class. I rewrote the code to use the enhanced Clipboard class in the Framework2, but that generates the same error. Interestingly enough using a test program, if I invoked 2 instances of the program, I could copy the chart using EditCopy to the clipboard in one instance, and paste the clipboard bitmap into the other instance. But accessing the clipboard once the ActiveX control copied a bitmap to it resulted in crash city. After research, I discovered that the Framework2 does indeed have some severe problems with accessing the clipboard for images. Fortunately, the Win32 clipboard APIs can be used directly in a Vs2005 program. The following partial code appears to work flawlessly in a VB.Net 2 program. I offer it as a solution for those that need it: Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Imports System.Windows.Forms Public Class Form2 <DllImport("user32.dll", EntryPoint:="OpenClipboard", _ SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function OpenClipboard(ByVal hWnd As IntPtr) As Boolean End Function <DllImport("user32.dll", EntryPoint:="EmptyClipboard", _ SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function EmptyClipboard() As Boolean End Function <DllImport("user32.dll", EntryPoint:="SetClipboardData", _ SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function SetClipboardData(ByVal uFormat As Integer, ByVal hWnd As IntPtr) As IntPtr End Function <DllImport("user32.dll", EntryPoint:="CloseClipboard", _ SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function CloseClipboard() As Boolean End Function <DllImport("user32.dll", EntryPoint:="GetClipboardData", _ SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function GetClipBoardData(ByVal uFormat As Integer) As IntPtr End Function <DllImport("user32.dll", EntryPoint:="IsClipboardFormatAvailable", _ SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ Public Shared Function IsClipboardFormatAvailable(ByVal uFormat As Integer) As Boolean End Function '/* ' * Predefined Clipboard Formats ' */ Private Const CF_TEXT As Integer = 1 Private Const CF_BITMAP As Integer = 2 Private Const CF_METAFILEPICT As Integer = 3 Private Const CF_SYLK As Integer = 4 Private Const CF_DIF As Integer = 5 Private Const CF_TIFF As Integer = 6 Private Const CF_OEMTEXT As Integer = 7 Private Const CF_DIB As Integer = 8 Private Const CF_PALETTE As Integer = 9 Private Const CF_PENDATA As Integer = 10 Private Const CF_RIFF As Integer = 11 Private Const CF_WAVE As Integer = 12 Private Const CF_UNICODETEXT As Integer = 13 Private Const CF_ENHMETAFILE As Integer = 14 Private Const CF_HDROP As Integer = 15 Private Const CF_LOCALE As Integer = 16 Private Const CF_MAX As Integer = 17 Private Const CF_OWNERDISPLAY As Integer = 128 Private Const CF_DSPTEXT As Integer = 129 Private Const CF_DSPBITMAP As Integer = 130 Private Const CF_DSPMETAFILEPICT As Integer = 131 Private Const CF_DSPENHMETAFILE As Integer = 142 Private Sub btnCopy_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCopy.Click Try AxMSChart1.EditCopy() Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Exclamation) End Try End Sub Private Sub btnPaste_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPaste.Click Try If (IsClipBoardFormatAvailable(CF_BITMAP)) Then OpenClipboard(Me.Handle) Dim hWnd As IntPtr = GetClipBoardData(CF_BITMAP) If (Not hWnd.Equals(IntPtr.Zero)) Then Dim img As System.Drawing.Image = System.Drawing.Image.FromHbitmap(hWnd) picPicture.Image = img End If CloseClipboard() Else MsgBox("A bitmap is not available") End If Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Exclamation) End Try End Sub |
|||||||||||||||||||||||