I have a project in which I use a backgroundworker to do the scanning function from a scanner asynchronously by WIA2. It works well with WIA.
Now I am trying to do the same by scanning with TWAIN. I can scan using TWAIN ok. However when I try to make it work in the background I cannot make it work properly since the event of scanning in TWAIN have a TransferImage handler and a ScanningComplete event handler which get aroused when the scan finishes. The transferImage is ok since it does not affect my background event. However I want to access a panel in the scanningComplete event, make it .Visible = False
A piece of what happens:
Private Sub rBEScan_Click(sender As Object, e As EventArgs) Handles rBEScan.Click
rPScanning.Visible = True
Me.rBEScan.Enabled = False
bGWScan.RunWorkerAsync()
End Sub
Private Sub bGWScan_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bGWScan.DoWork
Dim path As String = ""
Dim correct As Boolean = False
If scanMode = 1 Then
correct = ScannerRead(path, 1)
Else 'TWAIN
images = Nothing
images = New List(Of System.Drawing.Bitmap)
correct = scanTWAIN(gLocalScanner, path)
End If
Dim obj As Object
obj = correct
e.Result = obj
End Sub
Private Sub bGWScan_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles bGWScan.RunWorkerCompleted
Dim obj As Object
obj = e.Result
Dim lobj As Boolean
lobj = DirectCast(obj, Boolean)
rPScanning.Visible = False
Me.rBEScannerEskaneatu.Enabled = True
End Sub
Private Shared Function scanTWAIN(ByVal id As String, ByVal path As String) As Boolean ' prompt to scan more pages,
' SCAN TWAIN FUNCTION
AddHandler twain.TransferImage,
Sub(sender As Object, args As TwainDotNet.TransferImageEventArgs)
If (Not (args.Image Is Nothing)) Then
images.Add(args.Image)
End If
End Sub
' Re-enable the form after scanning completes
AddHandler twain.ScanningComplete,
Sub(sender As Object, e As TwainDotNet.ScanningCompleteEventArgs)
'Enabled = True
Dim lobj As String = ""
lobj = FuncionScanner.pdfIrudiraTwain(images, path, gLocalPreguntarRotacion, orritxurisep, orriDok, orriguztiakDok)
PrincipalR.rPScanning.Visible = False
PrincipalR.rBEScan.Enabled = True
End Sub
ScanningFunctionOfTwain With my settings.
End Sub
My problem is that I end the background worker before scanning the images, since the events are handled and aroused in another function that is called asynchronously.
Any idea of how can I put the rPScanning.Visible = False
and rBEScan.Visible = False
When the event within the background worker ends.
If it is not possible should I use another backgroundworker in the eventHandler of the scan pages in TWAIN.
Thank @JQSOFT, As you said I had to use a delegate sub to do handle the panel visibility. Here is the change in the code:
Private Shared Function scanTWAIN(ByVal id As String, ByVal path As String) As Boolean ' prompt to scan more pages,
' SCAN TWAIN FUNCTION
AddHandler twain.TransferImage,
Sub(sender As Object, args As TwainDotNet.TransferImageEventArgs)
If (Not (args.Image Is Nothing)) Then
images.Add(args.Image)
End If
End Sub
' Re-enable the form after scanning completes
AddHandler twain.ScanningComplete,
Sub(sender As Object, e As TwainDotNet.ScanningCompleteEventArgs)
Dim objNewThread As New Thread(Sub() FuncionScanner.pdfTwainThread(images, path, gLocalPreguntarRotacion,
orritxurisep, orriDok, orriguztiakDok,
rPScanning, rBEScan))
objNewThread.IsBackground = True
objNewThread.Start()
End Sub
ScanningFunctionOfTwain With my settings.
End Sub
I have put it in a new thread the after scan function and it works well. Since I use the new thread in another class I put the new delegate sub as well.
Public Shared Sub pdfTwainThread(ByVal lista As List(Of System.Drawing.Bitmap),
ByVal path As String, ByVal ori As Boolean,
ByVal orritxurisep As Boolean, ByVal orriDok As Boolean,
ByVal orriguztiakDok As Boolean,
ByRef rp As Telerik.WinControls.UI.RadPanel,
ByRef rb As Telerik.WinControls.UI.RadButtonElement)
Dim l As String = ""
l = pdfIrudiraTwain(lista, path, ori, orritxurisep, orriDok, orriguztiakDok)
panel_visible(False, rp, rb)
Dim txt As String = ""
Dim txt1 As String = ""
txt1 = Func_nombre(366)
If l <> "" Then
txt = Func_nombre(436)
MessageBox.Show(txt, txt1, MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
txt = Func_nombre(437)
MessageBox.Show(txt, txt1, MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
Delegate Sub PanelV(vf As Boolean, ByRef rp As Telerik.WinControls.UI.RadPanel,
ByRef rbscan As Telerik.WinControls.UI.RadButtonElement)
Private Shared Sub panel_visible_hemen(ByVal vis As Boolean, ByRef rp As Telerik.WinControls.UI.RadPanel,
ByRef rbscan As Telerik.WinControls.UI.RadButtonElement)
If rp.InvokeRequired Then
Dim d As New PanelV(AddressOf panel_visible_hemen)
rp.Invoke(d, New Object() {vis, rp, rbscan})
Else
rp.SendToBack()
rp.Visible = vis
rbscan.Enabled = True
End If
End Sub
I pass the panel and the buttonElement byref to the new function which I update in a delegate sub.
Thanks a lot for the help @JQSOFT.
I have post the answer just in case someone else needs.