Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Um Objeto de Serviço PosKeyboard lê as teclas de um teclado POS. Um teclado POS pode ser um teclado auxiliar ou pode ser um teclado virtual que consiste em algumas ou todas as teclas no 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 de dispositivo de entrada geral:
- Quando a entrada é recebida do teclado POS, um DataEvent é enfileirado.
- Se a propriedade AutoDisable for true, o dispositivo se desativa automaticamente quando um evento DataEvent é enfileirado. Isso é feito automaticamente pela classe PosKeyboardBase .
- Um evento DataEvent enfileirado será entregue ao aplicativo quando a propriedade DataEventEnabled for true e outros requisitos de entrega de eventos forem atendidos. A classe PosKeyboardBase gerenciará a entrega de eventos automaticamente.
- Um evento ErrorEvent é enfileirado se ocorre um erro durante a coleta ou processamento de entrada, e é entregue ao aplicativo quando DataEventEnabled é true e outros requisitos de entrega de eventos são atendidos.
- A propriedade DataCount , mantida pela classe PosKeyboardBase , pode ser lida para obter o número de eventos na fila.
- Todas as entradas enfileiradas podem ser excluídas chamando ClearInput().
O teclado POS é um dispositivo de uso exclusivo:
- O aplicativo deve reivindicar o dispositivo antes de habilitá-lo.
- O aplicativo deve reivindicar e habilitar o dispositivo antes que o dispositivo comece a ler a entrada.
Esta seção contém um objeto de serviço PosKeyboard de exemplo que gera pressionamentos de tecla simulados que são enviados para o aplicativo usando DataEvents. Este exemplo depende do objeto auxiliar de thread apresentado em Introducing Service Object Reader Threads. Para compilar este exemplo, você precisa incluir o código desse tópico.
Para escrever um objeto de serviço
Adicione diretivas using para Microsoft.PointofService, Microsoft.PointOfService.BaseServiceObjects e System.Threading.
Adicione o atributo global PosAssembly.
Escolha um nome de namespace apropriado para seu projeto.
Crie uma classe de Objeto de Serviço derivada de PosKeyboardBase.
Adicione o
ServiceObjectatributo à classe Service Object usando o valor DeviceType.PosKeyboard como o tipo de dispositivo.
Para adicionar recursos ao objeto de serviço de teclado de exemplo
Crie uma classe auxiliar de thread, KeyboardThreadingObject, derivada de ServiceObjectThreadHelper, conforme descrito na seção Threads de Leitura do Objeto de Serviço.
Implemente o método ServiceObjectThreadProcedure na classe KeyboardThreadingObject . Esse é o procedimento que será executado em um thread separado. No código de exemplo abaixo, esse método simula a entrada do teclado.
Essa classe de exemplo implementa um método chamado SendKey e outro chamado ChangePowerState. Esses métodos são wrappers em torno de membros protegidos. Como eles são protegidos, eles não podem ser invocados diretamente do objeto de threading.
Substitua o método PosCommon.Open para especificar recursos compatíveis com esse Objeto de Serviço e criar um novo objeto auxiliar de thread.
Substitua o PosCommon.DeviceEnable especificamente para abrir e fechar o auxiliar de thread.
Implemente os métodos virtuais abstratos do PosCommon, fornecendo funcionalidade mínima.
Executando o aplicativo
Este objeto de serviço de exemplo pode ser executado em conjunto com o aplicativo de teste fornecido com o POS para o SDK (Software Development Kit) do .NET.
Para testar o Objeto de Serviço
Inicie o aplicativo de teste e selecione SamplePosKeyboard na lista suspensa Teclado.
Abra e reclame o dispositivo e selecione o dispositivo com a caixa de seleção DeviceEnabled para habilitá-lo.
A verificação da caixa DataEventEnabled permitirá que o Objeto de Serviço envie uma única chave simulada para o aplicativo. O DataEvent é enfileirado automaticamente pela classe PosKeyboardBase quando KeyDown é chamado.
Selecionar a caixa habilitar automaticamente eventos de dados permite que o Objeto de Serviço continue entregando caracteres a cada dois segundos.
O Objeto de Serviço enviará pressionamentos de tecla simulados para caracteres 'a' até 'z'. Depois disso, um evento StatusUpdateEvent será enviado indicando que o dispositivo agora está offline. Esse evento é enviado automaticamente pela classe PosKeyboardBase quando Properties.PowerState é alterado.
Example
Este exemplo demonstra como desenvolver um objeto de serviço PosKeyboard simples. Ele dá suporte a um thread de leitor separado para enviar DataEvents de forma assíncrona para o aplicativo. Depois de compilado, você pode executar o Objeto de Serviço em conjunto com o aplicativo de teste incluído com o POS para SDK do .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
- Este exemplo requer que o código da seção Introdução aos Threads do Leitor de Objetos de Serviço seja incluído.
- Os assemblies Microsoft.PointOfService e Microsoft.PointOfService.BaseServiceObjects devem ser referenciados.