PosKeyboard サービス オブジェクトは、POS キーボードからキーを読み取ります。 POS キーボードは補助キーボードでも、システム キーボードの一部またはすべてのキーで構成される仮想キーボードでもかまいません。 Microsoft Point of Service for .NET (POS for .NET) では、POS キーボード の基本 クラスが PosKeyboardBase。
PosKeyboard サービス オブジェクトは、一般的な入力デバイス モデルに従います。
- POS キーボードから入力を受信すると、 DataEvent がキューに入れられます。
- AutoDisable プロパティが true の場合、DataEvent イベントがキューに登録されると、デバイスは自動的に自身を無効にします。 これは 、PosKeyboardBase クラスによって自動的に行われます。
- DataEventEnabled プロパティが true で、その他のイベント配信要件が満たされると、キューに登録された DataEvent イベントがアプリケーションに配信されます。 PosKeyboardBase クラスは、イベント配信を自動的に管理します。
- ErrorEvent イベントは、入力の収集または処理中にエラーが発生した場合にキューに登録され、DataEventEnabled が true で、その他のイベント配信要件が満たされたときにアプリケーションに配信されます。
- PosKeyboardBase クラスによって保持される DataCount プロパティを読み取って、キューに登録されたイベントの数を取得できます。
- キューに登録されているすべての入力は、 ClearInput()を呼び出すことによって削除できます。
POS キーボードは、排他的に使用されるデバイスです。
- アプリケーションは、デバイスを有効にする前に要求する必要があります。
- アプリケーションは、デバイスが入力の読み取りを開始する前に、デバイスを要求して有効にする必要があります。
このセクションには、DataEvents を使用してアプリケーションに送信されるシミュレートされたキーストロークを生成するサンプル PosKeyboard サービス オブジェクトが含まれています。 このサンプルは、「サービス オブジェクト リーダー スレッドの概要」に示されている スレッド ヘルパー オブジェクトに依存します。 このサンプルをコンパイルするには、そのトピックのコードを含める必要があります。
サービス オブジェクトを書き込むには
using ディレクティブを Microsoft.PointofService、Microsoft.PointOfService.BaseServiceObjects、および System.Threading に追加します。
グローバル属性 PosAssembly を追加します。
プロジェクトに適した名前空間名を選択します。
PosKeyboardBase から派生した Service Object クラスを作成します。
デバイスの種類として
ServiceObject値を使用して、属性を Service Object クラスに追加します。
サンプル キーボードのサービス オブジェクトに機能を追加するには
Service Object Read Threads セクションから ServiceObjectThreadHelper から派生したスレッド ヘルパー クラス KeyboardThreadingObject を作成します。
KeyboardThreadingObject クラスに ServiceObjectThreadProcedure メソッドを実装します。 これは、別のスレッドで実行されるプロシージャです。 次のサンプル コードでは、このメソッドはキーボード入力をシミュレートします。
このサンプル クラスは、 SendKey というメソッドと ChangePowerState という別のメソッドを実装します。 これらのメソッドはプロテクトされたメンバーのラッパーです。 これらは保護されているため、スレッド オブジェクトから直接呼び出すことはできません。
PosCommon.Open メソッドをオーバーライドして、このサービス オブジェクトでサポートされる機能を指定し、新しいスレッド ヘルパー オブジェクトを作成します。
スレッド ヘルパーを開くおよび閉じるために、PosCommon.DeviceEnable を特にオーバーライドします。
PosCommon から抽象仮想メソッドを実装し、最小限の機能を提供します。
アプリケーションの実行
このサンプル サービス オブジェクトは、POS for .NET Software Development Kit (SDK) で提供されるテスト アプリケーションと組み合わせて実行できます。
サービス オブジェクトをテストするには
テスト アプリケーションを起動し、[キーボード] ドロップダウン リストから SamplePosKeyboard を選択します。
デバイスを開いて要求し、DeviceEnabled チェック ボックスをオンにしてデバイスを有効にします。
[DataEventEnabled] ボックスをオンにすると、サービス オブジェクトは 1 つのシミュレートされたキーをアプリケーションに送信できます。 KeyDown が呼び出されると、DataEvent は PosKeyboardBase クラスによって自動的にキューに入れられます。
[ データ イベントを自動的に有効にする ] ボックスを選択すると、サービス オブジェクトは 2 秒間隔で文字の配信を続行できます。
Service オブジェクトは、'a' から 'z' までの文字のシミュレートされたキー ストロークを送信します。 その後、デバイスがオフラインになったことを示す StatusUpdateEvent イベントが送信されます。 このイベントは、Properties.PowerState が変更されると、PosKeyboardBase クラスによって自動的に送信されます。
Example
このサンプルでは、単純な PosKeyboard Service オブジェクトを開発する方法を示します。 DataEvents をアプリケーションに非同期的に送信する別のリーダー スレッドがサポートされています。 コンパイル後、.NET SDK 用 POS に含まれるテスト アプリケーションと共にサービス オブジェクトを実行できます。
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
}
コードのコンパイル
- このサンプルでは、「 サービス オブジェクト リーダー スレッドの概要 」セクションのコードを含める必要があります。
- アセンブリ Microsoft.PointOfService と Microsoft.PointOfService.BaseServiceObjects を参照する必要があります。
こちらもご覧ください
タスク
その他のリソース
.NET