Partilhar via


Implementação do PosKeyboard (POS para Documentação do SDK .NET v1.14)

Um Objeto de Serviço PosKeyboard lê teclas de um teclado POS. Um teclado POS pode ser um teclado auxiliar, ou pode ser um teclado virtual composto por algumas ou todas as teclas do teclado do sistema. No Microsoft Point of Service para .NET (POS para .NET), a classe base do teclado POS é PosKeyboardBase.

Um Objeto de Serviço PosKeyboard segue o modelo geral de dispositivo de entrada:

  • Quando é recebida uma entrada do teclado POS, um DataEvent é colocado na fila.
  • Se a propriedade AutoDisablefor verdadeira, então o dispositivo desativa-se automaticamente quando um evento DataEvent está em fila. Isto é feito automaticamente pela classe PosKeyboardBase .
  • Um evento DataEvent em fila será entregue à aplicação quando a propriedade DataEventEnabled for verdadeira e outros requisitos de entrega de eventos forem cumpridos. A classe PosKeyboardBase gerirá automaticamente a entrega dos eventos.
  • Um evento ErrorEvent é colocado em fila se ocorrer um erro durante a recolha ou o processamento de dados e é entregue à aplicação quando DataEventEnabled for verdadeiro e outros requisitos de entrega de eventos forem cumpridos.
  • A propriedade DataCount , que é mantida pela classe PosKeyboardBase , pode ser lida para obter o número de eventos em fila.
  • Todas as entradas em fila podem ser eliminadas ao chamar ClearInput().

O teclado POS é um dispositivo de uso exclusivo:

  • A aplicação deve reclamar o dispositivo antes de o ativar.
  • A aplicação deve reclamar e ativar o dispositivo antes de este começar a ler a entrada.

Esta secção contém um exemplo de Objeto de Serviço PosKeyboard que gera pressionamentos simulados que são enviados para a aplicação usando DataEvents. Este exemplo depende do objeto auxiliar de threads apresentado em Introdução às Threads de Leitores de Objetos de Serviço. Para compilar este exemplo, precisas de incluir o código desse tópico.

Para escrever um Objeto de Serviço

  1. Adicionar diretivas usadas para Microsoft.PointofService, Microsoft.PointOfService.BaseServiceObjects e System.Threading.

  2. Adicione o atributo global PosAssembly.

  3. Escolha um nome de namespace apropriado para o seu projeto.

  4. Crie uma classe de Objeto de Serviço derivada do PosKeyboardBase.

  5. Adicione o ServiceObject atributo à sua classe Service Object, usando o valor DeviceType.PosKeyboard como tipo de dispositivo.

Para adicionar funcionalidades ao Objecto de Serviço do teclado de exemplo

  1. Crie uma classe auxiliar de threads, KeyboardThreadingObject, derivada de ServiceObjectThreadHelper a partir da secção Service Object Read Threads .

  2. Implemente o método ServiceObjectThreadProcedure na classe KeyboardThreadingObject . Este é o procedimento que será executado numa thread separada. No código de exemplo abaixo, este método simula a entrada do teclado.

  3. Esta classe de exemplo implementa um método chamado SendKey e outro chamado ChangePowerState. Estes métodos são envoltórios em torno de membros protegidos. Como estão protegidos, não podem ser invocados diretamente do objeto threading.

  4. Sobrescreva o método PosCommon.Open para especificar capacidades suportadas por este Objeto de Serviço e crie um novo objeto auxiliar de threads.

  5. Sobrescrever o PosCommon.DeviceEnable especificamente para abrir e fechar o auxiliar de thread.

  6. Implemente os métodos virtuais abstratos do PosCommon, fornecendo funcionalidade mínima.

Executando o aplicativo

Este exemplo de Objeto de Serviço pode ser executado em conjunto com a aplicação de teste fornecida com o POS for .NET Software Development Kit (SDK).

Para testar o Objeto de Serviço

  1. Inicie a aplicação de teste e selecione SamplePosKeyboard na lista suspensa do Teclado.

  2. Abre e regista o dispositivo e depois seleciona o dispositivo com a caixa de seleção DeviceEnabled para o ativar.

  3. Assinalar a caixa DataEventEnabled permitirá que o Objeto de Serviço envie uma única chave simulada para a aplicação. O DataEvent é colocado automaticamente na fila pela classe PosKeyboardBase quando o KeyDown é chamado.

  4. Selecionar a caixa Ativar automaticamente eventos de dados permite que o Objeto de Serviço continue a entregar caracteres, com dois segundos de intervalo.

  5. O Objeto de Serviço enviará simulações de teclas para os caracteres 'a' a 'z'. Depois disso, será enviado um evento StatusUpdateEvent indicando que o dispositivo está offline. Este evento é enviado automaticamente pela classe PosKeyboardBase quando o Properties.PowerState é alterado.

Example

Este exemplo demonstra como desenvolver um simples Objeto de Serviço PosKeyboard . Suporta um thread de leitura separado para enviar DataEvents de forma assíncrona para a aplicação. Uma vez compilado, pode executar o Objeto de Serviço em conjunto com a aplicação de teste incluída no POS para o SDK .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
}

Compilando o código

Ver também

Tasks

Outros recursos