/// <summary> /// Returns a 3-element array describing the tablet's rotation range and resolution capabilities /// </summary> /// <returns></returns> public static WintabAxisArray GetDeviceRotation(out bool rotationSupported_O) { WintabAxisArray axisArray = new WintabAxisArray(); rotationSupported_O = false; IntPtr buf = CMemUtils.AllocUnmanagedBuf(axisArray); try { int size = (int)CWintabFuncs.WTInfoA( (uint)EWTICategoryIndex.WTI_DEVICES, (uint)EWTIDevicesIndex.DVC_ROTATION, buf); // If size == 0, then returns a zeroed struct. axisArray = CMemUtils.MarshalUnmanagedBuf <WintabAxisArray>(buf, size); rotationSupported_O = (axisArray.array[0].axResolution != 0 && axisArray.array[1].axResolution != 0); } catch (Exception ex) { MessageBox.Show("FAILED GetDeviceRotation: " + ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(axisArray); }
/// <summary> /// Returns a list of indecies of previous or currently attached devices. /// It is up to the caller to use the list to determine which devices are /// actually physically device by responding to data events for those devices. /// Devices that are not physically attached will, of course, never send /// a data event. /// </summary> /// <returns></returns> public static List <Byte> GetFoundDevicesIndexList() { List <Byte> list = new List <Byte>(); try { WintabLogContext ctx = new WintabLogContext(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(ctx); for (Int32 idx = 0; idx < MAX_NUM_ATTACHED_TABLETS; idx++) { int size = (int)CWintabFuncs.WTInfoA( (UInt32)(EWTICategoryIndex.WTI_DDCTXS + idx), 0, buf); if (size == 0) { break; } else { list.Add((Byte)idx); } } CMemUtils.FreeUnmanagedBuf(buf); } catch (Exception ex) { MessageBox.Show("FAILED GetNumberOfConfiguredDevices: " + ex.ToString()); } return(list); }
/// <summary> /// Return the extension mask for the given tag. /// </summary> /// <param name="tag_I">type of extension being searched for</param> /// <returns>0xFFFFFFFF on error</returns> public static UInt32 GetWTExtensionMask(EWTXExtensionTag tag_I) { UInt32 extMask = 0; IntPtr buf = CMemUtils.AllocUnmanagedBuf(extMask); try { UInt32 extIndex = FindWTExtensionIndex(tag_I); // Supported if extIndex != -1 if (extIndex != 0xFFFFFFFF) { int size = (int)CWintabFuncs.WTInfoA( (uint)EWTICategoryIndex.WTI_EXTENSIONS + (uint)extIndex, (uint)EWTIExtensionIndex.EXT_MASK, buf); extMask = (UInt32)CMemUtils.MarshalUnmanagedBuf <UInt32>(buf, size); } } catch (Exception ex) { MessageBox.Show("FAILED GetWTExtensionMask: " + ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(extMask); }
/// <summary> /// Returns extension index tag for given tag, if possible. /// </summary> /// <param name="tag_I">type of extension being searched for</param> /// <returns>0xFFFFFFFF on error</returns> public static UInt32 FindWTExtensionIndex(EWTXExtensionTag tag_I) { UInt32 thisTag = 0; UInt32 extIndex = 0xFFFFFFFF; IntPtr buf = CMemUtils.AllocUnmanagedBuf(thisTag); for (Int32 loopIdx = 0, size = -1; size != 0; loopIdx++) { size = (int)CWintabFuncs.WTInfoA( (uint)EWTICategoryIndex.WTI_EXTENSIONS + (UInt32)loopIdx, (uint)EWTIExtensionIndex.EXT_TAG, buf); if (size > 0) { thisTag = CMemUtils.MarshalUnmanagedBuf <UInt32>(buf, size); if ((EWTXExtensionTag)thisTag == tag_I) { extIndex = (UInt32)loopIdx; break; } } } CMemUtils.FreeUnmanagedBuf(buf); return(extIndex); }
/// <summary> /// Return max normal pressure supported by tablet. /// </summary> /// <param name="getNormalPressure_I">TRUE=> normal pressure; /// FALSE=> tangential pressure (not supported on all tablets)</param> /// <returns>maximum pressure value or zero on error</returns> public static Int32 GetMaxPressure(bool getNormalPressure_I = true) { WintabAxis pressureAxis = new WintabAxis(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(pressureAxis); EWTIDevicesIndex devIdx = (getNormalPressure_I ? EWTIDevicesIndex.DVC_NPRESSURE : EWTIDevicesIndex.DVC_TPRESSURE); try { int size = (int)CWintabFuncs.WTInfoA( (uint)EWTICategoryIndex.WTI_DEVICES, (uint)devIdx, buf); pressureAxis = CMemUtils.MarshalUnmanagedBuf <WintabAxis>(buf, size); } catch (Exception ex) { MessageBox.Show("FAILED GetMaxPressure: " + ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(pressureAxis.axMax); }
/// <summary> /// Returns a string containing the name of the selected stylus. /// </summary> /// <param name="index_I">indicates stylus type</param> /// <returns></returns> public static string GetStylusName(EWTICursorNameIndex index_I) { string stylusName = null; IntPtr buf = CMemUtils.AllocUnmanagedBuf(MAX_STRING_SIZE); try { int size = (int)CWintabFuncs.WTInfoA( (uint)index_I, (uint)EWTICursorsIndex.CSR_NAME, buf); if (size < 1) { throw new Exception("GetStylusName returned empty string."); } // Strip off final null character before marshalling. stylusName = CMemUtils.MarshalUnmanagedString(buf, size - 1); } catch (Exception ex) { MessageBox.Show("FAILED GetDeviceInfo: " + ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(stylusName); }
/// <summary> /// Returns one packet of Wintab data from the packet queue. /// </summary> /// <param name="hCtx_I">Wintab context to be used when asking for the data</param> /// <param name="pktID_I">Identifier for the tablet event packet to return.</param> /// <returns>Returns a data packet with non-null context if successful.</returns> public WintabPacket GetDataPacket(HCTX hCtx_I, UInt32 pktID_I) { IntPtr buf = CMemUtils.AllocUnmanagedBuf(Marshal.SizeOf(typeof(WintabPacket))); WintabPacket packet = new WintabPacket(); if (pktID_I == 0) { throw new Exception("GetDataPacket - invalid pktID"); } CheckForValidHCTX("GetDataPacket"); if (CWintabFuncs.WTPacket(hCtx_I, pktID_I, buf)) { packet = (WintabPacket)Marshal.PtrToStructure(buf, typeof(WintabPacket)); } else { // // If fails, make sure context is zero. // packet.pkContext = HCTX.Zero; } CMemUtils.FreeUnmanagedBuf(buf); return(packet); }
/// <summary> /// Returns a string containing device name. /// </summary> /// <returns></returns> public static String GetDeviceInfo() { string devInfo = null; IntPtr buf = CMemUtils.AllocUnmanagedBuf(MAX_STRING_SIZE); try { int size = (int)CWintabFuncs.WTInfoA( (uint)EWTICategoryIndex.WTI_DEVICES, (uint)EWTIDevicesIndex.DVC_NAME, buf); if (size < 1) { throw new Exception("GetDeviceInfo returned empty string."); } // Strip off final null character before marshalling. devInfo = CMemUtils.MarshalUnmanagedString(buf, size - 1); } catch (Exception ex) { MessageBox.Show("FAILED GetDeviceInfo: " + ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(devInfo); }
/// <summary> /// Returns one packet of Wintab data from the packet queue. /// </summary> /// <param name="hCtx_I">Wintab context to be used when asking for the data</param> /// <param name="pktID_I">Identifier for the tablet event packet to return.</param> /// <returns>Returns a data packet with non-null context if successful.</returns> public WintabPacket GetDataPacket(UInt32 hCtx_I, UInt32 pktID_I) { IntPtr buf = CMemUtils.AllocUnmanagedBuf(Marshal.SizeOf(typeof(WintabPacket))); WintabPacket packet = new WintabPacket(); if (pktID_I == 0) { throw new Exception("GetDataPacket - invalid pktID"); } CheckForValidHCTX("GetDataPacket"); if (CWintabFuncs.WTPacket(hCtx_I, pktID_I, buf)) { packet = (WintabPacket)Marshal.PtrToStructure(buf, typeof(WintabPacket)); } else { // // If fails, make sure context is zero. // packet.pkContext = 0; } /** * PERFORMANCE FIX: without this line, the memory consume of .NET apps increase * exponentially when the PEN is used for long time (or worse when the pen is leaved alone on the tablet screen) * causing the app to crash now or later... * Author: Alessandro del Gobbo ([email protected]) */ CMemUtils.FreeUnmanagedBuf(buf); return(packet); }
/// <summary> /// Returns a string containing the name of the selected stylus. /// </summary> /// <param name="index_I">indicates stylus type</param> /// <returns></returns> public static string GetStylusName(EWTICursorNameIndex index_I) { string stylusName = null; IntPtr buf = CMemUtils.AllocUnmanagedBuf(MAX_STRING_SIZE); try { int size = (int)CWintabFuncs.WTInfo( (uint)index_I, (uint)EWTICursorsIndex.CSR_NAME, buf); if (size < 1) { throw new Exception("GetStylusName returned empty string."); } // Strip off final null character before marshalling. stylusName = CMemUtils.MarshalUnmanagedString(buf, size - 2); } finally { CMemUtils.FreeUnmanagedBuf(buf); } return(stylusName); }
/// <summary> /// Return the number of tablets that have at some time been attached. /// A record of these devices is in the tablet settings. Since there /// is no direct query for this value, we have to enumerate all of /// the tablet settings. /// </summary> /// <returns>tablet count</returns> public static UInt32 GetNumberOfConfiguredDevices() { UInt32 numConfiguredTablets = 0; try { WintabLogContext ctx = new WintabLogContext(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(ctx); for (Int32 idx = 0; idx < MAX_NUM_ATTACHED_TABLETS; idx++) { int size = (int)CWintabFuncs.WTInfoA( (UInt32)(EWTICategoryIndex.WTI_DDCTXS + idx), 0, buf); if (size == 0) { break; } else { numConfiguredTablets++; } } CMemUtils.FreeUnmanagedBuf(buf); } catch (Exception ex) { MessageBox.Show("FAILED GetNumberOfConfiguredDevices: " + ex.ToString()); } return(numConfiguredTablets); }
/// <summary> /// Return the extension mask for the given tag. /// </summary> /// <param name="tag_I">type of extension being searched for</param> /// <returns>0xFFFFFFFF on error</returns> public static UInt32 GetWTExtensionMask(EWTXExtensionTag tag_I) { UInt32 extMask = 0; IntPtr buf = CMemUtils.AllocUnmanagedBuf(extMask); try { UInt32 extIndex = FindWTExtensionIndex(tag_I); // Supported if extIndex != -1 if (extIndex != 0xFFFFFFFF) { int size = (int)CWintabFuncs.WTInfo( (uint)EWTICategoryIndex.WTI_EXTENSIONS + (uint)extIndex, (uint)EWTIExtensionIndex.EXT_MASK, buf); extMask = (UInt32)CMemUtils.MarshalUnmanagedBuf <UInt32>(buf, size); } } finally { CMemUtils.FreeUnmanagedBuf(buf); } return(extMask); }
/// <summary> /// Get packet queue size for this data object's context. /// </summary> /// <returns>Returns a packet queue size in #packets or 0 if fails</returns> public UInt32 GetPacketQueueSize() { UInt32 numPkts = 0; CheckForValidHCTX("GetPacketQueueSize"); numPkts = CWintabFuncs.WTQueueSizeGet(m_context.HCtx); return(numPkts); }
/// <summary> /// Set packet queue size for this data object's context. /// </summary> /// <param name="numPkts_I">desired #packets in queue</param> /// <returns>Returns true if operation successful</returns> public bool SetPacketQueueSize(UInt32 numPkts_I) { bool status = false; CheckForValidHCTX("SetPacketQueueSize"); status = CWintabFuncs.WTQueueSizeSet(m_context.HCtx, numPkts_I); return(status); }
/// <summary> /// Returns TRUE if Wintab service is running and responsive. /// </summary> /// <returns></returns> public static bool IsWintabAvailable() { IntPtr buf = IntPtr.Zero; bool status = false; status = (CWintabFuncs.WTInfo(0, 0, buf) > 0); return(status); }
/// <summary> /// Sets an extension control property image (if supported by tablet). /// </summary> /// <param name="context_I">wintab context</param> /// <param name="extTagIndex_I">which extension tag we're setting</param> /// <param name="tabletIndex_I">index of the tablet being set</param> /// <param name="controlIndex_I">the index of the control being set</param> /// <param name="functionIndex_I">the index of the control function being set</param> /// <param name="propertyID_I">ID of the property being set</param> /// <param name="value_I">value of the property being set (a string)</param> /// <returns>true if successful</returns> public static bool ControlPropertySetImage( HCTX context_I, byte extTagIndex_I, byte tabletIndex_I, byte controlIndex_I, byte functionIndex_I, ushort propertyID_I, String imageFilePath_I ) { bool retStatus = false; WTExtensionImageProperty extProperty = new WTExtensionImageProperty(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(extProperty); try { byte[] imageBytes = null; System.Drawing.Image newImage = Image.FromFile(imageFilePath_I); if (newImage == null) { MessageBox.Show("Oops - couldn't find/read image: " + imageFilePath_I); return(false); } using (MemoryStream ms = new MemoryStream()) { newImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png); imageBytes = ms.ToArray(); } extProperty.extBase.version = 0; extProperty.extBase.tabletIndex = tabletIndex_I; extProperty.extBase.controlIndex = controlIndex_I; extProperty.extBase.functionIndex = functionIndex_I; extProperty.extBase.propertyID = propertyID_I; extProperty.extBase.reserved = 0; extProperty.extBase.dataSize = (uint)imageBytes.Length; extProperty.data = new byte[WTExtensionsGlobal.WTExtensionPropertyImageMaxDataBytes]; // Send image as an array of bytes. System.Buffer.BlockCopy(imageBytes, 0, extProperty.data, 0, (int)extProperty.extBase.dataSize); Marshal.StructureToPtr(extProperty, buf, false); retStatus = CWintabFuncs.WTExtSet((UInt32)context_I, (UInt32)extTagIndex_I, buf); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(retStatus); }
/// <summary> /// Open a Wintab context that will send packet events to a message window. /// </summary> /// <returns>Returns true if successful.</returns> public bool Open() { // Get the handle of the anonymous MessageEvents window. This is a // static (global) object, so there's only one of these at a time. HWND hwnd = MessageEvents.WindowHandle; m_hCTX = CWintabFuncs.WTOpen(hwnd, ref m_logContext, true); return(m_hCTX.IsValid); }
/// <summary> /// Removes all pending data packets from the context's queue. /// </summary> public void FlushDataPackets(uint numPacketsToFlush_I) { try { CheckForValidHCTX("FlushDataPackets"); CWintabFuncs.WTPacketsGet(m_context.HCtx, numPacketsToFlush_I, IntPtr.Zero); } catch (Exception ex) { MessageBox.Show("FAILED GetPacketDataRange: " + ex.ToString()); } }
public void BringToFront() { try { CheckForValidHCTX("BringToFront"); CWintabFuncs.WTOverlap(m_context.HCtx, true); } catch (Exception ex) { MessageBox.Show("FAILED BringToFront: " + ex.ToString()); } }
/// <summary> /// Enable/disable this Wintab context. /// </summary> /// <param name="enable_I">true = enable</param> /// <returns>Returns true if completed successfully</returns> public bool Enable(bool enable_I) { bool status = false; if (!m_hCTX.IsValid) { throw new Exception("EnableContext: invalid context"); } status = CWintabFuncs.WTEnable(m_hCTX, enable_I); return(status); }
/// <summary> /// Sends a tablet context to the top or bottom of the order of overlapping tablet contexts /// </summary> /// <param name="toTop_I">true = send tablet to top of order</param> /// <returns>Returns true if successsful</returns> public bool SetOverlapOrder(bool toTop_I) { bool status = false; if (!m_hCTX.IsValid) { throw new Exception("EnableContext: invalid context"); } status = CWintabFuncs.WTOverlap(m_hCTX, toTop_I); return(status); }
/// <summary> /// Open a Wintab context to the specified hwnd. /// </summary> /// <param name="hwnd_I">parent window for the context</param> /// <param name="enable_I">true to enable, false to disable</param> /// <returns>Returns non-zero context handle if successful.</returns> public HCTX Open(HWND hwnd_I, bool enable_I) { try { m_hCTX = CWintabFuncs.WTOpenA(hwnd_I, ref m_logContext, enable_I); } catch (Exception ex) { MessageBox.Show("FAILED OpenContext: " + ex.ToString()); } return(m_hCTX); }
/// <summary> /// Close the context for this object. /// </summary> /// <returns>true if context successfully closed</returns> public bool Close() { bool status = false; if (!m_hCTX.IsValid) { throw new Exception("CloseContext: invalid context"); } status = CWintabFuncs.WTClose(m_hCTX); m_hCTX = HCTX.Zero; m_logContext = new WintabLogContext(); return(status); }
/// <summary> /// Get packet queue size for this data object's context. /// </summary> /// <returns>Returns a packet queue size in #packets or 0 if fails</returns> public UInt32 GetPacketQueueSize() { UInt32 numPkts = 0; try { CheckForValidHCTX("GetPacketQueueSize"); numPkts = CWintabFuncs.WTQueueSizeGet(m_context.HCtx); } catch (Exception ex) { MessageBox.Show("FAILED GetPacketQueueSize: " + ex.ToString()); } return(numPkts); }
/// <summary> /// Set packet queue size for this data object's context. /// </summary> /// <param name="numPkts_I">desired #packets in queue</param> /// <returns>Returns true if operation successful</returns> public bool SetPacketQueueSize(UInt32 numPkts_I) { bool status = false; try { CheckForValidHCTX("SetPacketQueueSize"); status = CWintabFuncs.WTQueueSizeSet(m_context.HCtx, numPkts_I); } catch (Exception ex) { MessageBox.Show("FAILED SetPacketQueueSize: " + ex.ToString()); } return(status); }
/// <summary> /// Returns TRUE if Wintab service is running and responsive. /// </summary> /// <returns></returns> public static bool IsWintabAvailable() { IntPtr buf = IntPtr.Zero; bool status = false; try { status = (CWintabFuncs.WTInfoA(0, 0, buf) > 0); } catch (Exception ex) { MessageBox.Show("FAILED IsWintabAvailable: " + ex.ToString()); } return(status); }
/// <summary> /// Open a Wintab context that will send packet events to a message window. /// </summary> /// <returns>Returns true if successful.</returns> public bool Open() { // Get the handle of the anonymous MessageEvents window. This is a // static (global) object, so there's only one of these at a time. HWND hwnd = MessageEvents.WindowHandle; try { m_hCTX = CWintabFuncs.WTOpenA(hwnd, ref m_logContext, true); } catch (Exception ex) { MessageBox.Show("FAILED OpenContext: " + ex.ToString()); } return(m_hCTX > 0); }
/// <summary> /// Helper function to get digitizing or system default context. /// </summary> /// <param name="contextType_I">Use WTI_DEFCONTEXT for digital context or WTI_DEFSYSCTX for system context</param> /// <returns>Returns the default context or null on error.</returns> private static CWintabContext GetDefaultContext(EWTICategoryIndex contextIndex_I) { CWintabContext context = new CWintabContext(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(context.LogContext); try { int size = (int)CWintabFuncs.WTInfo((uint)contextIndex_I, 0, buf); context.LogContext = CMemUtils.MarshalUnmanagedBuf <WintabLogContext>(buf, size); } finally { CMemUtils.FreeUnmanagedBuf(buf); } return(context); }
/// <summary> /// Get a property value from an extension. /// </summary> /// <param name="context_I">Wintab context</param> /// <param name="extTagIndex_I">extension index tag</param> /// <param name="tabletIndex_I">tablet index</param> /// <param name="controlIndex_I">control index on the tablet</param> /// <param name="functionIndex_I">function index on the control</param> /// <param name="propertyID_I">ID of the property requested</param> /// <param name="result_O">value of the property requested</param> /// <returns>true if property obtained</returns> public static bool ControlPropertyGet( HCTX context_I, byte extTagIndex_I, byte tabletIndex_I, byte controlIndex_I, byte functionIndex_I, ushort propertyID_I, ref UInt32 result_O ) { bool retStatus = false; WTExtensionProperty extProperty = new WTExtensionProperty(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(extProperty); extProperty.extBase.version = 0; extProperty.extBase.tabletIndex = tabletIndex_I; extProperty.extBase.controlIndex = controlIndex_I; extProperty.extBase.functionIndex = functionIndex_I; extProperty.extBase.propertyID = propertyID_I; extProperty.extBase.reserved = 0; extProperty.extBase.dataSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(result_O); Marshal.StructureToPtr(extProperty, buf, false); try { bool status = CWintabFuncs.WTExtGet((UInt32)context_I, (UInt32)extTagIndex_I, buf); if (status) { WTExtensionProperty retProp = (WTExtensionProperty)Marshal.PtrToStructure(buf, typeof(WTExtensionProperty)); result_O = retProp.data[0]; retStatus = true; } } catch (Exception ex) { MessageBox.Show("FAILED ControlPropertyGet: " + ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(retStatus); }
/// <summary> /// Sets an extension control property string. /// </summary> /// <param name="context_I">wintab context</param> /// <param name="extTagIndex_I">which extension tag we're setting</param> /// <param name="tabletIndex_I">index of the tablet being set</param> /// <param name="controlIndex_I">the index of the control being set</param> /// <param name="functionIndex_I">the index of the control function being set</param> /// <param name="propertyID_I">ID of the property being set</param> /// <param name="value_I">value of the property being set (a string)</param> /// <returns>true if successful</returns> public static bool ControlPropertySet( HCTX context_I, byte extTagIndex_I, byte tabletIndex_I, byte controlIndex_I, byte functionIndex_I, ushort propertyID_I, String value_I ) { bool retStatus = false; WTExtensionProperty extProperty = new WTExtensionProperty(); IntPtr buf = CMemUtils.AllocUnmanagedBuf(extProperty); try { // Convert unicode string value_I to UTF8-encoded bytes byte[] utf8Bytes = System.Text.Encoding.Convert(Encoding.Unicode, Encoding.UTF8, Encoding.Unicode.GetBytes(value_I)); extProperty.extBase.version = 0; extProperty.extBase.tabletIndex = tabletIndex_I; extProperty.extBase.controlIndex = controlIndex_I; extProperty.extBase.functionIndex = functionIndex_I; extProperty.extBase.propertyID = propertyID_I; extProperty.extBase.reserved = 0; extProperty.extBase.dataSize = (uint)utf8Bytes.Length; extProperty.data = new byte[WTExtensionsGlobal.WTExtensionPropertyMaxDataBytes]; // Send input value as an array of UTF8-encoded bytes. System.Buffer.BlockCopy(utf8Bytes, 0, extProperty.data, 0, (int)extProperty.extBase.dataSize); Marshal.StructureToPtr(extProperty, buf, false); retStatus = CWintabFuncs.WTExtSet((UInt32)context_I, (UInt32)extTagIndex_I, buf); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } CMemUtils.FreeUnmanagedBuf(buf); return(retStatus); }