Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Input / Stylus / PenContexts.cs / 1305600 / PenContexts.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Security ;
using MS.Internal ;
using MS.Win32;
using MS.Utility;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.Internal;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Interop;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
using MS.Internal.PresentationCore; // SecurityHelper
namespace System.Windows.Input
{
/////////////////////////////////////////////////////////////////////////
internal sealed class PenContexts
{
/////////////////////////////////////////////////////////////////////////
///
/// Critical - InputManager ctor is critical, ergo this is critical data.
/// Called by Stylus.RegisterHwndForInput.
/// TreatAsSafe boundary is Stylus.RegisterHwndForInput called when a window is created.
///
[SecurityCritical]
internal PenContexts(StylusLogic stylusLogic, PresentationSource inputSource)
{
HwndSource hwndSource = inputSource as HwndSource;
if(hwndSource == null || IntPtr.Zero == (hwndSource).CriticalHandle)
{
throw new InvalidOperationException(SR.Get(SRID.Stylus_PenContextFailure));
}
_stylusLogic = stylusLogic;
_inputSource = new SecurityCriticalData(hwndSource);
}
/////////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code (TabletDevices.CreateContexts and PenContext.Enable) and accesses
/// SecurityCritical data (_inputSource.Value and _contexts).
/// Called by Stylus.EnableCore, Stylus.RegisterHwndForInput, Stylus.OnScreenMeasurementsChanged.
/// TreatAsSafe boundry is Stylus.EnableCore, Stylus.RegisterHwndForInput
/// and HwndWrapperHook class (via HwndSource.InputFilterMessage when
/// a WM_DISPLAYCHANGE is processed by HwndStylusInputProvider).
///
[SecurityCritical]
internal void Enable()
{
if (_contexts == null)
{
// create contexts
_contexts = _stylusLogic.TabletDevices.CreateContexts(_inputSource.Value.CriticalHandle, this);
foreach(PenContext context in _contexts)
{
context.Enable();
}
}
}
///
/// Critical - Accesses SecurityCritical data (_contexts).
/// Called by Stylus.UnregisterHwndForInput and Dispose.
/// TreatAsSafe boundry is Stylus.UnregisterHwndForInput
/// and HwndStylusInputProvider.Dispose(bool).
///
[SecurityCritical]
internal void Disable(bool shutdownWorkerThread)
{
if (_contexts != null)
{
foreach(PenContext context in _contexts)
{
context.Disable(shutdownWorkerThread);
}
_contexts = null; // release refs on PenContext objects
}
}
internal bool IsWindowDisabled
{
get { return _isWindowDisabled; }
set { _isWindowDisabled = value; }
}
internal Point DestroyedLocation
{
get { return _destroyedLocation; }
set { _destroyedLocation = value; }
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenDown.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenDown(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.Down, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenUp.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenUp(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.Up, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePackets.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPackets(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.Move, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePackets.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnInAirPackets(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.InAirMove, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenInRange.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenInRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.InRange, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenOutOfRange.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenOutOfRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int timestamp)
{
ProcessInput(RawStylusActions.OutOfRange, penContext, tabletDeviceId, stylusPointerId, new int[]{}, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical: Uses critical data _inputSource and calls SecurityCritical code
/// StylusLogic.ProcessSystemEvent.
/// Called by PenContext.FireSystemGesture.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnSystemEvent(PenContext penContext,
int tabletDeviceId,
int stylusPointerId,
int timestamp,
SystemGesture id,
int gestureX,
int gestureY,
int buttonState)
{
_stylusLogic.ProcessSystemEvent(penContext,
tabletDeviceId,
stylusPointerId,
timestamp,
id,
gestureX,
gestureY,
buttonState,
_inputSource.Value);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical: Uses critical data _inputSource and calls SecurityCritical
/// code StylusLogic.ProcessInput.
/// Called by OnPenDown, OnPenUp, OnPackets, OnInAirPackets, OnPenInRange and OnPenOutOfRange.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
void ProcessInput(
RawStylusActions actions,
PenContext penContext,
int tabletDeviceId,
int stylusPointerId,
int[] data, int timestamp)
{
// (all events but SystemEvent go thru here)
_stylusLogic.ProcessInput(
actions,
penContext,
tabletDeviceId,
stylusPointerId,
data,
timestamp,
_inputSource.Value);
}
/////////////////////////////////////////////////////////////////////////
///
/// Critical since it accesses SecurityCritical data _contexts and
/// returns SecurityCritical data PenContext.
///
[SecurityCritical]
internal PenContext GetTabletDeviceIDPenContext(int tabletDeviceId)
{
if (_contexts != null)
{
for (int i = 0; i < _contexts.Length; i++)
{
PenContext context = _contexts[i];
if (context.TabletDeviceId == tabletDeviceId)
return context;
}
}
return null;
}
/////////////////////////////////////////////////////////////////////////
///
/// Critical since it accesses SecurityCritical data _contexts.
///
[SecurityCritical]
internal bool ConsiderInRange(int timestamp)
{
if (_contexts != null)
{
for (int i = 0; i < _contexts.Length; i++)
{
PenContext context = _contexts[i];
// We consider it InRange if we have a queued up context event or
// the timestamp - LastInRangeTime <= 500 (seen one in the last 500ms)
// Here's some info on how this works...
// int.MaxValue - int.MinValue = -1 (subtracting any negative # from MaxValue keeps this negative)
// int.MinValue - int.MaxValue = 1 (subtracting any positive # from MinValue keeps this positive)
// So subtracting wrapping values will return proper sign depending on which was earlier.
// We do have the assumption that these values will be relative close in time. If the
// time wraps we'll say yet but the only harm is that we may defer a mouse move event temporarily
// which won't cause any harm.
if (context.QueuedInRangeCount > 0 || (Math.Abs(unchecked(timestamp - context.LastInRangeTime)) <= 500))
return true;
}
}
return false;
}
/////////////////////////////////////////////////////////////////////
///
/// This method adds the specified pen context index in response
/// to the WM_TABLET_ADDED notification
///
///
/// Critical - Calls SecurityCritical code (Disable and TabletDevice.CreateContext)
/// and accesses SecurityCritical data (_contexts).
/// Called by Stylus.OnTabletAdded.
/// TreatAsSafe boundary is HwndWrapperHook class (via HwndSource.InputFilterMessage).
///
[SecurityCritical]
internal void AddContext(uint index)
{
// We only tear down the old context when PenContexts are enabled without being
// dispose and we have a valid index. Otherwise, no-op here.
if (_contexts != null && index <= _contexts.Length && _inputSource.Value.CriticalHandle != IntPtr.Zero)
{
PenContext[] ctxs = new PenContext[_contexts.Length + 1];
uint preCopyCount = index;
uint postCopyCount = (uint)_contexts.Length - index;
Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
PenContext newContext = _stylusLogic.TabletDevices[(int)index].CreateContext(_inputSource.Value.CriticalHandle, this);
ctxs[index] = newContext;
Array.Copy(_contexts, index, ctxs, index+1, postCopyCount);
_contexts = ctxs;
newContext.Enable();
}
}
/////////////////////////////////////////////////////////////////////
///
/// This method removes the specified pen context index in response
/// to the WM_TABLET_REMOVED notification
///
///
/// Critical - Calls SecurityCritical code (Disable and PenContext constructor) and
/// accesses SecurityCritical data (_contexts).
/// Called by Stylus.OnTabletRemoved.
/// TreatAsSafe boundary is HwndWrapperHook class (via HwndSource.InputFilterMessage).
///
[SecurityCritical]
internal void RemoveContext(uint index)
{
// We only tear down the old context when PenContexts are enabled without being
// dispose and we have a valid index. Otherwise, no-op here.
if (_contexts != null && index < _contexts.Length)
{
PenContext removeCtx = _contexts[index];
PenContext[] ctxs = new PenContext[_contexts.Length - 1];
uint preCopyCount = index;
uint postCopyCount = (uint)_contexts.Length - index - 1;
Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
Array.Copy(_contexts, index+1, ctxs, index, postCopyCount);
removeCtx.Disable(false); // shut down this context.
_contexts = ctxs;
}
}
/////////////////////////////////////////////////////////////////////
internal object SyncRoot
{
get
{
return __rtiLock;
}
}
internal void AddStylusPlugInCollection(StylusPlugInCollection pic)
{
// must be called from inside of lock(__rtiLock)
// insert in ZOrder
_plugInCollectionList.Insert(FindZOrderIndex(pic), pic);
}
internal void RemoveStylusPlugInCollection(StylusPlugInCollection pic)
{
// must be called from inside of lock(__rtiLock)
_plugInCollectionList.Remove(pic);
}
internal int FindZOrderIndex(StylusPlugInCollection spicAdding)
{
//should be called inside of lock(__rtiLock)
DependencyObject spicAddingVisual = spicAdding.Element as Visual;
int i;
for (i=0; i < _plugInCollectionList.Count; i++)
{
// first see if parent of node, if it is then we can just scan till we find the
// first non parent and we're done
DependencyObject curV = _plugInCollectionList[i].Element as Visual;
if (VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
{
i++;
while (i < _plugInCollectionList.Count)
{
curV = _plugInCollectionList[i].Element as Visual;
if (!VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
break; // done
i++;
}
return i;
}
else
{
// Look to see if spicAddingVisual is higher in ZOrder than i, if so then we're done
DependencyObject commonParent = VisualTreeHelper.FindCommonAncestor(spicAddingVisual, curV);
// If no common parent found then we must have multiple plugincollection elements
// that have been removed from the visual tree and we haven't been notified yet of
// that change. In this case just ignore this plugincollection element and go to
// the next.
if (commonParent == null)
continue;
// If curV is the commonParent we find then we're done. This new plugin should be
// above this one.
if (curV == commonParent)
return i;
// now find first child for each under that common visual that these fall under (not they must be different or common parent is sort of busted.
while (VisualTreeHelper.GetParentInternal(spicAddingVisual) != commonParent)
spicAddingVisual = VisualTreeHelper.GetParentInternal(spicAddingVisual);
while (VisualTreeHelper.GetParentInternal(curV) != commonParent)
curV = VisualTreeHelper.GetParentInternal(curV);
// now see which is higher in zorder
int count = VisualTreeHelper.GetChildrenCount(commonParent);
for (int j = 0; j < count; j++)
{
DependencyObject child = VisualTreeHelper.GetChild(commonParent, j);
if (child == spicAddingVisual)
return i;
else if (child == curV)
break; // look at next index in _piList.
}
}
}
return i; // this wasn't higher so return last index.
}
///
/// Critical - Calls into security critical code TargetPlugInCollection.
/// Called by StylusLogic.CallPluginsForMouse.
/// TreatAsSafe boundary is mainly PenThread.ThreadProc and HwndWrapperHook class (via HwndSource.InputFilterMessage).
/// It can also be called via anyone with priviledge to call InputManager.ProcessInput().
///
[SecurityCritical]
internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
{
StylusPlugInCollection newPlugInCollection = null;
// lock to make sure only one event is processed at a time and no changes to state can
// be made until we finish routing this event.
lock(__rtiLock)
{
//Debug.Assert(inputReport.Actions == RawStylusActions.Down ||
// inputReport.Actions == RawStylusActions.Up ||
// inputReport.Actions == RawStylusActions.Move);
// Find new target plugin collection
if (directlyOver != null)
{
UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
if (uiElement != null)
{
newPlugInCollection = FindPlugInCollection(uiElement);
}
}
// Fire Leave event to old pluginCollection if we need to.
if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
{
// NOTE: input report points for mouse are in avalon measured units and not device!
RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);
currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);
}
if (newPlugInCollection != null)
{
// NOTE: input report points for mouse are in avalon measured units and not device!
RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
inputReport.RawStylusInput = rawStylusInput;
if (newPlugInCollection != currentPlugInCollection)
{
newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
}
// We are on the pen thread, just call directly.
newPlugInCollection.FireRawStylusInput(rawStylusInput);
// Fire custom data events (always confirmed for mouse)
foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
{
customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
}
}
}
return newPlugInCollection;
}
///
/// Critical - Calls into security critical code TargetPlugInCollection.
/// Called by StylusLogic.InvokeStylusPluginCollection.
/// TreatAsSafe boundary is mainly PenThread.ThreadProc and HwndWrapperHook class (via HwndSource.InputFilterMessage).
/// It can also be called via anyone with priviledge to call InputManager.ProcessInput().
///
[SecurityCritical]
internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
{
// Find PenContexts object for this inputReport.
StylusPlugInCollection pic = null;
// lock to make sure only one event is processed at a time and no changes to state can
// be made until we finish routing this event.
lock(__rtiLock)
{
switch (inputReport.Actions)
{
case RawStylusActions.Down:
case RawStylusActions.Move:
case RawStylusActions.Up:
// Figure out current target plugincollection.
pic = TargetPlugInCollection(inputReport);
break;
default:
return; // Nothing to do unless one of the above events
}
StylusPlugInCollection currentPic = inputReport.StylusDevice.CurrentNonVerifiedTarget;
// Fire Leave event if we need to.
if (currentPic != null && currentPic != pic)
{
// Create new RawStylusInput to send
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(currentPic.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.
RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic);
currentPic.FireEnterLeave(false, tempRawStylusInput, false);
inputReport.StylusDevice.CurrentNonVerifiedTarget = null;
}
if (pic != null)
{
// NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
// The transformTabletToView matrix and plugincollection rects though can change based
// off of layout events which is why we need to lock this.
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(pic.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.
RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic);
inputReport.RawStylusInput = rawStylusInput;
if (pic != currentPic)
{
inputReport.StylusDevice.CurrentNonVerifiedTarget = pic;
pic.FireEnterLeave(true, rawStylusInput, false);
}
// We are on the pen thread, just call directly.
pic.FireRawStylusInput(rawStylusInput);
}
} // lock(__rtiLock)
}
///
/// Critical - InputReport.InputSource has a LinkDemand so we need to be SecurityCritical.
/// Called by InvokeStylusPluginCollection.
/// TreatAsSafe boundary is mainly PenThread.ThreadProc and HwndWrapperHook class (via HwndSource.InputFilterMessage).
/// It can also be called via anyone with priviledge to call InputManager.ProcessInput().
///
[SecurityCritical]
internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
{
// Caller must make call to this routine inside of lock(__rtiLock)!
StylusPlugInCollection pic = null;
// We should only be called when not on the application thread!
System.Diagnostics.Debug.Assert(!inputReport.StylusDevice.CheckAccess());
// We're on the pen thread so can't touch visual tree. Use capturedPlugIn (if capture on) or cached rects.
bool elementHasCapture = false;
pic = inputReport.StylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);
int pointLength = inputReport.PenContext.StylusPointDescription.GetInputArrayLengthPerPoint();
// Make sure that the captured Plugin Collection is still in the list. CaptureChanges are
// deferred so there is a window where the stylus device is not updated yet. This protects us
// from using a bogus plugin collecton for an element that is in an invalid state.
if (elementHasCapture && !_plugInCollectionList.Contains(pic))
{
elementHasCapture = false; // force true hittesting to be done!
}
if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
{
int[] data = inputReport.Data;
System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
// Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
ptTablet = ptTablet * inputReport.StylusDevice.TabletDevice.TabletToScreen;
ptTablet.X = (int)Math.Round(ptTablet.X); // Make sure we snap to whole window pixels.
ptTablet.Y = (int)Math.Round(ptTablet.Y);
ptTablet = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.
pic = HittestPlugInCollection(ptTablet); // Use cached rectangles for UIElements.
}
return pic;
}
/////////////////////////////////////////////////////////////////////
// NOTE: this should only be called inside of app Dispatcher
internal StylusPlugInCollection FindPlugInCollection(UIElement element)
{
// Since we are only called on app Dispatcher this cannot change out from under us.
// System.Diagnostics.Debug.Assert(_stylusLogic.Dispatcher.CheckAccess());
foreach (StylusPlugInCollection plugInCollection in _plugInCollectionList)
{
// If same element or element is child of the plugincollection element than say we hit it.
if (plugInCollection.Element == element ||
(plugInCollection.Element as Visual).IsAncestorOf(element as Visual))
{
return plugInCollection;
}
}
return null;
}
/////////////////////////////////////////////////////////////////////
// NOTE: this is called on pen thread (outside of apps Dispatcher)
StylusPlugInCollection HittestPlugInCollection(Point pt)
{
// Caller must make call to this routine inside of lock(__rtiLock)!
foreach (StylusPlugInCollection plugInCollection in _plugInCollectionList)
{
if (plugInCollection.IsHit(pt))
{
return plugInCollection;
}
}
return null;
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - PresentationSource is critical
///
internal SecurityCriticalData _inputSource;
///
/// Critical to prevent accidental spread to transparent code
///
[SecurityCritical]
StylusLogic _stylusLogic;
object __rtiLock = new object();
List _plugInCollectionList = new List();
///
/// Critical to prevent accidental spread to transparent code
///
[SecurityCritical]
PenContext[] _contexts;
bool _isWindowDisabled;
Point _destroyedLocation = new Point(0,0);
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Security ;
using MS.Internal ;
using MS.Win32;
using MS.Utility;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.Internal;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Interop;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
using MS.Internal.PresentationCore; // SecurityHelper
namespace System.Windows.Input
{
/////////////////////////////////////////////////////////////////////////
internal sealed class PenContexts
{
/////////////////////////////////////////////////////////////////////////
///
/// Critical - InputManager ctor is critical, ergo this is critical data.
/// Called by Stylus.RegisterHwndForInput.
/// TreatAsSafe boundary is Stylus.RegisterHwndForInput called when a window is created.
///
[SecurityCritical]
internal PenContexts(StylusLogic stylusLogic, PresentationSource inputSource)
{
HwndSource hwndSource = inputSource as HwndSource;
if(hwndSource == null || IntPtr.Zero == (hwndSource).CriticalHandle)
{
throw new InvalidOperationException(SR.Get(SRID.Stylus_PenContextFailure));
}
_stylusLogic = stylusLogic;
_inputSource = new SecurityCriticalData(hwndSource);
}
/////////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code (TabletDevices.CreateContexts and PenContext.Enable) and accesses
/// SecurityCritical data (_inputSource.Value and _contexts).
/// Called by Stylus.EnableCore, Stylus.RegisterHwndForInput, Stylus.OnScreenMeasurementsChanged.
/// TreatAsSafe boundry is Stylus.EnableCore, Stylus.RegisterHwndForInput
/// and HwndWrapperHook class (via HwndSource.InputFilterMessage when
/// a WM_DISPLAYCHANGE is processed by HwndStylusInputProvider).
///
[SecurityCritical]
internal void Enable()
{
if (_contexts == null)
{
// create contexts
_contexts = _stylusLogic.TabletDevices.CreateContexts(_inputSource.Value.CriticalHandle, this);
foreach(PenContext context in _contexts)
{
context.Enable();
}
}
}
///
/// Critical - Accesses SecurityCritical data (_contexts).
/// Called by Stylus.UnregisterHwndForInput and Dispose.
/// TreatAsSafe boundry is Stylus.UnregisterHwndForInput
/// and HwndStylusInputProvider.Dispose(bool).
///
[SecurityCritical]
internal void Disable(bool shutdownWorkerThread)
{
if (_contexts != null)
{
foreach(PenContext context in _contexts)
{
context.Disable(shutdownWorkerThread);
}
_contexts = null; // release refs on PenContext objects
}
}
internal bool IsWindowDisabled
{
get { return _isWindowDisabled; }
set { _isWindowDisabled = value; }
}
internal Point DestroyedLocation
{
get { return _destroyedLocation; }
set { _destroyedLocation = value; }
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenDown.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenDown(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.Down, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenUp.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenUp(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.Up, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePackets.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPackets(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.Move, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePackets.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnInAirPackets(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.InAirMove, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenInRange.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenInRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
{
ProcessInput(RawStylusActions.InRange, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - Calls SecurityCritical code ProcessInput.
/// Called by PenContext.FirePenOutOfRange.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnPenOutOfRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int timestamp)
{
ProcessInput(RawStylusActions.OutOfRange, penContext, tabletDeviceId, stylusPointerId, new int[]{}, timestamp);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical: Uses critical data _inputSource and calls SecurityCritical code
/// StylusLogic.ProcessSystemEvent.
/// Called by PenContext.FireSystemGesture.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
internal void OnSystemEvent(PenContext penContext,
int tabletDeviceId,
int stylusPointerId,
int timestamp,
SystemGesture id,
int gestureX,
int gestureY,
int buttonState)
{
_stylusLogic.ProcessSystemEvent(penContext,
tabletDeviceId,
stylusPointerId,
timestamp,
id,
gestureX,
gestureY,
buttonState,
_inputSource.Value);
}
/////////////////////////////////////////////////////////////////////
///
/// Critical: Uses critical data _inputSource and calls SecurityCritical
/// code StylusLogic.ProcessInput.
/// Called by OnPenDown, OnPenUp, OnPackets, OnInAirPackets, OnPenInRange and OnPenOutOfRange.
/// TreatAsSafe boundary is PenThread.ThreadProc.
///
[SecurityCritical]
void ProcessInput(
RawStylusActions actions,
PenContext penContext,
int tabletDeviceId,
int stylusPointerId,
int[] data, int timestamp)
{
// (all events but SystemEvent go thru here)
_stylusLogic.ProcessInput(
actions,
penContext,
tabletDeviceId,
stylusPointerId,
data,
timestamp,
_inputSource.Value);
}
/////////////////////////////////////////////////////////////////////////
///
/// Critical since it accesses SecurityCritical data _contexts and
/// returns SecurityCritical data PenContext.
///
[SecurityCritical]
internal PenContext GetTabletDeviceIDPenContext(int tabletDeviceId)
{
if (_contexts != null)
{
for (int i = 0; i < _contexts.Length; i++)
{
PenContext context = _contexts[i];
if (context.TabletDeviceId == tabletDeviceId)
return context;
}
}
return null;
}
/////////////////////////////////////////////////////////////////////////
///
/// Critical since it accesses SecurityCritical data _contexts.
///
[SecurityCritical]
internal bool ConsiderInRange(int timestamp)
{
if (_contexts != null)
{
for (int i = 0; i < _contexts.Length; i++)
{
PenContext context = _contexts[i];
// We consider it InRange if we have a queued up context event or
// the timestamp - LastInRangeTime <= 500 (seen one in the last 500ms)
// Here's some info on how this works...
// int.MaxValue - int.MinValue = -1 (subtracting any negative # from MaxValue keeps this negative)
// int.MinValue - int.MaxValue = 1 (subtracting any positive # from MinValue keeps this positive)
// So subtracting wrapping values will return proper sign depending on which was earlier.
// We do have the assumption that these values will be relative close in time. If the
// time wraps we'll say yet but the only harm is that we may defer a mouse move event temporarily
// which won't cause any harm.
if (context.QueuedInRangeCount > 0 || (Math.Abs(unchecked(timestamp - context.LastInRangeTime)) <= 500))
return true;
}
}
return false;
}
/////////////////////////////////////////////////////////////////////
///
/// This method adds the specified pen context index in response
/// to the WM_TABLET_ADDED notification
///
///
/// Critical - Calls SecurityCritical code (Disable and TabletDevice.CreateContext)
/// and accesses SecurityCritical data (_contexts).
/// Called by Stylus.OnTabletAdded.
/// TreatAsSafe boundary is HwndWrapperHook class (via HwndSource.InputFilterMessage).
///
[SecurityCritical]
internal void AddContext(uint index)
{
// We only tear down the old context when PenContexts are enabled without being
// dispose and we have a valid index. Otherwise, no-op here.
if (_contexts != null && index <= _contexts.Length && _inputSource.Value.CriticalHandle != IntPtr.Zero)
{
PenContext[] ctxs = new PenContext[_contexts.Length + 1];
uint preCopyCount = index;
uint postCopyCount = (uint)_contexts.Length - index;
Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
PenContext newContext = _stylusLogic.TabletDevices[(int)index].CreateContext(_inputSource.Value.CriticalHandle, this);
ctxs[index] = newContext;
Array.Copy(_contexts, index, ctxs, index+1, postCopyCount);
_contexts = ctxs;
newContext.Enable();
}
}
/////////////////////////////////////////////////////////////////////
///
/// This method removes the specified pen context index in response
/// to the WM_TABLET_REMOVED notification
///
///
/// Critical - Calls SecurityCritical code (Disable and PenContext constructor) and
/// accesses SecurityCritical data (_contexts).
/// Called by Stylus.OnTabletRemoved.
/// TreatAsSafe boundary is HwndWrapperHook class (via HwndSource.InputFilterMessage).
///
[SecurityCritical]
internal void RemoveContext(uint index)
{
// We only tear down the old context when PenContexts are enabled without being
// dispose and we have a valid index. Otherwise, no-op here.
if (_contexts != null && index < _contexts.Length)
{
PenContext removeCtx = _contexts[index];
PenContext[] ctxs = new PenContext[_contexts.Length - 1];
uint preCopyCount = index;
uint postCopyCount = (uint)_contexts.Length - index - 1;
Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
Array.Copy(_contexts, index+1, ctxs, index, postCopyCount);
removeCtx.Disable(false); // shut down this context.
_contexts = ctxs;
}
}
/////////////////////////////////////////////////////////////////////
internal object SyncRoot
{
get
{
return __rtiLock;
}
}
internal void AddStylusPlugInCollection(StylusPlugInCollection pic)
{
// must be called from inside of lock(__rtiLock)
// insert in ZOrder
_plugInCollectionList.Insert(FindZOrderIndex(pic), pic);
}
internal void RemoveStylusPlugInCollection(StylusPlugInCollection pic)
{
// must be called from inside of lock(__rtiLock)
_plugInCollectionList.Remove(pic);
}
internal int FindZOrderIndex(StylusPlugInCollection spicAdding)
{
//should be called inside of lock(__rtiLock)
DependencyObject spicAddingVisual = spicAdding.Element as Visual;
int i;
for (i=0; i < _plugInCollectionList.Count; i++)
{
// first see if parent of node, if it is then we can just scan till we find the
// first non parent and we're done
DependencyObject curV = _plugInCollectionList[i].Element as Visual;
if (VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
{
i++;
while (i < _plugInCollectionList.Count)
{
curV = _plugInCollectionList[i].Element as Visual;
if (!VisualTreeHelper.IsAncestorOf(spicAddingVisual, curV))
break; // done
i++;
}
return i;
}
else
{
// Look to see if spicAddingVisual is higher in ZOrder than i, if so then we're done
DependencyObject commonParent = VisualTreeHelper.FindCommonAncestor(spicAddingVisual, curV);
// If no common parent found then we must have multiple plugincollection elements
// that have been removed from the visual tree and we haven't been notified yet of
// that change. In this case just ignore this plugincollection element and go to
// the next.
if (commonParent == null)
continue;
// If curV is the commonParent we find then we're done. This new plugin should be
// above this one.
if (curV == commonParent)
return i;
// now find first child for each under that common visual that these fall under (not they must be different or common parent is sort of busted.
while (VisualTreeHelper.GetParentInternal(spicAddingVisual) != commonParent)
spicAddingVisual = VisualTreeHelper.GetParentInternal(spicAddingVisual);
while (VisualTreeHelper.GetParentInternal(curV) != commonParent)
curV = VisualTreeHelper.GetParentInternal(curV);
// now see which is higher in zorder
int count = VisualTreeHelper.GetChildrenCount(commonParent);
for (int j = 0; j < count; j++)
{
DependencyObject child = VisualTreeHelper.GetChild(commonParent, j);
if (child == spicAddingVisual)
return i;
else if (child == curV)
break; // look at next index in _piList.
}
}
}
return i; // this wasn't higher so return last index.
}
///
/// Critical - Calls into security critical code TargetPlugInCollection.
/// Called by StylusLogic.CallPluginsForMouse.
/// TreatAsSafe boundary is mainly PenThread.ThreadProc and HwndWrapperHook class (via HwndSource.InputFilterMessage).
/// It can also be called via anyone with priviledge to call InputManager.ProcessInput().
///
[SecurityCritical]
internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
{
StylusPlugInCollection newPlugInCollection = null;
// lock to make sure only one event is processed at a time and no changes to state can
// be made until we finish routing this event.
lock(__rtiLock)
{
//Debug.Assert(inputReport.Actions == RawStylusActions.Down ||
// inputReport.Actions == RawStylusActions.Up ||
// inputReport.Actions == RawStylusActions.Move);
// Find new target plugin collection
if (directlyOver != null)
{
UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
if (uiElement != null)
{
newPlugInCollection = FindPlugInCollection(uiElement);
}
}
// Fire Leave event to old pluginCollection if we need to.
if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
{
// NOTE: input report points for mouse are in avalon measured units and not device!
RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);
currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);
}
if (newPlugInCollection != null)
{
// NOTE: input report points for mouse are in avalon measured units and not device!
RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
inputReport.RawStylusInput = rawStylusInput;
if (newPlugInCollection != currentPlugInCollection)
{
newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
}
// We are on the pen thread, just call directly.
newPlugInCollection.FireRawStylusInput(rawStylusInput);
// Fire custom data events (always confirmed for mouse)
foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
{
customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
}
}
}
return newPlugInCollection;
}
///
/// Critical - Calls into security critical code TargetPlugInCollection.
/// Called by StylusLogic.InvokeStylusPluginCollection.
/// TreatAsSafe boundary is mainly PenThread.ThreadProc and HwndWrapperHook class (via HwndSource.InputFilterMessage).
/// It can also be called via anyone with priviledge to call InputManager.ProcessInput().
///
[SecurityCritical]
internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
{
// Find PenContexts object for this inputReport.
StylusPlugInCollection pic = null;
// lock to make sure only one event is processed at a time and no changes to state can
// be made until we finish routing this event.
lock(__rtiLock)
{
switch (inputReport.Actions)
{
case RawStylusActions.Down:
case RawStylusActions.Move:
case RawStylusActions.Up:
// Figure out current target plugincollection.
pic = TargetPlugInCollection(inputReport);
break;
default:
return; // Nothing to do unless one of the above events
}
StylusPlugInCollection currentPic = inputReport.StylusDevice.CurrentNonVerifiedTarget;
// Fire Leave event if we need to.
if (currentPic != null && currentPic != pic)
{
// Create new RawStylusInput to send
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(currentPic.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.
RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic);
currentPic.FireEnterLeave(false, tempRawStylusInput, false);
inputReport.StylusDevice.CurrentNonVerifiedTarget = null;
}
if (pic != null)
{
// NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
// The transformTabletToView matrix and plugincollection rects though can change based
// off of layout events which is why we need to lock this.
GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
transformTabletToView.Children.Add(pic.ViewToElement); // Make it relative to the element.
transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.
RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic);
inputReport.RawStylusInput = rawStylusInput;
if (pic != currentPic)
{
inputReport.StylusDevice.CurrentNonVerifiedTarget = pic;
pic.FireEnterLeave(true, rawStylusInput, false);
}
// We are on the pen thread, just call directly.
pic.FireRawStylusInput(rawStylusInput);
}
} // lock(__rtiLock)
}
///
/// Critical - InputReport.InputSource has a LinkDemand so we need to be SecurityCritical.
/// Called by InvokeStylusPluginCollection.
/// TreatAsSafe boundary is mainly PenThread.ThreadProc and HwndWrapperHook class (via HwndSource.InputFilterMessage).
/// It can also be called via anyone with priviledge to call InputManager.ProcessInput().
///
[SecurityCritical]
internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
{
// Caller must make call to this routine inside of lock(__rtiLock)!
StylusPlugInCollection pic = null;
// We should only be called when not on the application thread!
System.Diagnostics.Debug.Assert(!inputReport.StylusDevice.CheckAccess());
// We're on the pen thread so can't touch visual tree. Use capturedPlugIn (if capture on) or cached rects.
bool elementHasCapture = false;
pic = inputReport.StylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);
int pointLength = inputReport.PenContext.StylusPointDescription.GetInputArrayLengthPerPoint();
// Make sure that the captured Plugin Collection is still in the list. CaptureChanges are
// deferred so there is a window where the stylus device is not updated yet. This protects us
// from using a bogus plugin collecton for an element that is in an invalid state.
if (elementHasCapture && !_plugInCollectionList.Contains(pic))
{
elementHasCapture = false; // force true hittesting to be done!
}
if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
{
int[] data = inputReport.Data;
System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
// Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
ptTablet = ptTablet * inputReport.StylusDevice.TabletDevice.TabletToScreen;
ptTablet.X = (int)Math.Round(ptTablet.X); // Make sure we snap to whole window pixels.
ptTablet.Y = (int)Math.Round(ptTablet.Y);
ptTablet = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.
pic = HittestPlugInCollection(ptTablet); // Use cached rectangles for UIElements.
}
return pic;
}
/////////////////////////////////////////////////////////////////////
// NOTE: this should only be called inside of app Dispatcher
internal StylusPlugInCollection FindPlugInCollection(UIElement element)
{
// Since we are only called on app Dispatcher this cannot change out from under us.
// System.Diagnostics.Debug.Assert(_stylusLogic.Dispatcher.CheckAccess());
foreach (StylusPlugInCollection plugInCollection in _plugInCollectionList)
{
// If same element or element is child of the plugincollection element than say we hit it.
if (plugInCollection.Element == element ||
(plugInCollection.Element as Visual).IsAncestorOf(element as Visual))
{
return plugInCollection;
}
}
return null;
}
/////////////////////////////////////////////////////////////////////
// NOTE: this is called on pen thread (outside of apps Dispatcher)
StylusPlugInCollection HittestPlugInCollection(Point pt)
{
// Caller must make call to this routine inside of lock(__rtiLock)!
foreach (StylusPlugInCollection plugInCollection in _plugInCollectionList)
{
if (plugInCollection.IsHit(pt))
{
return plugInCollection;
}
}
return null;
}
/////////////////////////////////////////////////////////////////////
///
/// Critical - PresentationSource is critical
///
internal SecurityCriticalData _inputSource;
///
/// Critical to prevent accidental spread to transparent code
///
[SecurityCritical]
StylusLogic _stylusLogic;
object __rtiLock = new object();
List _plugInCollectionList = new List();
///
/// Critical to prevent accidental spread to transparent code
///
[SecurityCritical]
PenContext[] _contexts;
bool _isWindowDisabled;
Point _destroyedLocation = new Point(0,0);
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RuntimeCompatibilityAttribute.cs
- SqlMetaData.cs
- CodeObjectCreateExpression.cs
- EndPoint.cs
- DocumentSequenceHighlightLayer.cs
- Cell.cs
- FrameDimension.cs
- GroupLabel.cs
- SqlSelectStatement.cs
- ThreadBehavior.cs
- EpmTargetPathSegment.cs
- CharEntityEncoderFallback.cs
- UpdateCompiler.cs
- PropertyMap.cs
- XmlNamespaceMappingCollection.cs
- ListSourceHelper.cs
- SafeHandle.cs
- DocumentsTrace.cs
- translator.cs
- DataStreamFromComStream.cs
- WindowsListViewItemCheckBox.cs
- ServiceHostingEnvironment.cs
- DirectoryObjectSecurity.cs
- ActiveDocumentEvent.cs
- MemberPath.cs
- ExtentCqlBlock.cs
- PointLight.cs
- ZipIOExtraFieldZip64Element.cs
- NotConverter.cs
- PropertyEmitterBase.cs
- ConnectionStringSettings.cs
- XmlSchemaRedefine.cs
- SiteMap.cs
- SmtpReplyReader.cs
- EntityDataSourceSelectedEventArgs.cs
- TargetControlTypeCache.cs
- ProgressBarBrushConverter.cs
- AnnotationStore.cs
- MediaContextNotificationWindow.cs
- DaylightTime.cs
- PageRequestManager.cs
- Stream.cs
- SqlWorkflowPersistenceService.cs
- XamlGridLengthSerializer.cs
- FontEditor.cs
- SessionParameter.cs
- CodeSnippetCompileUnit.cs
- X509Utils.cs
- XslNumber.cs
- NeedSkipTokenVisitor.cs
- ResolveDuplex11AsyncResult.cs
- CodeIdentifier.cs
- Geometry3D.cs
- ContractBase.cs
- VisualProxy.cs
- ValidationEventArgs.cs
- StandardToolWindows.cs
- SqlPersonalizationProvider.cs
- IPipelineRuntime.cs
- MetadataItemEmitter.cs
- SharedDp.cs
- DrawingCollection.cs
- Timer.cs
- DateTimeHelper.cs
- BufferedGraphicsContext.cs
- TextEffectCollection.cs
- Evidence.cs
- ParallelEnumerable.cs
- Soap.cs
- Page.cs
- AppModelKnownContentFactory.cs
- DataStorage.cs
- MultiPageTextView.cs
- FormViewUpdatedEventArgs.cs
- DataGridViewCellStyleEditor.cs
- HandleExceptionArgs.cs
- SettingsPropertyWrongTypeException.cs
- Pair.cs
- LiteralLink.cs
- UpDownEvent.cs
- EventProviderWriter.cs
- HtmlEmptyTagControlBuilder.cs
- ResourceDisplayNameAttribute.cs
- SizeConverter.cs
- SchemaReference.cs
- HtmlGenericControl.cs
- SemanticResultKey.cs
- KnownTypes.cs
- SystemColorTracker.cs
- BlockUIContainer.cs
- WebPartTracker.cs
- HttpCookiesSection.cs
- CodeParameterDeclarationExpressionCollection.cs
- NewArrayExpression.cs
- StreamBodyWriter.cs
- KeyGestureValueSerializer.cs
- TabItemAutomationPeer.cs
- SimpleMailWebEventProvider.cs
- AdvancedBindingEditor.cs
- DefaultMemberAttribute.cs