MainForm.vb
Imports System.ComponentModel Imports System.Drawing Imports System.Media Imports System.Reflection Imports System.Text Imports System.Threading Imports System.Windows.Forms Imports Bytescout.BarCodeReader Imports TouchlessLib Public Class MainForm ' Scan delay, ms. Const SCAN_DELAY As Integer = 1500 ' scan barcodes every 1.5 sec ' Touchless SDK library manager (to use it you should have TouchlessLib.dll referenced and WebCamLib.dll in the build output directory) Dim ReadOnly _touchlessLibManager As TouchlessMgr ' Background thread for barcode scanning Dim ReadOnly _backgroundWorker As New BackgroundWorker ' Synchronization event Dim ReadOnly _synchronizationEvent As New AutoResetEvent(False) ' Form constructor Public Sub New() InitializeComponent() ' Create Touchless library manager _touchlessLibManager = New TouchlessMgr() ' Setup background worker _backgroundWorker.WorkerSupportsCancellation = True AddHandler _backgroundWorker.DoWork, AddressOf BackgroundWorker_DoWork AddHandler _backgroundWorker.RunWorkerCompleted, AddressOf BackgroundWorker_RunWorkerCompleted End Sub ' On form loading Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' Fill devices combobox with available video cameras For Each camera As Camera In _touchlessLibManager.Cameras cmbCamera.Items.Add(camera) Next ' Select the first available camera. See also cmbCamera_SelectedIndexChanged event handler. If _touchlessLibManager.Cameras.Count > 0 Then cmbCamera.SelectedItem = _touchlessLibManager.Cameras(0) Else MessageBox.Show("No video camera available. Please connect the camera.") End If ' Populate barcode types combobox PopulateBarcodeTypesCombobox() ' Select some default barcode type cmbBarcodeType.SelectedItem = "QRCode" End Sub Private Sub PopulateBarcodeTypesCombobox() cmbBarcodeType.Items.Clear() For Each propertyInfo As PropertyInfo In GetType(BarcodeTypeSelector).GetProperties() cmbBarcodeType.Items.Add(propertyInfo.Name) Next End Sub ' On camera selected Private Sub cmbCamera_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbCamera.SelectedIndexChanged If _touchlessLibManager.CurrentCamera IsNot Nothing Then RemoveHandler _touchlessLibManager.CurrentCamera.OnImageCaptured, AddressOf CurrentCamera_OnImageCaptured End If If cmbCamera.SelectedIndex <> -1 Then Dim camera As Camera = _touchlessLibManager.Cameras(cmbCamera.SelectedIndex) If camera IsNot Nothing Then ' Set camera output image dimensions camera.CaptureWidth = Integer.Parse(tbCameraWidth.Text) camera.CaptureHeight = Integer.Parse(tbCameraHeight.Text) AddHandler camera.OnImageCaptured, AddressOf CurrentCamera_OnImageCaptured ' Select the camera _touchlessLibManager.CurrentCamera = camera End If End If End Sub Private Sub btnUpdateCameraImageDimensions_Click(sender As Object, e As EventArgs) Handles btnUpdateCameraImageDimensions.Click If _touchlessLibManager.CurrentCamera IsNot Nothing Then ' Update camera's output image dimensions _touchlessLibManager.CurrentCamera.CaptureWidth = Integer.Parse(tbCameraWidth.Text) _touchlessLibManager.CurrentCamera.CaptureHeight = Integer.Parse(tbCameraHeight.Text) End If End Sub Private Sub StartDecoding() If cmbCamera.SelectedIndex = -1 Then Return End If ' Clear the output text box rtbFoundBarcodes.Clear() ' Check if we have camera selected If cmbCamera.SelectedIndex <> -1 Then ' Start the decoding in the background thread Dim barcodeTypesToFind As BarcodeTypeSelector = GetBarcodeTypeFromCombobox() _backgroundWorker.RunWorkerAsync(barcodeTypesToFind) UpdateControls(True) Else MessageBox.Show("Please select the camera first!") End If End Sub Private Sub StopDecoding() _backgroundWorker.CancelAsync() ' Wait until BackgroundWorker finished If _backgroundWorker.IsBusy Then _synchronizationEvent.WaitOne() End If UpdateControls(False) End Sub Private Sub UpdateControls(started As Boolean) If started Then btnStart.Enabled = False btnStop.Enabled = True cmbBarcodeType.Enabled = False cmbCamera.Enabled = False tbCameraHeight.Enabled = False tbCameraWidth.Enabled = False btnUpdateCameraImageDimensions.Enabled = False cbStopOnFirstBarcode.Enabled = False lblScanning.Visible = True lblScanning.Text = "Scanning..." Else btnStart.Enabled = True btnStop.Enabled = False cmbBarcodeType.Enabled = True cmbCamera.Enabled = True cbStopOnFirstBarcode.Enabled = True tbCameraHeight.Enabled = True tbCameraWidth.Enabled = True btnUpdateCameraImageDimensions.Enabled = True lblScanning.Visible = True End If End Sub Private Sub CurrentCamera_OnImageCaptured(sender As Object, e As CameraEventArgs) pictureBoxPreview.Image = e.Image End Sub Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click StartDecoding() End Sub Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click StopDecoding() End Sub ' Background thread procedure used by BackgroundWorker Private Sub BackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs) Dim worker As BackgroundWorker = CType(sender, BackgroundWorker) Dim barcodeTypesToFind As BarcodeTypeSelector = CType(e.Argument, BarcodeTypeSelector) ' Create and setup barcode reader instance Using reader As New Reader reader.RegistrationName = "demo" reader.RegistrationKey = "demo" reader.BarcodeTypesToFind = barcodeTypesToFind ' Work while not canceled While True ' Check cancellation If worker.CancellationPending Then e.Cancel = True _synchronizationEvent.Set() Return End If ' Get image from camera by invoking method from UI thread Dim bitmap As Bitmap = CType(Invoke(New GetCameraImageDelegate(AddressOf GetCameraImage)), Bitmap) If bitmap Is Nothing Then e.Result = nothing return End If ' Search the image for barcodes Dim result As FoundBarcode() = reader.ReadFrom(bitmap) ' Update UI asynchronously BeginInvoke(New Action(Of FoundBarcode())(AddressOf UpdateStatus), New Object() { result }) ' Pause Thread.Sleep(SCAN_DELAY) End While End Using End Sub Delegate Function GetCameraImageDelegate() As Bitmap Private Function GetCameraImage() As Bitmap If Not IsDisposed and Not Disposing and _touchlessLibManager.CurrentCamera IsNot Nothing Then return _touchlessLibManager.CurrentCamera.GetCurrentImage() End If Return Nothing End Function ' Update UI with found barcodes information Private Sub UpdateStatus(foundBarcodes As FoundBarcode()) If foundBarcodes IsNot Nothing And foundBarcodes.Length > 0 Then ' Play sound if we found any barcode SystemSounds.Beep.Play() Dim stringBuilder As StringBuilder = New StringBuilder() stringBuilder.AppendFormat("Time: {0:HH:mm:ss:tt}", DateTime.Now) stringBuilder.AppendLine() ' Display found barcodes in the output text box For Each barcode As FoundBarcode In foundBarcodes stringBuilder.AppendFormat("Found barcode: {0} {1}", barcode.Type, barcode.Value) stringBuilder.AppendLine() Next rtbFoundBarcodes.Text = stringBuilder.ToString() ' Update status text with number of found barcodes lblFoundBarcodes.Text = String.Format("Found {0} barcodes:", foundBarcodes.Length) End If ' Make "Scanning..." label flicker. lblScanning.Visible = Not lblScanning.Visible lblScanning.Refresh() ' Check if we need to stop on first barcode found If cbStopOnFirstBarcode.Checked And foundBarcodes IsNot Nothing And foundBarcodes.Length > 0 Then StopDecoding() End If End Sub ' Background thread is finished Private Sub BackgroundWorker_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) ' Update UI asynchronously BeginInvoke(New Action(Of RunWorkerCompletedEventArgs)(AddressOf OnBackgroundWorkerFinished), New Object() {e}) End Sub Private Sub OnBackgroundWorkerFinished(completedEventArgs As RunWorkerCompletedEventArgs) If completedEventArgs.Cancelled Then lblScanning.Text = "Stopped" ElseIf completedEventArgs.Error IsNot Nothing Then lblScanning.Text = "Error: " + completedEventArgs.Error.Message Else lblScanning.Text = "Done!" End If UpdateControls(False) End Sub Private Function GetBarcodeTypeFromCombobox() As BarcodeTypeSelector Dim result As BarcodeTypeSelector = New BarcodeTypeSelector() Dim selectedBarcodeTypeName As String = CType(cmbBarcodeType.SelectedItem, String) Dim propertyInfo As PropertyInfo = GetType(BarcodeTypeSelector).GetProperty(selectedBarcodeTypeName) propertyInfo.SetValue(result, True, Nothing) Return result End Function Protected Overrides Sub OnClosing(e As CancelEventArgs) StopDecoding() _touchlessLibManager.Dispose() MyBase.OnClosing(e) End Sub Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click DialogResult = DialogResult.OK Close() End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try if _touchlessLibManager.CurrentCamera IsNot Nothing _touchlessLibManager.CurrentCamera.ShowPropertiesDialog(Handle) End If Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub End Class
Program.vb
Imports System.Collections.Generic Imports System.Windows.Forms NotInheritable Class Program Private Sub New() End Sub ''' <summary> ''' The main entry point for the application. ''' </summary> <MTAThread> _ Friend Shared Sub Main() Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) Dim dlg As New MainForm() dlg.ShowDialog() End Sub End Class