Udostępnij przez


Implementacja PosKeyboard (dokumentacja SDK POS dla platformy .NET w wersji 1.14)

Obiekt usługi PosKeyboard odczytuje klawisze z klawiatury POS. Klawiatura POS może być klawiaturą pomocniczą lub klawiaturą wirtualną, składającą się z niektórych lub wszystkich klawiszy klawiatury systemowej. W usłudze Microsoft Point of Service for .NET (POS for .NET) klasa podstawowa klawiatury POS to PosKeyboardBase.

Obiekt usługi PosKeyboard jest zgodny z ogólnym modelem urządzenia wejściowego:

  • Po odebraniu danych wejściowych z klawiatury POS, element DataEvent jest dodawany do kolejki.
  • Jeśli właściwość AutoDisable ma wartość true, to urządzenie automatycznie wyłącza się, gdy zdarzenie DataEvent zostanie umieszczone w kolejce. Jest to wykonywane automatycznie przez klasę PosKeyboardBase .
  • Zdarzenie DataEvent w kolejce zostanie dostarczone do aplikacji, gdy właściwość DataEventEnabled ma wartość true , a inne wymagania dotyczące dostarczania zdarzeń zostaną spełnione. Klasa PosKeyboardBase automatycznie zarządza dostarczaniem zdarzeń.
  • Zdarzenie ErrorEvent jest kolejkowane, jeśli wystąpi błąd podczas zbierania lub przetwarzania danych wejściowych, i jest dostarczane do aplikacji, gdy DataEventEnabled jest ustawiony na wartość true, i spełnione są inne wymagania dotyczące dostarczania zdarzeń.
  • Właściwość DataCount , która jest utrzymywana przez klasę PosKeyboardBase , może być odczytywana w celu uzyskania liczby zdarzeń w kolejce.
  • Wszystkie dane wejściowe w kolejce mogą zostać usunięte przez wywołanie metody ClearInput().

Klawiatura POS to urządzenie do wyłącznego użytku.

  • Aplikacja musi zarejestrować urządzenie przed jego włączeniem.
  • Aplikacja musi przejąć i włączyć urządzenie przed rozpoczęciem odczytywania danych wejściowych przez urządzenie.

Ta sekcja zawiera przykładowy obiekt usługi PosKeyboard , który generuje symulowane naciśnięcia wysyłane do aplikacji przy użyciu modułów DataEvents. Ten przykład opiera się na obiekcie pomocnika wątku przedstawionym w Wprowadzenie do wątków czytnika obiektów usługi. Aby skompilować ten przykład, należy dołączyć kod z tego tematu.

Aby napisać obiekt usługi

  1. Dodaj dyrektywy using dla obiektów Microsoft.PointofService, Microsoft.PointOfService.BaseServiceObjects i System.Threading.

  2. Dodaj atrybut globalny PosAssembly.

  3. Wybierz odpowiednią nazwę przestrzeni nazw dla projektu.

  4. Utwórz klasę obiektu usługi pochodzącą z bazy danych PosKeyboardBase.

  5. ServiceObject Dodaj atrybut do klasy Obiekt usługi przy użyciu wartości DeviceType.PosKeyboard jako typu urządzenia.

Aby dodać funkcje do przykładowego obiektu usługi klawiatury

  1. Utwórz klasę pomocnika wątków KeyboardThreadingObject, pochodzącą od ServiceObjectThreadHelper z sekcji Service Object Read Threads.

  2. Zaimplementuj metodę ServiceObjectThreadProcedure w klasie KeyboardThreadingObject . Jest to procedura, która zostanie uruchomiona w osobnym wątku. W poniższym przykładowym kodzie ta metoda symuluje wprowadzanie klawiatury.

  3. Ta przykładowa klasa implementuje metodę o nazwie SendKey i inną o nazwie ChangePowerState. Te metody oprawiają chronione składniki. Ponieważ są one chronione, nie mogą być wywoływane bezpośrednio z obiektu wątkowego.

  4. Zastąpij metodę PosCommon.Open , aby określić możliwości obsługiwane przez ten obiekt usługi i utworzyć nowy obiekt pomocnika wątku.

  5. Zastąp element PosCommon.DeviceEnable w celu otwierania i zamknięcia wątkowego pomocnika.

  6. Zaimplementuj abstrakcyjne metody wirtualne z programu PosCommon, zapewniając minimalną funkcjonalność.

Uruchamianie aplikacji

Ten przykładowy obiekt usługi można uruchomić w połączeniu z aplikacją testową dostarczoną z rozwiązaniem POS dla zestawu .NET Software Development Kit (SDK).

Aby przetestować obiekt usługi

  1. Uruchom aplikację testową i wybierz pozycję SamplePosKeyboard z listy rozwijanej Klawiatura .

  2. Otwórz i zarejestruj urządzenie, a następnie zaznacz pole wyboru DeviceEnabled dla urządzenia, aby je włączyć.

  3. Zaznaczenie pola DataEventEnabled umożliwi obiektowi usługi wysyłanie pojedynczego symulowanego klucza do aplikacji. Element DataEvent jest automatycznie kolejkowany przez klasę PosKeyboardBase po wywołaniu polecenia KeyDown .

  4. Wybranie pola Automatycznie włącz zdarzenia danych umożliwia obiektowi usługi kontynuowanie dostarczania znaków w odstępie dwóch sekund.

  5. Obiekt usługi będzie wysyłać symulowane naciśnięcia klawiszy dla znaków od 'a' do 'z'. Następnie zostanie wysłane zdarzenie StatusUpdateEvent wskazujące, że urządzenie jest teraz w trybie offline. To zdarzenie jest wysyłane automatycznie przez klasę PosKeyboardBase po zmianie właściwości.PowerState .

Example

W tym przykładzie pokazano, jak utworzyć prosty obiekt usługi PosKeyboard . Obsługuje oddzielny wątek czytnika do asynchronicznego wysyłania DataEvents do aplikacji. Po skompilowaniu można wykonać obiekt usługi w połączeniu z aplikacją testową dołączoną do zestawu SDK POS for .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
}

Kompilowanie kodu

Zobacz też

Tasks

Inne zasoby