Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to make a userform release system graphics (.net)
    primarykey
    data
    text
    <p>I'm using VS2008 and I've managed to pull together code that I've taught myself (badly) along with stuff I've found on the internet and I've now hit a wall. I've had a look around and I can't figure out how to get around the problem.</p> <p>When someone presses a button I thread out to two modules, the first puts a picture box ontop of the datagrid and spins an image whilst it waits for the second thread to save data to Excel. The problem I get is the error message 'object in use elsewhere' when it gets to the line 'Me.PictureBox4.Image = DirectCast(BM_out.Clone(), System.Drawing.Image)' while running the code.</p> <pre><code>Public MoveByCalc As Double Public ReturnStack As New System.Collections.Generic.Stack(Of Integer) Public BM_In As New Bitmap(My.Resources.Fan) Public Wid As Single = BM_In.Width Public Hgt As Single = BM_In.Height Public Cx As Single = Wid / 2 Public Cy As Single = Hgt / 2 Public TimeElapsed As Single = 1 Public EndThread As String = "No" Public X As Integer Public BS As New BindingSource Public AutoNum As Integer Public CellConnection As New OleDbConnection Public DB1Connection As New OleDbConnection Public DB2Connection As New OleDbConnection Public OldScrollValue As Integer : Public Direction As Integer Public objDataAdapter As New OleDbDataAdapter() Public objDataSet As New DataSet() Public objDataAdapterDB1 As New OleDbDataAdapter() Public objDataSetDB1 As New DataSet() Public objDataAdapterDB2 As New OleDbDataAdapter() Public objDataSetDB2 As New DataSet() Public DBCount As String Public LoadError As Integer Public TempString As String Public DisableSearch As Integer Public DataGridTop As Double Public DataGridHeight As Double Public DataGridBottom As Double Public DBLoc As Integer Public ButtonSelectedColour As Color = Color.FromArgb(253, 183, 89) Public Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseButton.Click PictureBox4.Visible = True PictureBox4.Top = DataGridView1.Top : PictureBox4.Left = DataGridView1.Left PictureBox4.Height = DataGridView1.Height : PictureBox4.Width = DataGridView1.Width EndThread = "No" DataGridView1.DataSource = objDataSet.Tables(0).DefaultView Dim T As Thread T = New Thread(AddressOf Me.FanSpin) T.Start() Dim S As Thread S = New Thread(AddressOf Me.SaveData) S.Start() End Sub Private Sub FanSpin() Dim KeepRunning As Boolean = True 'On Error GoTo EndThread While KeepRunning TimeElapsed = TimeElapsed + 1 Dim Corners As Point() = { _ New Point(0, 0), _ New Point(Wid, 0), _ New Point(0, Hgt), _ New Point(Wid, Hgt)} Dim I As Long For I = 0 To 3 Corners(I).X -= Cx Corners(I).Y -= Cy Next I Dim theta As Single = Single.Parse(-TimeElapsed) * PI / 180.0 Dim X As Single Dim Y As Single For I = 0 To 3 X = Corners(I).X Y = Corners(I).Y Corners(I).X = X * Cos(theta) + Y * Sin(theta) Corners(I).Y = -X * Sin(theta) + Y * Cos(theta) Next I Dim xmin As Single = Corners(0).X Dim ymin As Single = Corners(0).Y For I = 1 To 3 If xmin &gt; Corners(I).X Then xmin = Corners(I).X If ymin &gt; Corners(I).Y Then ymin = Corners(I).Y Next I For I = 0 To 3 Corners(I).X -= xmin Corners(I).Y -= ymin Next I Dim BM_out As Bitmap = New Bitmap(CInt(-2 * xmin), CInt(-2 * ymin)) Dim gr_out As Graphics = Graphics.FromImage(BM_out) ReDim Preserve Corners(2) SyncLock BM_In gr_out.DrawImage(BM_In, Corners) End SyncLock If BM_out IsNot Nothing Then SyncLock BM_out Me.PictureBox4.Image = DirectCast(BM_out.Clone(), System.Drawing.Image) End SyncLock End If If EndThread = "Yes" Then KeepRunning = False End If End While EndThread: PictureBox4.Image = Nothing If Me.PictureBox4.InvokeRequired Then PictureBox4.Invoke(New Action(AddressOf PictureBox4.Hide)) Else Me.PictureBox4.Visible = False End If End Sub Public Sub DataBindToDataGrid() Select Case ReturnStack.Peek() Case 1 DataGridView1.DataSource = objDataSetDB1.Tables(0).DefaultView Case 2 DataGridView1.DataSource = objDataSetDB2.Tables(0).DefaultView End Select End Sub Private Sub SaveData() Dim CallDataBindToDataGrid As New MethodInvoker(AddressOf Me.DataBindToDataGrid) Dim XLApp As New Excel.Application Dim Wb As Excel.Workbook Dim Ws As Excel.Worksheet Dim XlRange As Excel.Range XLApp = New Excel.Application Wb = XLApp.Workbooks.Open(My.Settings.Database3C) Ws = Wb.Worksheets("Data") Ws.Activate() Ws.Unprotect() XlRange = Ws.Range("A5", "V100") XlRange.ClearContents() XlRange = Ws.Range("A5") Dim Count As Integer = 0 For Count = 0 To 49 XlRange.Value = DataGridView1.Rows(Count).Cells(0).Value XlRange.Offset(0, 1).Value = DataGridView1.Rows(Count).Cells(1).Value.ToString XlRange.Offset(0, 2).Value = DataGridView1.Rows(Count).Cells(2).Value.ToString XlRange.Offset(0, 3).Value = DataGridView1.Rows(Count).Cells(3).Value.ToString XlRange.Offset(0, 4).Value = DataGridView1.Rows(Count).Cells(4).Value.ToString XlRange.Offset(0, 5).Value = DataGridView1.Rows(Count).Cells(5).Value.ToString XlRange.Offset(0, 6).Value = DataGridView1.Rows(Count).Cells(6).Value.ToString XlRange.Offset(0, 7).Value = DataGridView1.Rows(Count).Cells(7).Value.ToString XlRange.Offset(0, 8).Value = DataGridView1.Rows(Count).Cells(8).Value.ToString XlRange.Offset(0, 9).Value = DataGridView1.Rows(Count).Cells(9).Value.ToString XlRange.Offset(0, 10).Value = DataGridView1.Rows(Count).Cells(10).Value.ToString XlRange.Offset(0, 11).Value = DataGridView1.Rows(Count).Cells(11).Value.ToString XlRange.Offset(0, 12).Value = DataGridView1.Rows(Count).Cells(12).Value.ToString XlRange.Offset(0, 13).Value = DataGridView1.Rows(Count).Cells(13).Value.ToString XlRange.Offset(0, 14).Value = DataGridView1.Rows(Count).Cells(14).Value.ToString XlRange.Offset(0, 15).Value = DataGridView1.Rows(Count).Cells(15).Value.ToString XlRange.Offset(0, 16).Value = DataGridView1.Rows(Count).Cells(16).Value.ToString XlRange.Offset(0, 17).Value = DataGridView1.Rows(Count).Cells(17).Value.ToString XlRange.Offset(0, 18).Value = DataGridView1.Rows(Count).Cells(18).Value.ToString XlRange.Offset(0, 19).Value = DataGridView1.Rows(Count).Cells(19).Value.ToString XlRange.Offset(0, 20).Value = DataGridView1.Rows(Count).Cells(20).Value.ToString XlRange.Offset(0, 21).Value = DataGridView1.Rows(Count).Cells(21).Value.ToString XlRange.Offset(0, 22).Value = DataGridView1.Rows(Count).Cells(23).Value.ToString 'DB Log numbers XlRange = XlRange.Offset(1, 0) Next Count XLApp.DisplayAlerts = False Wb.Save() Wb.Close() Wb = Nothing ReturnStack.Push(1) If My.Settings.Database1 &lt;&gt; "" Then Me.BeginInvoke(CallDataBindToDataGrid) Wb = XLApp.Workbooks.Open(My.Settings.Database1) GoTo SaveData End If ReturnLabel1: ReturnStack.Push(2) If My.Settings.Database2 &lt;&gt; "" Then Me.BeginInvoke(CallDataBindToDataGrid) Wb = XLApp.Workbooks.Open(My.Settings.Database2) GoTo SaveData End If ReturnLabel2: SaveData: Ws = Wb.Worksheets("Analysis") Ws.Activate() Ws.Unprotect() XlRange = Ws.Range("A10", "AO2009") XlRange.ClearContents() XlRange = Ws.Range("A10") Dim I As Integer Dim J As Integer For I = 0 To DataGridView1.RowCount - 2 If DataGridView1.Rows(I).Cells(1).Value.ToString &lt;&gt; "" Then For J = 0 To DataGridView1.ColumnCount - 1 Ws.Cells(I + 10, J + 1) = DataGridView1(J, I).Value.ToString() Next End If Next XLApp.DisplayAlerts = False Wb.Save() Wb.Close() Wb = Nothing Select Case ReturnStack.Peek() Case 1 : GoTo ReturnLabel1 Case 2 : GoTo ReturnLabel2 End Select EndSub101: XLApp.Quit() XLApp = Nothing GC.Collect() GC.WaitForPendingFinalizers() EndThread = "Yes" End Sub </code></pre> <p>I've narrowed the problem down (I think) to the system not releasing the graphics (releasehdc?) when I change the datasource of the datagridview. I think this is the case as it works when I don't change the datasource and it actually starts working in it's current state but stops halfway through! I need to change the datasource so I can save different data sets to different Excel files.</p> <p>I know I shouldn't be calling graphics inside threads and cross threading like this (it's the only way I could get it to work...sort of) but any help someone could provide to get around this error would be greatly appreciated.</p> <p>Thanks Paul</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload