Sdílet prostřednictvím


Implementace PosKeyboard (Dokumentace k sadě SDK POS pro .NET v1.14)

Objekt služby PosKeyboard čte klávesy z klávesnice POS. Klávesnice POS může být pomocná klávesnice nebo se může jednat o virtuální klávesnici, která se skládá z některých nebo všech kláves na systémové klávesnici. Ve službě Microsoft Point of Service for .NET (POS pro .NET) je POS klávesnice základní třídaPosKeyboardBase.

Objekt služby PosKeyboard se řídí obecným vstupním modelem zařízení:

  • Při přijetí vstupu z klávesnice POS se DataEvent zařadí do fronty.
  • Pokud je vlastnost AutoDisabletrue, zařízení se automaticky zakáže, když je událost DataEvent zařazena do fronty. To se provádí automaticky pomocí Třídy PosKeyboardBase .
  • Událost DataEvent zařazená do fronty se doručí do aplikace, pokud je vlastnost DataEventEnabledpravdivá a splní se další požadavky na doručení událostí. Třída PosKeyboardBase bude automaticky spravovat doručování událostí.
  • Událost ErrorEvent se zařadí do fronty, pokud dojde k chybě při shromažďování nebo zpracování vstupu a doručí se do aplikace, když je dataEventEnabledpravdivá a jsou splněny další požadavky na doručení událostí.
  • DataCount vlastnost spravovaná třídou PosKeyboardBase může být přečtena pro získání počtu událostí ve frontě.
  • Všechny vstupy ve frontě mohou být odstraněny voláním ClearInput().

Klávesnice POS je exkluzivní zařízení:

  • Aplikace musí zařízení před povolením deklarovat.
  • Aplikace musí zařízení deklarovat a povolit, než zařízení začne číst vstup.

Tato část obsahuje ukázkový objekt služby PosKeyboard , který generuje simulované stisknutí kláves, které se odesílají do aplikace pomocí DataEvents. Tato ukázka závisí na pomocném objektu vlákna zobrazeném v Představení vláken čtenáře objektů služby. Pokud chcete tuto ukázku zkompilovat, musíte zahrnout kód z tohoto tématu.

Vytvořit objekt služby

  1. Přidejte direktivy using pro Microsoft.PointofService, Microsoft.PointOfService.BaseServiceObjects a System.Threading.

  2. Přidejte globální atribut PosAssembly.

  3. Zvolte vhodný název oboru názvů pro váš projekt.

  4. Vytvořte třídu Service Object odvozenou z PosKeyboardBase.

  5. ServiceObject Přidejte atribut do třídy Service Object a jako typ zařízení použijte hodnotu DeviceType.PosKeyboard.

Přidání funkcí do ukázkového objektu služby klávesnice

  1. Vytvořte pomocnou třídu vlákna KeyboardThreadingObject odvozenou z ServiceObjectThreadHelper z oddílu Čtení vláken objektu služby .

  2. Implementujte Metodu ServiceObjectThreadProcedure ve třídě KeyboardThreadingObject . Jedná se o postup, který se spustí v samostatném vlákně. V níže uvedeném vzorovém kódu tato metoda simuluje vstup klávesnice.

  3. Tato ukázková třída implementuje metodu s názvem SendKey a další s názvem ChangePowerState. Tyto metody jsou obaly kolem chráněných členů. Protože jsou chráněné, nelze je vyvolat přímo z objektu vlákna.

  4. Přepište metodu PosCommon.Open pro určení schopností, které tento objekt služby podporuje, a vytvoření nového pomocného objektu vlákna.

  5. Přepište PosCommon.DeviceEnable speciálně pro otevření a zavření pomocné rutiny vlákna.

  6. Implementujte abstraktní virtuální metody z PosCommon a poskytněte minimální funkčnost.

Spuštění aplikace

Tento ukázkový objekt služby lze spustit ve spojení s testovací aplikací poskytovanou se sadou POS pro sadu .NET Software Development Kit (SDK).

Otestování objektu služby

  1. Spusťte testovací aplikaci a v rozevíracím seznamu Klávesnice vyberte SamplePosKeyboard.

  2. Otevřete a přiřaďte zařízení, a poté zaškrtněte políčko DeviceEnabled pro jeho povolení.

  3. Zaškrtnutím pole DataEventEnabled umožníte objektu služby odeslat do aplikace jeden simulovaný klíč. DataEvent je automaticky zařazen do fronty třídou PosKeyboardBase při volání KeyDown.

  4. Výběrem pole Automatické povolení datových událostí umožníte objektu služby pokračovat v doručování znaků, dva sekundy od sebe.

  5. Objekt služby odešle simulované tahy kláves pro znaky "a" až 'z'. Potom se odešle událost StatusUpdateEvent , která značí, že zařízení je teď offline. Tato událost je automaticky odeslána třídou PosKeyboardBase, když je Properties.PowerState změněn.

Example

Tato ukázka ukazuje, jak vytvořit jednoduchý objekt služby PosKeyboard . Podporuje samostatné vlákno čtečky pro asynchronní odesílání objektů DataEvent do aplikace. Po kompilaci můžete spustit objekt služby ve spojení s testovací aplikací, která je součástí POS pro sadu .NET SDK.

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
}

Probíhá kompilace kódu

Viz také

Tasks

Další zdroje informací