# 拓思德点阵笔 引用 ```csharp using TStudyDigitalPen.HID; ``` 代码 ```csharp #region 拓思德点阵笔 #region 值初始化 // 不同尺寸点阵纸点阵宽高尺寸计算方法为:纸张物理尺寸(毫米)/0.3 *8,详见 开发必读.pdf 文档 /// /// A4点阵纸点阵宽度 /// private const int A4_WIDTH = 5600; /// /// A4点阵纸点阵高度 /// private const int A4_HEIGHT = 7920; ///// ///// 画板 ///// //private Graphics graphics; /// /// 笔画坐标数组 /// //private List stroke; /// /// 笔序列号 /// private string penSerial; /// /// 笔是否在点 /// private bool isPenDown; //当前点阵地址 private string currentPageSerial = string.Empty; //不同点阵地址对应的笔迹绘制图片,用于实现在不同点阵地址书写切换时,显示书写内容自动切换 //本例图片放在内存中存储,对于大量或者需要在多个点阵地址对应图片进行切换演示,建议将图片存储到文件,以免内存溢出 private Dictionary pagesDic = new Dictionary(); #endregion 值初始化 public void InitTSDPen() { //stroke = new List(); //获取点阵笔实例,并绑定点阵笔事件 //将授权文件内容传入,获取点阵笔对象实例 APP.digitalPen = DigitalPenHID.GetInstance(certificates.MyLicense.Bytes); //绑定笔连接事件 APP.digitalPen.PenConnected += OnTSDPenConnect; //绑定笔断开事件 APP.digitalPen.PenDisconnect += OnTSDPenDisconnect; //绑定笔书写输出坐标事件 APP.digitalPen.PenCoordinate += OnTSDPenCoordinate; //绑定抬笔事件 APP.digitalPen.PenUp += OnTSDPenUp; //绑定落笔事件 APP.digitalPen.PenDown += OnTSDPenDown; APP.digitalPen.PenBatteryCapacity += OnTSDBatteryCapacity; APP.digitalPen.PenMemoryFillLevel += OnTSDMemoryFillLevel; //完成初始化点阵笔,开始与点阵笔通信 ERROR_CODE ER = APP.digitalPen.Start(); //启动接收笔数据,完成初始化工作 ERROR_CODE rc = APP.digitalPen.Start(); //判断是否成功 if (ER != ERROR_CODE.ERROR_OK) { MessageWindow.Show("初始化失败,授权过期,返回值:" + ER.ToString()); } } /// /// 落笔 /// /// /// 时间戳,1970年1月1日到现在的总毫秒数 /// /// /// 点阵笔序列号 /// /// /// 点阵笔型号编号 /// private void OnTSDPenDown(ulong time, string penSerial, int penType) { if (CheckAccess()) { Action action = new Action(OnTSDPenDown); Dispatcher.Invoke(action, new object[] { time, penSerial, penType }); } else { isPenDown = true; } } /// /// 抬笔 /// /// /// 时间戳,1970年1月1日到现在的总毫秒数 /// /// /// 点阵笔序列号 /// /// /// 点阵笔型号编号 /// private void OnTSDPenUp(ulong time, string penSerial, int penType) { if (CheckAccess()) { Action action = new Action(OnTSDPenUp); Dispatcher.Invoke(action, new object[] { time, penSerial, penType }); } else { isPenDown = false; APP.PenSerial = penSerial; } if (APP.PageContextData.currpage > 0) { Dispatcher.Invoke(new Action(() => { myblackboard.changepages(0, 0, true, Color, PenSize, APP.PageContextData.currpage - 1, 0); })); } } /// /// 笔断开 /// /// /// 时间戳,1970年1月1日到现在的总毫秒数 /// /// /// 点阵笔序列号 /// /// /// 点阵笔型号编号 /// private void OnTSDPenDisconnect(ulong time, string penSerial, int penType) { if (CheckAccess()) { Action action = new Action(OnTSDPenDisconnect); Dispatcher.Invoke(action, new object[] { time, penSerial, penType }); } else { APP.PenSerial = penSerial; APP.PenStatus = false; UpdateDevStatus(); } } /// /// 笔连接 /// /// /// 时间戳,1970年1月1日到现在的总毫秒数 /// /// /// 点阵笔序列号 /// /// /// 点阵笔型号编号 /// private void OnTSDPenConnect(ulong time, string penSerial, int penType) { if (CheckAccess()) { Action action = new Action(OnTSDPenConnect); Dispatcher.Invoke(action, new object[] { time, penSerial, penType }); } else { APP.PenSerial = penSerial; APP.PenStatus = true; this.penSerial = penSerial; //连接后,在获取笔数据前,可以清除笔内的历史数据 //APP.digitalPen.ClearMemory(penSerial); //开始接收笔数据 APP.digitalPen.GetPenData(penSerial); UpdateDevStatus(); } } /// /// 电池电量 /// /// /// /// /// /// /// /// /// private void OnTSDBatteryCapacity(ulong time, string penSerial, int penType, byte capacity) { if (CheckAccess()) { Action action = new Action(OnTSDBatteryCapacity); Dispatcher.Invoke(action, new object[] { time, penSerial, penType, capacity }); } else { //System.Windows.MessageWindow.Show("电池电量:" + capacity.ToString()); } } /// /// 已用存储 /// /// /// /// /// /// /// /// /// private void OnTSDMemoryFillLevel(ulong time, string penSerial, int penType, byte fillLevel) { if (CheckAccess()) { Action action = new Action(OnTSDMemoryFillLevel); Dispatcher.Invoke(action, new object[] { time, penSerial, penType, fillLevel }); } else { } } /// /// 笔书写,收到坐标 /// /// /// 时间戳,1970年1月1日到现在的总毫秒数 /// /// /// 点阵笔序列号 /// /// /// 点阵笔型号编号 /// /// /// 点阵地址 /// /// /// x坐标 /// /// /// y坐标 /// /// /// 压力值 /// private void OnTSDPenCoordinate(ulong time, string penSerial, int penType, string pageSerial, int cx, int cy, byte force) { if (CheckAccess()) { Action ac = new Action(OnTSDPenCoordinate); Dispatcher.Invoke(ac, new object[] { time, pageSerial, penType, pageSerial, cx, cy, force }); } else { //判断是否是落笔后输出的坐标,在设置悬浮模式下,落笔前的悬浮坐标不绘制 if (!isPenDown) { return; } //stroke.Add(new System.Drawing.Point(cx, cy)); double PropW = blackboard_canvas.ActualWidth / A4_WIDTH; double PropH = blackboard_canvas.ActualHeight / A4_HEIGHT; //点 double tempX = cx * PropW; double tempY = cy * PropH; //pageSerial //点阵IP地址 与打印的页面关联 if (APP.PageContextData.currpage > 0) { Dispatcher.Invoke(new Action(() => { float Pressure = force / 100f; //myblackboard.changepages(testX, testY,false); myblackboard.changepages(tempX, tempY, false, Color, PenSize, APP.PageContextData.currpage - 1, Pressure); #region 设置滚动条位置 //点在显示页面上方 if (tempY < ScroMain.VerticalOffset) { //滚动条当前位置 double RollCurrentLocation = ScroMain.VerticalOffset; //向上滚动至以点为中心需要滚动的距离 double UpRoll = (RollCurrentLocation - tempY) + (ScroMain.ActualHeight / 2); //如果小于0则等于0 double RollLocation = RollCurrentLocation - UpRoll; if (RollLocation < 0) { RollLocation = 0; } ////滚动条实际偏移量 //double RollOffset = RollCurrentLocation - RollLocation; ScroMain.ScrollToVerticalOffset(RollLocation); } //点在显示页面下方 if (tempY > ScroMain.VerticalOffset + ScroMain.ActualHeight) { //滚动条当前位置 double RollCurrentLocation = ScroMain.VerticalOffset; //向下滚动至以点为中心需要滚动的距离 double DownRoll = (tempY - RollCurrentLocation) - (ScroMain.ActualHeight / 2); //如果小于0则等于0 double RollLocation = RollCurrentLocation + DownRoll; //滚动条最大滚动值 double ScrollbarMaxNum = GridM.ActualHeight - ScroMain.ActualHeight; if (RollLocation > ScrollbarMaxNum) { RollLocation = ScrollbarMaxNum; } ////滚动条实际偏移量 //double RollOffset = RollLocation-RollCurrentLocation; ScroMain.ScrollToVerticalOffset(RollLocation); } #endregion 设置滚动条位置 if (tempX > 0 && tempY > 0) { //System.Windows.Point getP = blackboard_canvas.PointToScreen(new System.Windows.Point(testX, testY)); System.Windows.Point getP = ScroMain.PointToScreen(new System.Windows.Point(tempX, tempY - ScroMain.VerticalOffset)); SetCursorPos((int)getP.X, (int)getP.Y); } })); } } } /// /// 清空笔内存储 /// public void ClearPenStorage() { if (!string.IsNullOrEmpty(penSerial)) { APP.digitalPen.ClearMemory(penSerial); } } /// /// 获取剩余电量 /// public void GetPenElectricityQuantity() { if (!string.IsNullOrEmpty(penSerial)) { APP.digitalPen.GetBatteryCapacity(penSerial); } } /// /// 获取存储空间 /// public void GetUsedStorage() { if (!string.IsNullOrEmpty(penSerial)) { APP.digitalPen.GetMemoryFillLevel(penSerial); } } /// /// 开启悬浮 /// public void 开启悬浮() { if (!string.IsNullOrEmpty(penSerial)) { APP.digitalPen.SetPenHoverMode(true, penSerial); } } /// /// 关闭悬浮 /// public void 关闭悬浮() { if (!string.IsNullOrEmpty(penSerial)) { APP.digitalPen.SetPenHoverMode(false, penSerial); } } /// /// 引用user32.dll动态链接库(windows api), 使用库中定义 API:SetCursorPos 设置光标位置 /// [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int SetCursorPos(int x, int y); #endregion 拓思德点阵笔 ```