// ScanAPI Helper provides a series of Callbacks
        // indicating some asynchronous events has occurred
        #region ScanApiHelperNotification Members

        // a scanner has connected to the host
        public void OnDeviceArrival(long result, ScanApiHelper.DeviceInfo newDevice)
        {
            if (SktScanErrors.SKTSUCCESS(result))
            {
                UpdateStatusText("New Scanner: " + newDevice.Name);
                _device = newDevice;
// This is for the Host Acknowledgment feature. These lines can
// be safely removed from #if to the #endif from your application
// if this feature is not needed
#if HOSTACK
                // Set the device to NOT acknowledge itself
                _scanApiHelper.PostSetLocalAcknowledgement(_device, false, null);
                // And make sure it does not give any indication after a scan
                _scanApiHelper.PostSetDecodeAction(_device, ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionNone, null);
#else
                // Set the device to NOT acknowledge itself
                _scanApiHelper.PostSetLocalAcknowledgement(_device, true, null);
                // And make sure it does not give any indication after a scan
                int decode = ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionBeep |
                             ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionFlash |
                             ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionRumble;
                _scanApiHelper.PostSetDecodeAction(_device, decode, null);
#endif
            }
            else
            {
                string strMsg = String.Format("Unable to open scanner, error = {0}.", result);
                MessageBox.Show(strMsg, strAppName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        // ScanAPI Helper provides a series of Callbacks
        // indicating some asynchronous events has occurred
        #region ScanApiHelperNotification Members

        // a scanner has connected to the host
        public void OnDeviceArrival(long result, ScanApiHelper.DeviceInfo newDevice)
        {
            if (SktScanErrors.SKTSUCCESS(result))
            {
                UpdateStatusText("New Scanner: " + newDevice.Name);
                _device = newDevice;
            }
            else
            {
                string strMsg = String.Format("Unable to open scanner, error = {0}.", result);
                MessageBox.Show(strMsg, strAppName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        // some decoded data have been received
        public void OnDecodedData(ScanApiHelper.DeviceInfo device, ISktScanDecodedData decodedData)
        {
            UpdateDecodedDataText(decodedData.DataToUTF8String);
// This is for the Host Acknowledgment feature. These lines can
// be safely removed from #if to the #endif from your application
// if this feature is not needed
#if HOSTACK
            Thread.Sleep(3 * 1000); // just a delay to show the trigger lock...
            // Send confirmation to scanner, good or bad
            _scanApiHelper.PostSetDataConfirmation(_device, bDoGoodScan, null);
            bDoGoodScan = !bDoGoodScan; // Alternate between a good read and a bad read..
#endif
        }
 /**
  * PostSetStandConfig
  * Constructs a request object for setting the Stand Config of the scanner
  *
  */
 public void PostSetStandConfig(DeviceInfo deviceInfo, int standConfig, ICommandContextCallback callback)
 {
     ISktScanDevice device = deviceInfo.SktScanDevice;
     ISktScanObject newScanObj = SktClassFactory.createScanObject();
     newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdStandConfigDevice;
     newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeUlong;
     newScanObj.Property.Ulong = standConfig;
     CommandContext command = new CommandContext(false, newScanObj, device, null, callback);
     AddCommand(command);
 }
        public void PostSetSoundConfig(DeviceInfo device, Byte[] bArray, ICommandContextCallback callback)
        {
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdSoundConfigDevice;
            newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeArray;
            newScanObj.Property.Array.Value = bArray;

            CommandContext command = new CommandContext(false, newScanObj, device.SktScanDevice, null, callback);
            AddCommand(command);
        }
        /**
         * PostSetPostamble
         *
         * Configure the postamble of the device
         * @param device
         * @param suffix
         */
        public void PostSetPostamble(DeviceInfo device, String suffix, ICommandContextCallback callback)
        {
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdPostambleDevice;
            newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeString;
            newScanObj.Property.String.Value=suffix;

            CommandContext command = new CommandContext(false, newScanObj, device.SktScanDevice, null, callback);
            AddCommand(command);
        }
 /**
  * PostSetLocalAcknowledgement
  * Set the scanner LocalAcknowledgement<p>
  * This is only required if the scanner Confirmation Mode is set to kSktScanDataConfirmationModeApp
  * or kSktScanDataConfirmationModeScanAPI
  */
 public void PostSetLocalAcknowledgement(DeviceInfo deviceInfo, bool bLocalAcknowledgement, ICommandContextCallback callback)
 {
     ISktScanDevice device = deviceInfo.SktScanDevice;
     ISktScanObject newScanObj = SktClassFactory.createScanObject();
     newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdLocalAcknowledgmentDevice;
     newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeByte;
     newScanObj.Property.Byte = bLocalAcknowledgement ? ScanAPI.ISktScanProperty.values.deviceDataAcknowledgment.kSktScanDeviceDataAcknowledgmentOn : ScanAPI.ISktScanProperty.values.deviceDataAcknowledgment.kSktScanDeviceDataAcknowledgmentOff;
     CommandContext command = new CommandContext(false, newScanObj, device, deviceInfo, callback);
     AddCommand(command);
 }
 /**
  * PostSetFriendlyName
  * Constructs a request object for setting the Friendly Name in the scanner
  *
  */
 public void PostSetFriendlyName(DeviceInfo deviceInfo, String friendlyName, ICommandContextCallback callback)
 {
     ISktScanDevice device = deviceInfo.SktScanDevice;
     ISktScanObject newScanObj = SktClassFactory.createScanObject();
     newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdFriendlyNameDevice;
     newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeString;
     newScanObj.Property.String.Value=friendlyName;
     CommandContext command = new CommandContext(false, newScanObj, device, null, callback);
     AddCommand(command);
 }
        /**
         * DoStartDecode
         */
        public void PostStartDecode(DeviceInfo deviceInfo, ICommandContextCallback callback)
        {
            ISktScanDevice device = deviceInfo.SktScanDevice;
            // create and initialize the property to send to the device
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdTriggerDevice;
            newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeByte;
            newScanObj.Property.Byte = (byte)ISktScanProperty.values.trigger.kSktScanTriggerStart;

            // add the property and the device to the command context list
            // to send it as soon as it is possible
            CommandContext command = new CommandContext(false, newScanObj, device, deviceInfo, callback);
            AddCommand(command);
        }
 /**
  * HandleDeviceArrival
  * This method is called each time a device connect to the host.
  *
  * We create a device info object to hold all the necessary
  * information about this device, including its interface
  * which is used as handle
  */
 private void HandleDeviceArrival(ISktScanObject scanObject)
 {
     String friendlyName=scanObject.Msg.DeviceName;
     String deviceGuid=scanObject.Msg.DeviceGuid;
     long type=scanObject.Msg.DeviceType;
     ISktScanDevice device=SktClassFactory.createDeviceInstance(_scanApi);
     DeviceInfo newDevice=null;
     long result=device.Open(deviceGuid);
     if(SktScanErrors.SKTSUCCESS(result))
     {
         // add the new device into the list
         newDevice=new DeviceInfo(friendlyName,device,type);
         lock(_devicesList){
             _devicesList.Add(newDevice);
             _devicesList.Remove(_noDeviceConnected);
         }
     }
     if(_notification!=null)
         _notification.OnDeviceArrival(result,newDevice);
 }
        // a scanner has disconnected from the host
        public void OnDeviceRemoval(ScanApiHelper.DeviceInfo deviceRemoved)
        {
            UpdateStatusText("Scanner Removed: " + deviceRemoved.Name);

            _device = null;
        }
        /**
         * PostGetStandConfig
         * Creates a TSktScanObject and initializes it to perform a request for the
         * Stand configuration of the scanner.
         */
        public void PostGetStandConfig(DeviceInfo deviceInfo, ICommandContextCallback callback)
        {
            ISktScanDevice device = deviceInfo.SktScanDevice;
            // create and initialize the property to send to the device
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdStandConfigDevice;
            newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeNone;

            // add the property and the device to the command context list
            // to send it as soon as it is possible
            CommandContext command = new CommandContext(true, newScanObj, device, deviceInfo, callback);
            AddCommand(command);
        }
 /**
  * PostGetLocalAcknowledgement
  * Get the scanner LocalAcknowledgement<p>
  * This is only required if the scanner Confirmation Mode is set to kSktScanDataConfirmationModeApp
  * or kSktScanDataConfirmationModeScanAPI
  */
 public void PostGetLocalAcknowledgement(DeviceInfo deviceInfo, ICommandContextCallback callback)
 {
     ISktScanDevice device = deviceInfo.SktScanDevice;
     ISktScanObject newScanObj = SktClassFactory.createScanObject();
     newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdLocalAcknowledgmentDevice;
     newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeNone;
     CommandContext command = new CommandContext(true, newScanObj, device, deviceInfo, callback);
     AddCommand(command);
 }
        /**
         * PostGetDataStore
         *
         * Configure the timers of the device
         * @param device
         * @param suffix
         */
        public void PostGetDataStore(DeviceInfo device, byte index, ICommandContextCallback callback)
        {
            byte[] bArray = {0, 0};

            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdDataStoreDevice;
            newScanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeArray;
            newScanObj.Property.Array.Value = bArray;
            newScanObj.Property.Array.Size = bArray.Length;

            CommandContext command = new CommandContext(true, newScanObj, device.SktScanDevice, device, callback);
            AddCommand(command);
        }
        /**
         * DoGetCapabilitiesDevice
         *
         * Creates a TSktScanObject and initializes it to perform a request for the
         * Capabilities Device in the scanner.
         */
        public void PostGetCapabilitiesDevice(DeviceInfo deviceInfo, ICommandContextCallback callback)
        {
            ISktScanDevice device = deviceInfo.SktScanDevice;
            // create and initialize the property to send to the device
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdCapabilitiesDevice;
            newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeByte;
            newScanObj.Property.Byte=(byte)ISktScanProperty.values.capabilityGroup.kSktScanCapabilityLocalFunctions;

            // add the property and the device to the command context list
            // to send it as soon as it is possible
            CommandContext command = new CommandContext(true, newScanObj, device, deviceInfo, callback);
            AddCommand(command);
        }
 public ScanApiHelper()
 {
     _commandContexts = new List<CommandContext>();
     _scanApi = SktClassFactory.createScanApiInstance();
     _notification = null;
     _devicesList = new List<DeviceInfo>();
     _noDeviceConnected = new DeviceInfo("", null, SktScanDeviceType.kSktScanDeviceTypeNone);
     _scanApiOpen = false;
 }
 public CommandContext(bool getOperation,ISktScanObject scanObj,ISktScanDevice scanDevice,DeviceInfo deviceInfo,ICommandContextCallback callback)
 {
     this._getOperation=getOperation;
     scanObj.Property.Context=this;
     this._scanObj=scanObj;
     this._callback=callback;
     this._status=statusReady;
     this._scanDevice=scanDevice;
     this._retries=0;
     this._deviceInfo=deviceInfo;
     this.SymbologyId=0;
 }
        /**
         * PostSetSymbologyInfo
         * Constructs a request object for setting the Symbology Info in the scanner
         *
         */
        public void PostSetSymbologyInfo(DeviceInfo deviceInfo, int Symbology, bool Status, ICommandContextCallback callback)
        {
            ISktScanDevice device = deviceInfo.SktScanDevice;
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdSymbologyDevice;
            newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeSymbology;
            newScanObj.Property.Symbology.Flags=ISktScanSymbology.flags.kSktScanSymbologyFlagStatus;
            newScanObj.Property.Symbology.ID=Symbology;
            newScanObj.Property.Symbology.Status = Status ? ISktScanSymbology.status.kSktScanSymbologyStatusEnable : ISktScanSymbology.status.kSktScanSymbologyStatusDisable;

            CommandContext command = new CommandContext(false, newScanObj, device, null, callback)
            {
                SymbologyId = Symbology // keep the symbology ID because the Set Complete won't return it
            };
            AddCommand(command);
        }
 /**
  * PostGetSymbologyInfo
  *
  * Creates a TSktScanObject and initializes it to perform a request for the
  * Symbology Info in the scanner.
  *
  */
 public void PostGetSymbologyInfo(DeviceInfo deviceInfo, int symbologyId, ICommandContextCallback callback)
 {
     ISktScanDevice device = deviceInfo.SktScanDevice;
     // create and initialize the property to send to the device
     ISktScanObject newScanObj = SktClassFactory.createScanObject();
     newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdSymbologyDevice;
     newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeSymbology;
     newScanObj.Property.Symbology.Flags=ISktScanSymbology.flags.kSktScanSymbologyFlagStatus;
     newScanObj.Property.Symbology.ID=symbologyId;
     // add the property and the device to the command context list
     // to send it as soon as it is possible
     CommandContext command = new CommandContext(true, newScanObj, device, deviceInfo, callback);
     AddCommand(command);
 }
 /**
  * remove the pending commands for a specific device
  * or all the pending commands if null is passed as
  * iDevice parameter
  * @param iDevice reference to the device for which
  * the commands must be removed from the list or <b>null</b>
  * if all the commands must be removed.
  */
 public void RemoveCommands(DeviceInfo device)
 {
     ISktScanDevice iDevice=null;
     if(device!=null)
         iDevice=device.SktScanDevice;
     // remove all the pending command for this device
     lock(_commandContexts){
         if(iDevice!=null)
             _commandContexts.RemoveAll(scandevice => scandevice.ScanDevice == iDevice);
         else
             _commandContexts.Clear();
     }
 }
        // a scanner has disconnected from the host
        public void OnDeviceRemoval(ScanApiHelper.DeviceInfo deviceRemoved)
        {
            UpdateStatusText("Scanner Removed: " + deviceRemoved.Name);

            _device = null;
        }
        /**
         * PostSetDataConfirmation
         * acknowledge the decoded data<p>
         * This is only required if the scanner Confirmation Mode is set to kSktScanDataConfirmationModeApp
         */
        public void PostSetDataConfirmation(DeviceInfo deviceInfo, bool bGoodScan, ICommandContextCallback callback)
        {
            ISktScanDevice device = deviceInfo.SktScanDevice;
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdDataConfirmationDevice;
            newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeUlong;
            newScanObj.Property.Ulong=
                    bGoodScan ?
                    SktScan.helper.SKTDATACONFIRMATION(
                            0,
                            ISktScanProperty.values.dataConfirmation.kSktScanDataConfirmationRumbleNone,
                            ISktScanProperty.values.dataConfirmation.kSktScanDataConfirmationBeepGood,
                            ISktScanProperty.values.dataConfirmation.kSktScanDataConfirmationLedGreen)
                    :
                    SktScan.helper.SKTDATACONFIRMATION(
                            0,
                            ISktScanProperty.values.dataConfirmation.kSktScanDataConfirmationRumbleNone,
                            ISktScanProperty.values.dataConfirmation.kSktScanDataConfirmationBeepBad,
                            ISktScanProperty.values.dataConfirmation.kSktScanDataConfirmationLedRed);

            CommandContext command = new CommandContext(false, newScanObj, device, null, callback);
            lock (_commandContexts)
            {
                if (_commandContexts.Count == 0)
                    AddCommand(command);
                else
                {
                    const int index = 0;
                    CommandContext pendingCommand = _commandContexts.ElementAt(index);
                    if (pendingCommand.Status == CommandContext.statusNotCompleted)
                        _commandContexts.Insert(index + 1,command);
                }
            }

            // try to see if the confirmation can be sent right away
            SendNextCommand();
        }
        /**
         * PostSetDecodeAction
         *
         * Configure the local decode action of the device
         *
         * @param device
         * @param decodeVal
         */
        public void PostSetDecodeAction(DeviceInfo device, int decodeVal, ICommandContextCallback callback)
        {
            ISktScanObject newScanObj = SktClassFactory.createScanObject();
            newScanObj.Property.ID=ISktScanProperty.propId.kSktScanPropIdLocalDecodeActionDevice;
            newScanObj.Property.Type=ISktScanProperty.types.kSktScanPropTypeByte;
            newScanObj.Property.Byte=(byte)(decodeVal & 0xffff);

            CommandContext command = new CommandContext(false, newScanObj, device.SktScanDevice, null, callback);
            AddCommand(command);
        }
 // a scanner has connected to the host
 public void OnDeviceArrival(long result, ScanApiHelper.DeviceInfo newDevice)
 {
     if (SktScanErrors.SKTSUCCESS(result))
     {
         UpdateStatusText("New Scanner: " + newDevice.Name);
         _device = newDevice;
     // This is for the Host Acknowledgment feature. These lines can
     // be safely removed from #if to the #endif from your application
     // if this feature is not needed
     #if HOSTACK
         // Set the device to NOT acknowledge itself
         _scanApiHelper.PostSetLocalAcknowledgement(_device, false, null);
         // And make sure it does not give any indication after a scan
         _scanApiHelper.PostSetDecodeAction(_device, ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionNone, null);
     #else
         // Set the device to NOT acknowledge itself
         _scanApiHelper.PostSetLocalAcknowledgement(_device, true, null);
         // And make sure it does not give any indication after a scan
         int decode = ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionBeep |
             ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionFlash |
             ISktScanProperty.values.localDecodeAction.kSktScanLocalDecodeActionRumble;
         _scanApiHelper.PostSetDecodeAction(_device, decode, null);
     #endif
     }
     else
     {
         string strMsg = String.Format("Unable to open scanner, error = {0}.", result);
         MessageBox.Show(strMsg, strAppName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
     }
 }