事件處理常式範例 (POS for .NET v1.14 SDK 文件)
此範例示範應用程式如何為 Microsoft Point of Service for .NET (POS for .NET) 所支援之五個事件型別的任一個處理常式:
- DataEvent
- ErrorEvent
- StatusUpdateEvent
- OutputCompleteEvent
- DirectIOEvent
它也會示範應用程式如何管理對 PosPrinter 裝置的非同步輸出要求。
建立範例專案
從非同步輸出範例編譯並安裝 Service 物件範例程式碼。
在 Microsoft Visual Studio 2013 中建立 Windows Forms 應用程式專案。
下方程式碼區段會包含兩個檔案:AsyncApp.cs 和 AsyncApp.Designer.cs。
在新建立的專案中,以 AsyncApp.cs 取代 Form1.cs,並以 AsyncApp.Designer.cs 取代 Form1.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;
}
}
如果您第一次按下 [列印同步],然後按下 [列印非同步] 按鈕,程式應該會顯示下列文字。
開啟裝置:AsyncOutputPrinter,輸入:PosPrinterRegistering 事件:ErrorEventRegistering 事件:OutputCompleteEventPrinting 會同步進行。呼叫 PrintNormal 開始列印...PrintNormal 已傳回! OutputID = 0Printing 會以非同步方式進行。呼叫 PrintNormal 開始列印...PrintNormal 已傳回! OutputID = 1Microsoft.PointOfService.OutputCompleteEventArgs, TimeStamp: 11:35:39 AM, EventId: 1, OutputId: 1.