此示例演示应用程序如何为 Microsoft Point of Service for .NET (POS for .NET) 支持的任何五种事件类型注册处理程序:
- DataEvent
- ErrorEvent
- StatusUpdateEvent
- OutputCompleteEvent
- DirectIOEvent
它还演示了应用程序如何管理对 PosPrinter 设备的异步输出请求。
创建示例项目
编译并安装异步输出示例中的服务对象示例代码。
在 Microsoft Visual Studio 2013 中创建 Windows 窗体应用程序项目。
下面的代码部分包括两个文件:AsyncApp.cs 和 AsyncApp.Designer.cs。
在新创建的项目中,将 Form1.cs 替换为 AsyncApp.cs,将 Form1.Designer.cs 替换为 AsyncApp.Designer.cs。
如果尚未创建项目,请添加对 Microsoft.PointOfService.dll 的程序集引用。 在标准安装中,可以在 Program Files (x86)\Microsoft Point Of Service\SDK 下找到此文件。
编译和运行。
运行示例
此示例显示一个 GUI 用户界面,该界面允许用户将异步和同步打印请求发送到异步输出示例服务对象。
服务对象等待几秒钟,然后从请求返回,而无论是同步请求还是异步请求。
UI 在文本框中显示每个请求的状态。
示例
此示例代码演示了几个要点:
- 使用 OutputCompleteEvent 事件通知应用程序服务对象已完成输出请求。
- 注册事件处理程序,包括使用反射来执行此操作。
- 使用 PosExplorer 搜索特定的服务对象。
为了演示如何使用反射来发现给定对象上可用的事件,此代码使用从 CreateInstance(DeviceInfo) 返回的 PosCommon 对象,而无需先将其强制转换为 PosPrinter。 在大多数情况下,应用程序不需要以这种方式为泛型,因此会根据需要强制转换对象。
// ASYNCAPP.CS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Reflection;
using Microsoft.PointOfService;
namespace AsyncOutputApp
{
public partial class AsyncApp : Form
{
PosCommon posCommon;
PosExplorer posExplorer;
public AsyncApp()
{
InitializeComponent();
btnPrintAsync.Enabled = true;
btnPrintSync.Enabled = true;
posExplorer = new PosExplorer(this);
posCommon = null;
string SOName = "AsyncOutputPrinter";
try
{
OpenDevice(SOName);
SetupEvents();
}
catch
{
MessageBox.Show("The Service Object '" +
SOName + "' failed to load",
"Service Object Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
btnPrintAsync.Enabled = false;
btnPrintSync.Enabled = false;
}
}
private void OpenDevice(string SOName)
{
string str = txtPrintResults.Text;
DeviceInfo device = null;
txtPrintResults.Clear();
{
// Retrieve the list of PosPrinter Service Objects.
DeviceCollection devices =
posExplorer.GetDevices(
DeviceType.PosPrinter);
// Iterate through the list looking for the one
// needed for this sample.
foreach(DeviceInfo d in devices)
{
if(d.ServiceObjectName == SOName)
{
device = d;
break;
}
}
if (device == null)
{
throw new Exception("Service Object not found");
}
txtPrintResults.Text = "Opening device: " +
device.ServiceObjectName + ", type: " +
device.Type + "\r\n";
posCommon =
(PosCommon)posExplorer.CreateInstance(device);
posCommon.Open();
posCommon.Claim(0);
posCommon.DeviceEnabled = true;
}
}
// When this button is pressed, AsyncMode is turned off,
// and the application waits for each print request
// to complete before regaining control.
private void btnPrintSync_Click(object sender, EventArgs e)
{
PosPrinter posPrinter = posCommon as PosPrinter;
posPrinter.AsyncMode = false;
txtPrintResults.AppendText(
"Printing will take place " +
"synchronously.\r\n");
StartPrinting();
}
// When this button is pressed, AsyncMode is turned on. Print
// requests will be queued and delivered on a
// first-in-first-out basis.
private void btnPrintAsync_Click(object sender, EventArgs e)
{
PosPrinter posPrinter = posCommon as PosPrinter;
posPrinter.AsyncMode = true;
txtPrintResults.AppendText(
"Printing will take place " +
"asynchronously.\r\n");
StartPrinting();
}
private void StartPrinting()
{
PosPrinter posPrinter = posCommon as PosPrinter;
txtPrintResults.AppendText(
"Calling PrintNormal to start " +
"printing...\r\n");
// Notice that calling PrintNormal() here may not result
// in a print request being sent immediately to the
// printer. In asynchronous mode, the requested is
// placed in a first-in-first-out queue managed by
// POS for .NET.
try
{
posPrinter.PrintNormal(
PrinterStation.Receipt,
"This is do-nothing print data");
}
catch (PosControlException e)
{
txtPrintResults.AppendText(
"PrintNormal threw a " +
"PosControlException! Description: " +
e.Message + "\r\n");
return;
}
// When data is sent to an output device, POS for .NET
// updates the OutputId property in the target object.
// When an OutputCompleteEvent is sent to the app,
// the OutputCompleteEventArgs will contain this id.
Int32 id = posPrinter.OutputId;
txtPrintResults.AppendText(
"PrintNormal has returned! OutputID = " +
id + "\r\n");
}
// Visual Studio-generated code.
private void AsyncApp_Load(object sender, EventArgs e)
{
}
#region Event Registration
private void SetupEvents()
{
// All PosCommon objects support StatusUpdateEvent and
// DirectIOEvent events, so simply register a handler
// for those events.
posCommon.StatusUpdateEvent +=
new StatusUpdateEventHandler(
co_OnStatusUpdateEvent);
posCommon.DirectIOEvent +=
new DirectIOEventHandler(
co_OnDirectIOEvent);
// In addition to the events common to all devices
// (StatusUpdateEvent and DirectIOEvent), a device
// type may also support DataEvent, ErrorEvent, or
// OutputCompleteEvent events.
//
// In this example, the following code uses reflection
// to determine which events are supported by this
// object (posCommon).
//
// However, in the general case, an application will know
// what type of device was returned when PosExplorer
// CreateInstance() was called;therefore will not
// need to use reflection, but can instead register
// event handlers using the mechanism used for
// StatusUpdateEvent and DirectIOEvent events above.
EventInfo dataEvent =
posCommon.GetType().GetEvent(
"DataEvent");
if (dataEvent != null)
{
dataEvent.AddEventHandler(posCommon,
new DataEventHandler(
co_OnDataEvent));
txtPrintResults.AppendText("Registering Event: " +
"DataEvent\r\n");
}
EventInfo errorEvent =
posCommon.GetType().GetEvent(
"ErrorEvent");
if (errorEvent != null)
{
errorEvent.AddEventHandler(posCommon,
new DeviceErrorEventHandler(
co_OnErrorEvent));
txtPrintResults.AppendText("Registering Event: " +
"ErrorEvent\r\n");
}
EventInfo outputCompleteEvent =
posCommon.GetType().GetEvent(
"OutputCompleteEvent");
if (outputCompleteEvent != null)
{
outputCompleteEvent.AddEventHandler(
posCommon, new OutputCompleteEventHandler(
co_OnOutputCompleteEvent));
txtPrintResults.AppendText("Registering Event: " +
"OutputCompleteEvent\r\n");
}
}
#endregion Event Registration
#region Event Handlers
private void co_OnDataEvent(
object obj,
DataEventArgs d)
{
txtPrintResults.AppendText(d.ToString() + "\r\n");
}
private void co_OnStatusUpdateEvent(
object source,
StatusUpdateEventArgs d)
{
txtPrintResults.AppendText(d.ToString() + "\r\n");
}
private void co_OnDirectIOEvent(
object source,
DirectIOEventArgs d)
{
txtPrintResults.AppendText(d.ToString() + "\r\n");
}
private void co_OnErrorEvent(
object source,
DeviceErrorEventArgs d)
{
string str = d.ToString();
MessageBox.Show(d.ToString(),
"OnErrorEvent called",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
txtPrintResults.AppendText(d.ToString() + "\r\n");
}
private void co_OnOutputCompleteEvent(
object source,
OutputCompleteEventArgs d)
{
txtPrintResults.AppendText(d.ToString() + "\r\n");
}
#endregion Event Handlers
}
}
// ASYNCAPP.DESIGNER.CS
namespace AsyncOutputApp
{
partial class AsyncApp
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.txtPrintResults = new System.Windows.Forms.TextBox();
this.btnPrintSync = new System.Windows.Forms.Button();
this.btnPrintAsync = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// txtPrintResults
//
this.txtPrintResults.BackColor = System.Drawing.SystemColors.Window;
this.txtPrintResults.Location = new System.Drawing.Point(12, 119);
this.txtPrintResults.Multiline = true;
this.txtPrintResults.Name = "txtPrintResults";
this.txtPrintResults.ReadOnly = true;
this.txtPrintResults.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtPrintResults.Size = new System.Drawing.Size(650, 200);
this.txtPrintResults.TabIndex = 3;
//
// btnPrintSync
//
this.btnPrintSync.Location = new System.Drawing.Point(12, 12);
this.btnPrintSync.Name = "btnPrintSync";
this.btnPrintSync.Size = new System.Drawing.Size(132, 39);
this.btnPrintSync.TabIndex = 1;
this.btnPrintSync.Text = "Print Synchronous";
this.btnPrintSync.UseVisualStyleBackColor = true;
this.btnPrintSync.Click += new System.EventHandler(this.btnPrintSync_Click);
//
// btnPrintAsync
//
this.btnPrintAsync.Location = new System.Drawing.Point(12, 57);
this.btnPrintAsync.Name = "btnPrintAsync";
this.btnPrintAsync.Size = new System.Drawing.Size(132, 39);
this.btnPrintAsync.TabIndex = 2;
this.btnPrintAsync.Text = "Print Asynchronously";
this.btnPrintAsync.UseVisualStyleBackColor = true;
this.btnPrintAsync.Click += new System.EventHandler(this.btnPrintAsync_Click);
//
// AsyncApp
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(685, 331);
this.Controls.Add(this.btnPrintAsync);
this.Controls.Add(this.btnPrintSync);
this.Controls.Add(this.txtPrintResults);
this.Name = "AsyncApp";
this.Text = "Form1";
this.Load += new System.EventHandler(this.AsyncApp_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtPrintResults;
private System.Windows.Forms.Button btnPrintSync;
private System.Windows.Forms.Button btnPrintAsync;
}
}
如果先按“同步打印”,然后按“异步打印”按钮,程序应显示以下文本。
Opening device: AsyncOutputPrinter, type: PosPrinterRegistering Event: ErrorEventRegistering Event: OutputCompleteEventPrinting will take place synchronously.Calling PrintNormal to start printing...PrintNormal has returned! OutputID = 0Printing will take place asynchronously.Calling PrintNormal to start printing...PrintNormal has returned! OutputID = 1Microsoft.PointOfService.OutputCompleteEventArgs, TimeStamp: 11:35:39 AM, EventId: 1, OutputId: 1.