Partager via


Implémentation PosKeyboard (documentation du SDK POS pour .NET v1.14)

Un objet de service PosKeyboard lit les touches d’un clavier POS. Un clavier POS peut être un clavier auxiliaire, ou il peut s’agir d’un clavier virtuel composé de certaines ou de toutes les touches du clavier système. Dans Microsoft Point of Service pour .NET (POS pour .NET), la classe de base du clavier POS est PosKeyboardBase.

Un objet de service PosKeyboard suit le modèle d’appareil d’entrée général :

  • Lorsque l’entrée est reçue du clavier POS, un DataEvent est mis en file d’attente.
  • Si la propriété AutoDisable a la valeur true, l’appareil se désactive automatiquement lorsqu’un événement DataEvent est mis en file d’attente. Cette opération est effectuée automatiquement par la classe PosKeyboardBase .
  • Un événement DataEvent mis en file d’attente est remis à l’application lorsque la propriété DataEventEnabled a la valeur true et que d’autres exigences de remise d’événements sont remplies. La classe PosKeyboardBase gère automatiquement la remise des événements.
  • Un événement ErrorEvent est mis en file d’attente s'il se produit une erreur lors de la collecte ou du traitement de l’entrée et est livré à l’application lorsque DataEventEnabled est vrai et que d’autres exigences de remise d’événements sont remplies.
  • La propriété DataCount , qui est gérée par la classe PosKeyboardBase , peut être lue pour obtenir le nombre d’événements mis en file d’attente.
  • Toutes les entrées mises en file d’attente peuvent être supprimées en appelant ClearInput().

Le clavier POS est un appareil à usage exclusif :

  • L’application doit revendiquer l’appareil avant de l’activer.
  • L’application doit revendiquer et activer l’appareil avant que l’appareil commence à lire l’entrée.

Cette section contient un exemple d’objet de service PosKeyboard qui génère des séquences de touches simulées qui sont envoyées à l’application à l’aide de DataEvents. Cet exemple dépend de l’objet thread-helper présenté dans l’introduction des threads lecteur d’objets de service. Pour compiler cet exemple, vous devez inclure le code de cette rubrique.

Pour écrire un objet de service

  1. Ajoutez des directives using pour Microsoft.PointofService, Microsoft.PointOfService.BaseServiceObjects et System.Threading.

  2. Ajoutez l’attribut global PosAssembly.

  3. Choisissez un nom d’espace de noms approprié pour votre projet.

  4. Créez une classe Service Object dérivée de PosKeyboardBase.

  5. Ajoutez l’attribut ServiceObject à votre classe Service Object à l’aide de la valeur DeviceType.PosKeyboard comme type d’appareil.

Pour ajouter des fonctionnalités à l’exemple d’objet de service de clavier

  1. Créez une classe d’assistance de thread, KeyboardThreadingObject, dérivée de ServiceObjectThreadHelper dans la section Threads de lecture d’objet service.

  2. Implémentez la méthode ServiceObjectThreadProcedure dans la classe KeyboardThreadingObject . Il s’agit de la procédure qui sera exécutée sur un thread distinct. Dans l’exemple de code ci-dessous, cette méthode simule l’entrée du clavier.

  3. Cet exemple de classe implémente une méthode appelée SendKey et une autre appelée ChangePowerState. Ces méthodes sont des wrappers autour des membres protégés. Étant donné qu’ils sont protégés, ils ne peuvent pas être appelés directement à partir de l’objet threading.

  4. Remplacez la méthode PosCommon.Open pour spécifier les fonctionnalités prises en charge par cet objet service et créer un objet thread-helper.

  5. Remplacez posCommon.DeviceEnable spécifiquement pour ouvrir et fermer le thread-helper.

  6. Implémentez les méthodes virtuelles abstraites de PosCommon, fournissant des fonctionnalités minimales.

Exécution de l’application

Cet exemple d’objet de service peut être exécuté conjointement avec l’application de test fournie avec le kit de développement logiciel .NET (SDK) pour points de vente (POS).

Pour tester l’objet de service

  1. Démarrez l’application de test et sélectionnez SamplePosKeyboard dans la liste déroulante Clavier .

  2. Ouvrez et réclamez l’appareil, puis sélectionnez l’appareil avec la case à cocher DeviceEnabled pour l’activer.

  3. En cochant la case DataEventEnabled, l'objet de service pourra envoyer une clé simulée unique à l'application. DataEvent est mis en file d’attente automatiquement par la classe PosKeyboardBase lorsque KeyDown est appelé.

  4. Cocher la case activer automatiquement les événements de données permet à l'objet de service de continuer à distribuer des caractères, deux secondes d'intervalle.

  5. L’objet de service envoie des traits de touche simulés pour les caractères « a » à « z ». Après cela, un événement StatusUpdateEvent est envoyé indiquant que l’appareil est désormais hors connexion. Cet événement est envoyé automatiquement par la classe PosKeyboardBase lorsque Properties.PowerState est modifié.

Example

Cet exemple montre comment développer un objet de service PosKeyboard simple. Il prend en charge un thread de lecteur distinct pour envoyer des DataEvents de manière asynchrone à l’application. Une fois compilé, vous pouvez exécuter l'objet de service conjointement avec l'application de test incluse dans le SDK POS pour .NET.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

using Microsoft.PointOfService;
using Microsoft.PointOfService.BaseServiceObjects;

[assembly: PosAssembly("Service Object Contractors, Inc.")]

namespace SOSamples.Keyboard
{
    [ServiceObject(
            DeviceType.PosKeyboard,
            "SamplePosKeyboard",
            "Sample PosKeyboard Service Object",
            1,
            9)]

    public class SampleKeyboard : PosKeyboardBase
    {
        KeyboardThreadingObject ReadThread = null;

        public SampleKeyboard()
        {
            // DevicePath must be set before Open() is called.
            // In the case of Play and Plug hardware, the
            // POS for .NET Base class will set this value.
            DevicePath = "Sample Keyboard";

            // NOTE: You can test the power notification events
            // sent from this Service Object by selecting the
            // "Power Notify" check box.

            // Let the application know advanced power
            // reporting is supported.
            Properties.CapPowerReporting = PowerReporting.Advanced;
            Properties.CapKeyUp = false;
        }

        ~SampleKeyboard()
        {
            // Code added from previous sections to terminate
            // the read thread started by the thread-helper
            // object.
            if (ReadThread != null)
            {
                ReadThread.CloseThread();
            }

            Dispose(false);
        }

        // Expose the protected KeyDown() method so that it can be
        // called from our threading helper.
        public void SendKey(int key)
        {
            KeyDown(key);
        }

        // Expose the protected PowerState property so it can be
        // changed from the threading helper.
        public void ChangePowerState(PowerState state)
        {
            Properties.PowerState = state;
        }

        #region Override Virtual PosCommon Members
        public override void Open()
        {
            base.Open();

            // Create the reader-thread object.
            ReadThread = new KeyboardThreadingObject(this);
        }

        public override bool DeviceEnabled
        {
            get
            {
                return base.DeviceEnabled;
            }
            set
            {
                if (value != base.DeviceEnabled)
                {
                    base.DeviceEnabled = value;

                    if (value == false)
                    {
                        // Stop the reader thread when the device
                        // is disabled.
                        ReadThread.CloseThread();
                    }
                    else
                    {
                        try
                        {
                            // By enabling the device, start the
                            // reader thread.
                            ReadThread.OpenThread();
                        }
                        catch (Exception e)
                        {
                            base.DeviceEnabled = false;

                            if (e is PosControlException)
                                throw;

                            throw new PosControlException(
                                    "Unable to Enable Device",
                                    ErrorCode.Failure, e);
                        }
                    }
                }
            }
        }
        #endregion Override Virtual PosCommon Members

        #region Implement Abstract PosCommon Members
        private string MyHealthText = "";

        // PosCommon.CheckHealthText.
        public override string CheckHealthText
        {
            get
            {
                // VerifyState(mustBeClaimed,
                // mustBeEnabled).
                VerifyState(false, false);
                return MyHealthText;
            }
        }

        //  PosCommon.CheckHealth.
        public override string CheckHealth(
                        HealthCheckLevel level)
        {
            // Verify that device is open, claimed and enabled.
            VerifyState(true, true);

            // Your code here:
            // Check the health of the device and return a
            // descriptive string.

            // Cache result in the CheckHealthText property.
            MyHealthText = "Ok";
            return MyHealthText;
        }

        // PosCommon.DirectIOData.
        public override DirectIOData DirectIO(
                                int command,
                                int data,
                                object obj)
        {
            // Verify that the device is open.
            VerifyState(false, false);

            return new DirectIOData(data, obj);
        }
        #endregion  Implement Abstract PosCommon Members
    }

    #region Thread Helper Class
    public class KeyboardThreadingObject :
        ServiceObjectThreadHelper, IDisposable
    {
        // This is a helper class which will depend on
        // being able to call back into the actual Service
        // Object to pass along data. However, you cannot
        // keep a strong reference to the Service Object,
        // since that may prevent clean disposal, leaving
        // hardware resources unavailable to other processes.
        // Therefore, you create a weak reference. From this
        // reference, you can get a temporary strong reference,
        // which you can act on and then release.
        WeakReference ServiceObjectReference;

        // The name of the Service Object.
        string ObjectName;

        public KeyboardThreadingObject(SampleKeyboard so)
        {
            ObjectName = GetType().Name;
            ServiceObjectReference = new WeakReference(so);
        }

        // This method will be called during initialization.
        public override void ServiceObjectThreadOpen()
        {
            Logger.Info(ObjectName, "Keyboard Thread Open");
        }

        // This method will be called curing shutdown.
        public override void ServiceObjectThreadClose()
        {
            Logger.Info(ObjectName, "Keyboard Thread Open");
        }

        // Your code used to monitor your device for input should
        // go here. The implementation below generates simulated
        // input as an example.
        public override void ServiceObjectThreadProcedure(
                            AutoResetEvent ThreadStopEvent)
        {
            Logger.Info(ObjectName,
                            "Keyboard Thread Procedure Entered");
            int KeyValue = (int)'a';

            while (true)
            {
                // When this method is called by the
                // ServiceObjectThreadHelper, it is obligated to
                // exit when the event ThreadStopEvent has been
                // set.
                if (ThreadStopEvent.WaitOne(2000, false))
                {
                    break;
                }

                if (KeyValue <= (int) 'z')
                {
                    Logger.Info(ObjectName, "Reader Thread cycling");

                    // Try to get a strong reference to the Service
                    // Object using the weak reference saved when
                    // this helper object was created.
                    SampleKeyboard Keyboard =
                        ServiceObjectReference.Target
                        as SampleKeyboard;

                    // If this fails, that means the Service Object
                    // has already been disposed of - exit the thread.
                    if (Keyboard == null)
                    {
                        break;
                    }

                    if (Keyboard.DataEventEnabled == true)
                    {
                        // Call a method implemented in our Keyboard
                        // class to queue the key stroke.
                        Keyboard.SendKey(KeyValue);

                        // Simulate input by moving through the
                        // alphabet, sending one character at a time.
                        KeyValue++;
                        if (KeyValue >= (int)'z')
                        {
                            // Once you run out of input, simulate a
                            // power state change. Setting the SO's
                            // PowerState property to
                            // PowerState.Offline will cause a
                            // StatusUpdateEvent to be sent to the
                            // application.
                            Keyboard.ChangePowerState(
                                            PowerState.Offline);

                            // Release the strong reference.
                            Keyboard = null;

                            // There is no more work, so exit the
                            // loop.
                            break;
                        }
                    }

                    // Release the strong reference.
                    Keyboard = null;
                }
            }
        }
    }
    #endregion Thread Helper Class
}

Compilation du code

Voir aussi

Tasks

Autres ressources