Using the Managed Library
Using the Managed Library |
This topic contains notes on using the Tablet PC platform Managed Library.
Binding to the Latest Microsoft.Ink.dll
The latest Microsoft.Ink.dll is a compatible replacement for Microsoft.Ink.dll version 1.0 and Microsoft.Ink.15.dll. However, you need to instruct the common language runtime loader to use the newer dynamic-link library (DLL) wherever the older DLLs have been referenced. There are two ways to do this:
Publisher Policy. This is a type of config file that is wrapped in an assembly and installed in the global assembly cache (GAC). You would name it
Policy.Microsoft.Ink.dll
and sign it with the same strong name asMicrosoft.Ink.dll
. Publisher policy affects all applications on the machine, so the side effect is that all applications that were successfully running with version 1.0 or 1.5 would now start using the new DLL.Application Policy. Add a bindingRedirect element to the app.config or web.config file. See the bindingRedirect element for how to construct this XML. Typically, you would use the following XML to force all prior versions to be mapped to the latest version:
<bindingRedirect oldVersion="0.0.0.0-1.7.2600.xxxx" newVersion="1.7.2600.xxxx" />
For more information see How the Runtime Locates Assemblies and Application Configuration Files Explained .
Object Comparison
For all objects in the Tablet PC Platform Managed library, Object.Equals is not overridden to correctly compare two objects that are the same. The managed API does not support the comparison of objects for equality, either through the Equals function or through the equals (==) operator.
Working with Events
If the code within an event handler for any of the managed objects throws an exception, the exception is not delivered to the user. To ensure that exceptions are delivered, use try-catch blocks in your event handlers for managed events.
To avoid a memory leak you must explicitly call the Dispose method on any Tablet PC object or control to which an event handler has been attached before the object or control goes out of scope.
Managing Forms
The System.Windows.Forms.Form class and its base classes do not define a finalizer. To clean up your resources on a form, write a subclass that provides a finalizer (for example, the C# destructor using the ~) that calls Dispose(false) . To do the cleanup the finalizer overrides Dispose(bool) and then calls the base class Dispose(bool) . Do not refer to other objects that require the Finalize method in your Dispose method when the Boolean parameter is False because they may already have been finalized. For more information about releasing resources see Finalize Methods and Destructors .
Forms and the RecognizerContext
RecognizerContext events run in a different thread than the thread that the form is on. Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, you must use one of the control's invoke methods to marshal the call to the proper thread. Four methods on a control are thread safe: the Invoke , BeginInvoke , EndInvoke and CreateGraphics methods. For all other method calls, use one of these invoke methods when calling from a different thread.
Waiting for Events
The Tablet PC environment is multithreaded. Use the CoWaitForMultipleHandles function instead of other wait methods to allow re-entrant COM calls to enter your multithreaded apartment (MTA) while your application is waiting on an event.
Disposing Managed Objects and Controls
To avoid a memory leak you must explicitly call the Dispose method on any Tablet PC object or control to which an event handler has been attached before the object or control goes out of scope.
To improve the performance of your application, manually dispose of the following objects, controls, and collection when they are no longer needed.
- Divider object
- Ink object
- InkCollector object
- InkEdit control
- InkOverlay object
- InkPicture control
- PenInputPanel object
- RecognizerContext object
- Strokes collection
The following C# example demonstrates some scenarios in which the Dispose method is used.
// A field for a Divider object
private Microsoft.Ink.Divider theDivider;
// A method that creates a Divider object
public void CreateDivider()
{
// Make sure any previous Divider object was disposed of.
if (null != theDivider)
{
theDivider.Dispose();
theDivider = null;
}
// Create the Divider object.
theDivider = new Microsoft.Ink.Divider();
// The remainder of the method
}
// A method that disposes of the Divider object
public void DisposeDivider()
{
// The remainder of the method
// Dispose of the Divider object.
if (null != theDivider)
{
theDivider.Dispose();
theDivider = null;
}
}
// A method that uses a local PenInputPanel object.
public void UsePenInputPanel()
{
// Create the PenInputPanel object.
Microsoft.Ink.PenInputPanel thePenInputPanel =
new Microsoft.Ink.PenInputPanel();
// The remainder of the method
// Dispose of the PenInputPanel object before exiting.
thePenInputPanel.Dispose();
thePenInputPanel = null;
}