Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / Ink / InkCollectionBehavior.cs / 1 / InkCollectionBehavior.cs
//---------------------------------------------------------------------------- // // File: InkCollectionBehavior.cs // // Description: // Ink Collection Behavior // // Authors: [....]/[....]/bkrantz // // Copyright (C) 2003 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Diagnostics; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Interop; using System.ComponentModel; using System.Collections.Specialized; using Swi = System.Windows.Ink; using System.Windows.Documents; namespace MS.Internal.Ink { ////// InkCollectionBehavior /// ////// This class is sealed, I was worried that StylusEndInput could be overridden /// and bypass the security check, but it turns out that concern is not valid. /// Even if StylusEndInput was overridden and called the base method, we're still fine /// here since we don't make a security decision based on the bool that is passed /// to the method. We make the security decision based on the _userInitiated security critical /// member. All the same, we'll leave this class as sealed. /// internal sealed class InkCollectionBehavior : StylusEditingBehavior { //------------------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------------------- #region Constructors ////// Critical: Touches critical member _stylusPoints, which is passed to /// SecurityCritical method InkCanvas.RaiseGestureOrStrokeCollected /// /// TreatAsSafe: only initializes _stylusPoints to null, _userInitialize to false /// /// [SecurityCritical, SecurityTreatAsSafe] internal InkCollectionBehavior(EditingCoordinator editingCoordinator, InkCanvas inkCanvas) : base(editingCoordinator, inkCanvas) { _stylusPoints = null; _userInitiated = false; } #endregion Constructors ////// A method which flags InkCollectionBehavior when it needs to reset the dynamic renderer. /// Called By: /// EditingCoordinator.OnInkCanvasDeviceDown /// internal void ResetDynamicRenderer() { _resetDynamicRenderer = true; } //-------------------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------------------- #region Protected Methods ////// Overrides SwitchToMode /// As the following expected results /// 1. From Ink To InkAndGesture /// Packets between StylusDown and StylusUp are sent to the gesture reco. On StylusUp gesture event fires. If it�s not a gesture, StrokeCollected event fires. /// 2. From Ink To GestureOnly /// Packets between StylusDown and StylusUp are send to the gesture reco. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it�s not a gesture. /// 3. From Ink To EraseByPoint /// Stroke is discarded. PointErasing is performed after changing the mode. /// 4. From Ink To EraseByStroke /// Stroke is discarded. StrokeErasing is performed after changing the mode. /// 5. From Ink To Select /// Stroke is discarded. Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected. /// 6. From Ink To None /// Stroke is discarded. /// 7. From InkAndGesture To Ink /// Stroke is collected for all packets between StylusDown and StylusUp. Gesture event does not fire. /// 8. From InkAndGesture To GestureOnly /// Packets between StylusDown and StylusUp are sent to the gesture reco. Stroke gets removed on StylusUp even if it�s not a gesture. /// 9. From InkAndGesture To EraseByPoint /// Stroke is discarded. PointErasing is performed after changing the mode, gesture event does not fire. /// 10. From InkAndGesture To EraseByStroke /// Stroke is discarded. StrokeErasing is performed after changing the mode, gesture event does not fire. /// 11. From InkAndGesture To Select /// Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected. /// 12. From InkAndGesture To None /// Stroke is discarded, no gesture is recognized. /// 13. From GestureOnly To InkAndGesture /// Packets between StylusDown and StylusUp are sent to the gesture reco. On StylusUp gesture event fires. If it�s not a gesture, StrokeCollected event fires. /// 14. From GestureOnly To Ink /// Stroke is collected. Gesture event does not fire. /// 15. From GestureOnly To EraseByPoint /// Stroke is discarded PointErasing is performed after changing the mode, gesture event does not fire /// 16. From GestureOnly To EraseByStroke /// Stroke is discarded. StrokeErasing is performed after changing the mode, gesture event does not fire. /// 17. From GestureOnly To Select /// Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected. /// 18. From GestureOnly To None /// Stroke is discarded. Gesture event does not fire. /// /// ////// Critical: Clones SecurityCritical member _stylusPoints, which is only critical /// as an argument in StylusInputEnd to critical method InkCanvas.RaiseGestureOrStrokeCollected /// /// TreatAsSafe: This method simply clones critical member _stylusPoints and passes that to transparent code /// _stylusPoints is only critical when passed to InkCanvas.RaiseGestureOrStrokeCollected. /// [SecurityCritical, SecurityTreatAsSafe] protected override void OnSwitchToMode(InkCanvasEditingMode mode) { Debug.Assert(EditingCoordinator.IsInMidStroke, "SwitchToMode should only be called in a mid-stroke"); switch ( mode ) { case InkCanvasEditingMode.Ink: case InkCanvasEditingMode.InkAndGesture: case InkCanvasEditingMode.GestureOnly: { // We are under one of those Ink modes now. Nothing to change here except raising the mode change event. InkCanvas.RaiseActiveEditingModeChanged(new RoutedEventArgs(InkCanvas.ActiveEditingModeChangedEvent, InkCanvas)); break; } case InkCanvasEditingMode.EraseByPoint: case InkCanvasEditingMode.EraseByStroke: { // Discard the collected ink. Commit(false); // Change the Erase mode EditingCoordinator.ChangeStylusEditingMode(this, mode); break; } case InkCanvasEditingMode.Select: { // Make a copy of the current cached points. StylusPointCollection cachedPoints = _stylusPoints != null ? _stylusPoints.Clone() : null; // Discard the collected ink. Commit(false); // Change the Select mode IStylusEditing newBehavior = EditingCoordinator.ChangeStylusEditingMode(this, mode); if ( cachedPoints != null // NOTICE-2006/04/27-[....], // EditingCoordinator.ChangeStylusEditingMode raises external event. // The user code could take any arbitrary action for instance calling InkCanvas.ReleaseMouseCapture() // So there is no guarantee that we could receive the newBehavior. && newBehavior != null) { // Now add the previous points to the lasso behavior // The SelectionBehavior doesn't check userInitiated, pass false // even if our _userInitiated flag is true newBehavior.AddStylusPoints(cachedPoints, false/*userInitiated*/); } break; } case InkCanvasEditingMode.None: { // Discard the collected ink. Commit(false); // Change to the None mode EditingCoordinator.ChangeStylusEditingMode(this, mode); break; } default: Debug.Assert(false, "Unknown InkCanvasEditingMode!"); break; } } ////// OnActivate /// protected override void OnActivate() { base.OnActivate(); // Enable RealTimeInking. if (InkCanvas.InternalDynamicRenderer != null) { InkCanvas.InternalDynamicRenderer.Enabled = true; InkCanvas.UpdateDynamicRenderer(); // Kick DynamicRenderer to be hooked up to renderer. } //if we're activated in PreviewStylusDown or in mid-stroke, the DynamicRenderer will miss the down //and will not ink. If that is the case, flag InkCollectionBehavior to reset RTI. _resetDynamicRenderer = EditingCoordinator.StylusOrMouseIsDown; } ////// OnDeactivate /// protected override void OnDeactivate() { base.OnDeactivate(); // Disable RealTimeInking. if (InkCanvas.InternalDynamicRenderer != null) { InkCanvas.InternalDynamicRenderer.Enabled = false; InkCanvas.UpdateDynamicRenderer(); // Kick DynamicRenderer to be removed from renderer. } } ////// Get Pen Cursor /// ///protected override Cursor GetCurrentCursor() { if ( EditingCoordinator.UserIsEditing == true ) { return Cursors.None; } else { return PenCursor; } } /// /// StylusInputBegin /// /// stylusPoints /// true if the source eventArgs.UserInitiated flag was set to true ////// Critical: Constructs SecurityCritical member _stylusPoints, which is passed /// as an argument in StylusInputEnd to critical method InkCanvas.RaiseGestureOrStrokeCollected /// /// Also accesses critical member _userInitiated, which is used to determine if all of the /// stylusPoints were user initiated /// [SecurityCritical] protected override void StylusInputBegin(StylusPointCollection stylusPoints, bool userInitiated) { _userInitiated = false; //we only initialize to true if the first stylusPoints were user initiated if (userInitiated) { _userInitiated = true; } _stylusPoints = new StylusPointCollection(stylusPoints.Description, 100); _stylusPoints.Add(stylusPoints); _strokeDrawingAttributes = this.InkCanvas.DefaultDrawingAttributes.Clone(); // Reset the dynamic renderer if it's been flagged. if ( _resetDynamicRenderer ) { InputDevice inputDevice = EditingCoordinator.GetInputDeviceForReset(); if ( InkCanvas.InternalDynamicRenderer != null && inputDevice != null ) { StylusDevice stylusDevice = inputDevice as StylusDevice; // If the input device is MouseDevice, null will be passed in Reset Method. InkCanvas.InternalDynamicRenderer.Reset(stylusDevice, stylusPoints); } _resetDynamicRenderer = false; } // Call InvalidateBehaviorCursor at the end of the routine. The method will cause an external event fired. // So it should be invoked after we set up our states. EditingCoordinator.InvalidateBehaviorCursor(this); } ////// StylusInputContinue /// /// stylusPoints /// true if the source eventArgs.UserInitiated flag was set to true ////// Critical: Adds to SecurityCritical member _stylusPoints, which are passed /// as an argument in StylusInputEnd to critical method InkCanvas.RaiseGestureOrStrokeCollected /// /// Also accesses critical member _userInitiated, which is used to determine if all of the /// stylusPoints were user initiated /// [SecurityCritical] protected override void StylusInputContinue(StylusPointCollection stylusPoints, bool userInitiated) { //we never set _userInitated to true after it is initialized, only to false if (!userInitiated) { _userInitiated = false; } _stylusPoints.Add(stylusPoints); } ////// StylusInputEnd /// /// commit ////// Critical: Calls SecurityCritical method InkCanvas.RaiseGestureOrStrokeCollected with /// critical data _stylusPoints /// /// Also accesses critical member _userInitiated, which is used to determine if all of the /// stylusPoints were user initiated /// /// TreatAsSafe: The critical methods that build up the critical argument _stylusPoints which /// is passed to critical method InkCanvas.RaiseGestureOrStrokeCollected are already marked /// critical. No critical data is passed in this method. /// [SecurityCritical, SecurityTreatAsSafe] protected override void StylusInputEnd(bool commit) { // The follow code raises Gesture and/or StrokeCollected event // The out-side code could throw exception in the their handlers. We use try/finally block to protect our status. try { if ( commit ) { // if ( _stylusPoints != null ) { Debug.Assert(_strokeDrawingAttributes != null, "_strokeDrawingAttributes can not be null, did we not see a down?"); Stroke stroke = new Stroke(_stylusPoints, _strokeDrawingAttributes); //we don't add the stroke to the InkCanvas stroke collection until RaiseStrokeCollected //since this might be a gesture and in some modes, gestures don't get added InkCanvasStrokeCollectedEventArgs argsStroke = new InkCanvasStrokeCollectedEventArgs(stroke); InkCanvas.RaiseGestureOrStrokeCollected(argsStroke, _userInitiated); } } } finally { _stylusPoints = null; _strokeDrawingAttributes = null; _userInitiated = false; EditingCoordinator.InvalidateBehaviorCursor(this); } } ////// ApplyTransformToCursor /// protected override void OnTransformChanged() { // Drop the cached pen cursor. _cachedPenCursor = null; } #endregion Protected Methods //-------------------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------------------- #region Private Methods private Cursor PenCursor { get { // We only update our cache cursor when DefaultDrawingAttributes has changed or // there are animated transforms being applied to InkCanvas. if ( _cachedPenCursor == null || _cursorDrawingAttributes != InkCanvas.DefaultDrawingAttributes ) { //adjust the DA for any Layout/Render transforms. Matrix xf = GetElementTransformMatrix(); DrawingAttributes da = this.InkCanvas.DefaultDrawingAttributes; if ( !xf.IsIdentity ) { //scale the DA, zero the offsets. xf *= da.StylusTipTransform; xf.OffsetX = 0; xf.OffsetY = 0; if ( xf.HasInverse ) { da = da.Clone(); da.StylusTipTransform = xf; } } _cursorDrawingAttributes = InkCanvas.DefaultDrawingAttributes.Clone(); _cachedPenCursor = PenCursorManager.GetPenCursor(da, false, (this.InkCanvas.FlowDirection == FlowDirection.RightToLeft)); } return _cachedPenCursor; } } #endregion Private Methods //------------------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------------------- #region Private Fields // A flag indicates that the dynamic renderer needs to be reset when StylusInputs begins. private bool _resetDynamicRenderer; ////// Critical: This is critical data passed as an argument to /// critical method InkCanvas.RaiseGestureOrStrokeCollected. /// [SecurityCritical] private StylusPointCollection _stylusPoints; ////// Critical: We use this to track if the input that makes up _stylusPoints /// 100% came frome the user (using the RoutedEventArgs.UserInitiated property) /// [SecurityCritical] private bool _userInitiated; ////// We clone the InkCanvas.DefaultDrawingAttributes on down, in case they are /// changed mid-stroke /// private DrawingAttributes _strokeDrawingAttributes; ////// The cached DrawingAttributes and Cursor instances for rendering the pen cursor. /// private DrawingAttributes _cursorDrawingAttributes; private Cursor _cachedPenCursor; #endregion Private Fields } } // 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
- ListBoxItem.cs
- RecordBuilder.cs
- ZoneLinkButton.cs
- WebControlParameterProxy.cs
- CodeAttributeArgumentCollection.cs
- Grammar.cs
- ValidatingPropertiesEventArgs.cs
- BuiltInExpr.cs
- listitem.cs
- ControlFilterExpression.cs
- AppSettingsSection.cs
- SafeLibraryHandle.cs
- FixedSOMLineCollection.cs
- CellCreator.cs
- ItemCheckEvent.cs
- PropertyFilterAttribute.cs
- PersonalizationState.cs
- ThemeDirectoryCompiler.cs
- CompilerParameters.cs
- TypedDataSetSchemaImporterExtension.cs
- TextAnchor.cs
- TextWriterTraceListener.cs
- FixedDocument.cs
- DefaultMergeHelper.cs
- DataGridViewColumnConverter.cs
- SocketManager.cs
- IsolatedStorageFile.cs
- ScriptModule.cs
- ListControlConvertEventArgs.cs
- WebPartDeleteVerb.cs
- DWriteFactory.cs
- UIAgentAsyncParams.cs
- SafeMILHandleMemoryPressure.cs
- PhysicalFontFamily.cs
- SqlEnums.cs
- EnglishPluralizationService.cs
- ObjectDataSourceDisposingEventArgs.cs
- GACMembershipCondition.cs
- Connector.xaml.cs
- LookupBindingPropertiesAttribute.cs
- TypeInformation.cs
- NativeStructs.cs
- WebPartMenu.cs
- SortAction.cs
- ListBoxItem.cs
- SRef.cs
- XmlSchemaParticle.cs
- CharAnimationUsingKeyFrames.cs
- EtwTrackingParticipant.cs
- PositiveTimeSpanValidator.cs
- HyperLinkStyle.cs
- TraceHwndHost.cs
- GeometryGroup.cs
- AnnotationDocumentPaginator.cs
- WizardStepCollectionEditor.cs
- DataGridViewCellStyleEditor.cs
- SplitterCancelEvent.cs
- Quad.cs
- FunctionImportMapping.cs
- EnumType.cs
- Tuple.cs
- RayHitTestParameters.cs
- Table.cs
- SQLGuid.cs
- EmbeddedMailObject.cs
- QualificationDataItem.cs
- CqlLexer.cs
- HttpPostedFileWrapper.cs
- JulianCalendar.cs
- ZipArchive.cs
- EntityCommandCompilationException.cs
- SmtpNtlmAuthenticationModule.cs
- Base64WriteStateInfo.cs
- FixedSOMTextRun.cs
- ClientRuntimeConfig.cs
- CharacterBuffer.cs
- NetworkAddressChange.cs
- LowerCaseStringConverter.cs
- DbConnectionStringCommon.cs
- DetailsViewInsertedEventArgs.cs
- TimeSpanMinutesOrInfiniteConverter.cs
- ConnectionPoint.cs
- WindowsGrip.cs
- MaskDescriptor.cs
- TemplatedAdorner.cs
- XmlSerializationWriter.cs
- NativeRecognizer.cs
- EventLogLink.cs
- EntryPointNotFoundException.cs
- RIPEMD160.cs
- OverflowException.cs
- HandledMouseEvent.cs
- Attributes.cs
- DBConnection.cs
- OrderedEnumerableRowCollection.cs
- HttpCacheVaryByContentEncodings.cs
- TimersDescriptionAttribute.cs
- PrintingPermission.cs
- DbTransaction.cs
- GenericTypeParameterBuilder.cs