Search code examples
vb.netbackgroundworkertwaindotnet

TWAIN events in BackgroundWorker


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.


Solution

  • 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.