예제 #1
0
파일: EventMap.cs 프로젝트: yk2012985/wpf
        private static object NotifySource(Object args)
        {
            object[]           argsArray = (object[])args;
            PresentationSource source    = argsArray[0] as PresentationSource;

            if (source != null && !source.IsDisposed)
            {
                bool needAsserts = System.Security.SecurityManager.CurrentThreadRequiresSecurityContextCapture();
                if (needAsserts)
                {
                    // permission required to set RootVisual
                    new UIPermission(UIPermissionWindow.AllWindows).Assert();
                }

                // setting the RootVisual to itself triggers the logic to
                // add to the AutomationEvents list
                source.RootVisual = source.RootVisual;

                if (needAsserts)
                {
                    UIPermission.RevertAssert();
                }
            }
            return(null);
        }
예제 #2
0
        // Copies the internal strokes to the IDataObject
        protected override void DoCopy(IDataObject dataObject)
        {
            // samgeo - Presharp issue
            // Presharp gives a warning when local IDisposable variables are not closed
            // in this case, we can't call Dispose since it will also close the underlying stream
            // which needs to be open for consumers to read
#pragma warning disable 1634, 1691
#pragma warning disable 6518

            // Save the data in the data object.
            MemoryStream stream = new MemoryStream();
            Strokes.Save(stream);
            stream.Position = 0;
            (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert
            try
            {
                dataObject.SetData(StrokeCollection.InkSerializedFormat, stream);
            }
            finally
            {
                UIPermission.RevertAssert();
            }
#pragma warning restore 6518
#pragma warning restore 1634, 1691
        }
예제 #3
0
        internal HwndStylusInputProvider(HwndSource source)
        {
            InputManager inputManager = InputManager.Current;
            StylusLogic  stylusLogic  = inputManager.StylusLogic;

            IntPtr sourceHandle;

            (new UIPermission(PermissionState.Unrestricted)).Assert();
            try //Blessed Assert this is for RegisterInputManager and RegisterHwndforinput
            {
                // Register ourselves as an input provider with the input manager.
                _site = new SecurityCriticalDataClass <InputProviderSite>(inputManager.RegisterInputProvider(this));

                sourceHandle = source.Handle;
            }
            finally
            {
                UIPermission.RevertAssert();
            }

            stylusLogic.RegisterHwndForInput(inputManager, source);
            _source      = new SecurityCriticalDataClass <HwndSource>(source);
            _stylusLogic = new SecurityCriticalDataClass <StylusLogic>(stylusLogic);

            // Enables multi-touch input
            UnsafeNativeMethods.SetProp(new HandleRef(this, sourceHandle), "MicrosoftTabletPenServiceProperty", new HandleRef(null, new IntPtr(MultiTouchEnabledFlag)));
        }
예제 #4
0
파일: PointUtil.cs 프로젝트: ay2015/wpf
        public static Point ClientToScreen(Point ptClient, PresentationSource presentationSource)
        {
            // For now we only know how to use HwndSource.
            HwndSource inputSource = presentationSource as HwndSource;

            if (inputSource == null)
            {
                return(ptClient);
            }

            // Convert the point to screen coordinates.
            NativeMethods.POINT ptScreen = new NativeMethods.POINT((int)ptClient.X, (int)ptClient.Y);

            // MITIGATION: AVALON_RTL_AND_WIN32RTL
            //
            // When a window is marked with the WS_EX_LAYOUTRTL style, Win32
            // mirrors the coordinates during the various translation APIs.
            //
            // Avalon also sets up mirroring transforms so that we properly
            // mirror the output since we render to DirectX, not a GDI DC.
            //
            // Unfortunately, this means that our coordinates are already mirrored
            // by Win32, and Avalon mirrors them again.  To work around this
            // problem, we un-mirror the coordinates from Win32 before hit-testing
            // in Avalon.
            //

            //
            // Assert for unamanaged code permission to get to the handle.
            // Note that we can't use HwndSource.UnsecureHandle here - as this method is called cross-assembly
            //
            HandleRef handleRef;

            new UIPermission(UIPermissionWindow.AllWindows).Assert(); // BlessedAssert:
            try
            {
                handleRef = new HandleRef(inputSource, inputSource.Handle);
            }
            finally
            {
                UIPermission.RevertAssert();
            }

            int windowStyle = UnsafeNativeMethods.GetWindowLong(handleRef, NativeMethods.GWL_EXSTYLE);

            if ((windowStyle & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL)
            {
                NativeMethods.RECT rcClient = new NativeMethods.RECT();
                SafeNativeMethods.GetClientRect(handleRef, ref rcClient);
                ptScreen.x = rcClient.right - ptScreen.x;
            }

            UnsafeNativeMethods.ClientToScreen(handleRef, ptScreen);

            return(new Point(ptScreen.x, ptScreen.y));
        }
 internal static void InitializeHostFilterInput()
 {
     (new UIPermission(PermissionState.Unrestricted)).Assert(); // Blessed assert
     try
     {
         ComponentDispatcher.ThreadFilterMessage +=
             new ThreadMessageEventHandler(HostFilterInput);
     }
     finally
     {
         UIPermission.RevertAssert();
     }
 }
 internal HwndKeyboardInputProvider(HwndSource source)
 {
     (new UIPermission(PermissionState.Unrestricted)).Assert();
     try //Blessed assert for InputManager.Current.RegisterInputProvider
     {
         _site = new SecurityCriticalDataClass <InputProviderSite>(InputManager.Current.RegisterInputProvider(this));
     }
     finally
     {
         UIPermission.RevertAssert();
     }
     _source = new SecurityCriticalDataClass <HwndSource>(source);
 }
예제 #7
0
파일: PointUtil.cs 프로젝트: ay2015/wpf
        internal static Point ScreenToClient(Point ptScreen, PresentationSource presentationSource)
        {
            // For now we only know how to use HwndSource.
            HwndSource inputSource = presentationSource as HwndSource;

            if (inputSource == null)
            {
                return(ptScreen);
            }

            HandleRef handleRef;

            new UIPermission(UIPermissionWindow.AllWindows).Assert(); // BlessedAssert:
            try
            {
                handleRef = new HandleRef(inputSource, inputSource.Handle);
            }
            finally
            {
                UIPermission.RevertAssert();
            }

            // Convert the point from screen coordinates back to client coordinates.
            NativeMethods.POINT ptClient = new NativeMethods.POINT((int)ptScreen.X, (int)ptScreen.Y);
            SafeNativeMethods.ScreenToClient(handleRef, ptClient);

            // MITIGATION: WIN32_AND_AVALON_RTL
            //
            // When a window is marked with the WS_EX_LAYOUTRTL style, Win32
            // mirrors the coordinates during the various translation APIs.
            //
            // Avalon also sets up mirroring transforms so that we properly
            // mirror the output since we render to DirectX, not a GDI DC.
            //
            // Unfortunately, this means that our coordinates are already mirrored
            // by Win32, and Avalon mirrors them again.  To work around this
            // problem, we un-mirror the coordinates from Win32 before hit-testing
            // in Avalon.
            //
            int windowStyle = SafeNativeMethods.GetWindowStyle(handleRef, true);

            if ((windowStyle & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL)
            {
                NativeMethods.RECT rcClient = new NativeMethods.RECT();
                SafeNativeMethods.GetClientRect(handleRef, ref rcClient);
                ptClient.x = rcClient.right - ptClient.x;
            }

            return(new Point(ptClient.x, ptClient.y));
        }
예제 #8
0
        internal static bool IsClipboardPopulated()
        {
            bool isPopulated = false;

            (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert
            try
            {
                isPopulated = (GetDataObjectInternal() != null);
            }
            finally
            {
                UIPermission.RevertAssert();
            }
            return(isPopulated);
        }
예제 #9
0
파일: Menu.cs 프로젝트: notfarfromorion/wpf
 private void SetupMainMenu()
 {
     if (_enterMenuModeHandler == null)
     {
         _enterMenuModeHandler = new KeyboardNavigation.EnterMenuModeEventHandler(OnEnterMenuMode);
         (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //Blessed Assert
         try
         {
             KeyboardNavigation.Current.EnterMenuMode += _enterMenuModeHandler;
         }
         finally
         {
             UIPermission.RevertAssert();
         }
     }
 }
예제 #10
0
        internal HwndPointerInputProvider(HwndSource source)
        {
            (new UIPermission(PermissionState.Unrestricted)).Assert();
            try //Blessed Assert for InputManager.Current.RegisterInputProvider
            {
                _site = new SecurityCriticalDataClass <InputProviderSite>(InputManager.Current.RegisterInputProvider(this));
            }
            finally
            {
                UIPermission.RevertAssert();
            }

            _source       = new SecurityCriticalDataClass <HwndSource>(source);
            _pointerLogic = new SecurityCriticalDataClass <PointerLogic>(StylusLogic.GetCurrentStylusLogicAs <PointerLogic>());

            // Register the stylus plugin manager
            _pointerLogic.Value.PlugInManagers[_source.Value] = new PointerStylusPlugInManager(_source.Value);

            // Store if this window is enabled or disabled
            int style = MS.Win32.UnsafeNativeMethods.GetWindowLong(new HandleRef(this, source.CriticalHandle), MS.Win32.NativeMethods.GWL_STYLE);

            IsWindowEnabled = (style & MS.Win32.NativeMethods.WS_DISABLED) == 0;
        }
            private void Win32SetForegroundWindow()
            {
                PresentationSource source = null;
                IntPtr             hwnd   = IntPtr.Zero;

                source = PresentationSource.CriticalFromVisual(_textEditor.UiScope);
                if (source != null)
                {
                    new UIPermission(UIPermissionWindow.AllWindows).Assert();   //BlessedAssert
                    try
                    {
                        hwnd = (source as IWin32Window).Handle;
                    }
                    finally
                    {
                        UIPermission.RevertAssert();
                    }
                }

                if (hwnd != IntPtr.Zero)
                {
                    UnsafeNativeMethods.SetForegroundWindow(new HandleRef(null, hwnd));
                }
            }
예제 #12
0
        /// <summary>
        /// Creates DataObject for Copy and Drag operations
        /// </summary>
        internal static DataObject _CreateDataObject(TextEditor This, bool isDragDrop)
        {
            DataObject dataObject;

            // Create the data object for drag and drop.
            //  We could provide more extensibility here -
            // by allowing application to create its own DataObject.
            // Without it our extensibility looks inconsistent:
            // the interface IDataObject suggests that you can
            // create your own implementation of it, but you
            // really cannot, because there is no way of
            // using it in our TextEditor.Copy/Drag.
            (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert
            try
            {
                dataObject = new DataObject();
            }
            finally
            {
                UIPermission.RevertAssert();
            }

            // Get plain text and copy it into the data object.
            string textString = This.Selection.Text;

            if (textString != String.Empty)
            {
                // Copy plain text into data object.
                // ConfirmDataFormatSetting rasies a public event - could throw recoverable exception.
                if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.Text))
                {
                    dataObject.SetData(DataFormats.Text, textString, false);
                }

                // Copy unicode text into data object.
                // ConfirmDataFormatSetting rasies a public event - could throw recoverable exception.
                if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.UnicodeText))
                {
                    dataObject.SetData(DataFormats.UnicodeText, textString, false);
                }
            }

            // Get the rtf and xaml text and then copy it into the data object after confirm data format.
            // We do this only if our content is rich
            if (This.AcceptsRichContent)
            {
                Stream wpfContainerMemory = null;
                // null wpfContainerMemory on entry means that container is optional
                // and will be not created when there is no images in the range.

                // Create in-memory wpf package, and serialize the content of selection into it
                string xamlTextWithImages = WpfPayload.SaveRange(This.Selection, ref wpfContainerMemory, /*useFlowDocumentAsRoot:*/ false);

                if (xamlTextWithImages.Length > 0)
                {
                    // ConfirmDataFormatSetting raises a public event - could throw recoverable exception.
                    if (wpfContainerMemory != null && ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.XamlPackage))
                    {
                        dataObject.SetData(DataFormats.XamlPackage, wpfContainerMemory);
                    }

                    // ConfirmDataFormatSetting raises a public event - could throw recoverable exception.
                    if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.Rtf))
                    {
                        // Convert xaml to rtf text to set rtf data into data object.
                        string rtfText = ConvertXamlToRtf(xamlTextWithImages, wpfContainerMemory);

                        if (rtfText != String.Empty)
                        {
                            dataObject.SetData(DataFormats.Rtf, rtfText, true);
                        }
                    }

                    // Add a CF_BITMAP if we have only one image selected.
                    Image image = This.Selection.GetUIElementSelected() as Image;
                    if (image != null && image.Source is System.Windows.Media.Imaging.BitmapSource)
                    {
                        dataObject.SetImage((System.Windows.Media.Imaging.BitmapSource)image.Source);
                    }
                }

                // Xaml format is availabe both in Full Trust and in Partial Trust
                // Need to re-serialize xaml to avoid image references within a container:
                StringWriter  stringWriter = new StringWriter(CultureInfo.InvariantCulture);
                XmlTextWriter xmlWriter    = new XmlTextWriter(stringWriter);
                TextRangeSerialization.WriteXaml(xmlWriter, This.Selection, /*useFlowDocumentAsRoot:*/ false, /*wpfPayload:*/ null);
                string xamlText = stringWriter.ToString();
                //  Use WpfPayload.SaveRangeAsXaml method to produce correct image.Source properties.

                if (xamlText.Length > 0)
                {
                    // ConfirmDataFormatSetting rasies a public event - could throw recoverable exception.
                    if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.Xaml))
                    {
                        // Place Xaml data onto the dataobject using safe setter
                        dataObject.SetData(DataFormats.Xaml, xamlText, false);
                    }
                }
            }

            // Notify application about our data object preparation completion
            DataObjectCopyingEventArgs dataObjectCopyingEventArgs = new DataObjectCopyingEventArgs(dataObject, /*isDragDrop:*/ isDragDrop);

            This.UiScope.RaiseEvent(dataObjectCopyingEventArgs);
            if (dataObjectCopyingEventArgs.CommandCancelled)
            {
                dataObject = null;
            }

            return(dataObject);
        }
예제 #13
0
        private void OnCopy(object sender, ExecutedRoutedEventArgs e)
        {
            if (HasSelection && _selectionRect.Width > 0 && _selectionRect.Height > 0)
            {
                //Copy to clipboard
                IDataObject dataObject;
                string      textString = GetText();
                object      bmp        = null;

                bool supportImageCopy = false;

                if (_scope is DocumentGrid && ((DocumentGrid)_scope).DocumentViewerOwner is DocumentApplicationDocumentViewer)
                {
                    // This is XPSViewer, make sure it is user initiated
                    if (!e.UserInitiated && !HasRubberBandCopyPermissions())
                    {
                        return;
                    }
                    supportImageCopy = true;
                }
                else
                {
                    //Outside of XPSViewer, support image copy in full trust only
                    supportImageCopy = HasRubberBandCopyPermissions();
                }

                if (supportImageCopy)
                {
                    bmp = SystemDrawingHelper.GetBitmapFromBitmapSource(GetImage());
                }

                (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert
                try
                {
                    dataObject = new DataObject();
                    // Order of data is irrelevant, the pasting application will determine format
                    dataObject.SetData(DataFormats.Text, textString, true);
                    dataObject.SetData(DataFormats.UnicodeText, textString, true);
                    if (bmp != null)
                    {
                        dataObject.SetData(DataFormats.Bitmap, bmp, true);
                    }
                }
                finally
                {
                    UIPermission.RevertAssert();
                }


                PermissionSet ps = new PermissionSet(PermissionState.None);
                ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
                ps.AddPermission(new UIPermission(UIPermissionClipboard.AllClipboard));
                ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));

                if (supportImageCopy)
                {
                    CodeAccessPermission mediaAccessPermission = SecurityHelper.CreateMediaAccessPermission(null);
                    ps.AddPermission(mediaAccessPermission);
                }

                ps.Assert(); // BlessedAssert

                try
                {
                    Clipboard.SetDataObject(dataObject, true);
                }
                catch (System.Runtime.InteropServices.ExternalException)
                {
                    // Clipboard is failed to set the data object.
                    return;
                }
                finally
                {
                    SecurityPermission.RevertAssert();
                }
            }
        }
예제 #14
0
        internal static DataObject _CreateDataObject(TextEditor This, bool isDragDrop)
        {
            DataObject dataObject;

            // Create the data object for drag and drop.
            //



            (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();//BlessedAssert
            try
            {
                dataObject = new DataObject();
            }
            finally
            {
                UIPermission.RevertAssert();
            }

            // Get plain text and copy it into the data object.
            string textString = This.Selection.Text;

            if (textString != String.Empty)
            {
                // Copy plain text into data object.
                // ConfirmDataFormatSetting rasies a public event - could throw recoverable exception.
                if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.Text))
                {
                    CriticalSetDataWrapper(dataObject, DataFormats.Text, textString);
                }

                // Copy unicode text into data object.
                // ConfirmDataFormatSetting rasies a public event - could throw recoverable exception.
                if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.UnicodeText))
                {
                    CriticalSetDataWrapper(dataObject, DataFormats.UnicodeText, textString);
                }
            }

            // Get the rtf and xaml text and then copy it into the data object after confirm data format.
            // We do this only if our content is rich
            if (This.AcceptsRichContent)
            {
                // This ensures that in the confines of partial trust RTF is not enabled.
                // We use unmanaged code permission over clipboard permission since
                // the latter is available in intranet zone and this is something that will
                // fail in intranet too.
                if (SecurityHelper.CheckUnmanagedCodePermission())
                {
                    // In FullTrust we allow all rich formats on the clipboard

                    Stream wpfContainerMemory = null;
                    // null wpfContainerMemory on entry means that container is optional
                    // and will be not created when there is no images in the range.

                    // Create in-memory wpf package, and serialize the content of selection into it
                    string xamlTextWithImages = WpfPayload.SaveRange(This.Selection, ref wpfContainerMemory, /*useFlowDocumentAsRoot:*/ false);

                    if (xamlTextWithImages.Length > 0)
                    {
                        // ConfirmDataFormatSetting raises a public event - could throw recoverable exception.
                        if (wpfContainerMemory != null && ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.XamlPackage))
                        {
                            dataObject.SetData(DataFormats.XamlPackage, wpfContainerMemory);
                        }

                        // ConfirmDataFormatSetting raises a public event - could throw recoverable exception.
                        if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.Rtf))
                        {
                            // Convert xaml to rtf text to set rtf data into data object.
                            string rtfText = ConvertXamlToRtf(xamlTextWithImages, wpfContainerMemory);

                            if (rtfText != String.Empty)
                            {
                                dataObject.SetData(DataFormats.Rtf, rtfText, true);
                            }
                        }
                    }

                    // Add a CF_BITMAP if we have only one image selected.
                    Image image = This.Selection.GetUIElementSelected() as Image;
                    if (image != null && image.Source is System.Windows.Media.Imaging.BitmapSource)
                    {
                        dataObject.SetImage((System.Windows.Media.Imaging.BitmapSource)image.Source);
                    }
                }

                // Xaml format is availabe both in Full Trust and in Partial Trust
                // Need to re-serialize xaml to avoid image references within a container:
                StringWriter  stringWriter = new StringWriter(CultureInfo.InvariantCulture);
                XmlTextWriter xmlWriter    = new XmlTextWriter(stringWriter);
                TextRangeSerialization.WriteXaml(xmlWriter, This.Selection, /*useFlowDocumentAsRoot:*/ false, /*wpfPayload:*/ null);
                string xamlText = stringWriter.ToString();
                //

                if (xamlText.Length > 0)
                {
                    // ConfirmDataFormatSetting rasies a public event - could throw recoverable exception.
                    if (ConfirmDataFormatSetting(This.UiScope, dataObject, DataFormats.Xaml))
                    {
                        // Place Xaml data onto the dataobject using safe setter
                        CriticalSetDataWrapper(dataObject, DataFormats.Xaml, xamlText);

                        // The dataobject itself must hold an information about permission set
                        // of the source appdomain. Set it there:

                        // Package permission set for the current appdomain
                        PermissionSet psCurrentAppDomain            = SecurityHelper.ExtractAppDomainPermissionSetMinusSiteOfOrigin();
                        string        permissionSetCurrentAppDomain = psCurrentAppDomain.ToString();
                        CriticalSetDataWrapper(dataObject, DataFormats.ApplicationTrust, permissionSetCurrentAppDomain);
                    }
                }
            }

            // Notify application about our data object preparation completion
            DataObjectCopyingEventArgs dataObjectCopyingEventArgs = new DataObjectCopyingEventArgs(dataObject, /*isDragDrop:*/ isDragDrop);

            This.UiScope.RaiseEvent(dataObjectCopyingEventArgs);
            if (dataObjectCopyingEventArgs.CommandCancelled)
            {
                dataObject = null;
            }

            return(dataObject);
        }
예제 #15
0
        /// <summary>
        /// Kopiuje pojedynczą komórkę do schowka.
        /// </summary>
        public void CopyCellContentToClipboard()
        {
            DataGridCellInfo cellInfo;
            DataGridColumn   currentColumn = null;
            object           currentItem   = null;
            string           format        = DataFormats.UnicodeText;

            if (this.CurrentCell != null)
            {
                cellInfo = this.CurrentCell;
            }
            else if (this.SelectedCells.Count > 0)
            {
                cellInfo = this.SelectedCells[0];
            }

            currentColumn = cellInfo.Column;

            if (currentColumn == null)
            {
                if (this.CurrentCell != null && this.CurrentCell.Column != null)
                {
                    currentColumn = this.CurrentCell.Column;
                }
                else if (this.SelectedCells.Count > 0)
                {
                    currentColumn = this.SelectedCells[0].Column;
                }
            }

            if (currentColumn == null)
            {
                return;
            }

            if (cellInfo.Item != null)
            {
                currentItem = cellInfo.Item;
            }
            else if (this.CurrentItem != null)
            {
                currentItem = this.CurrentItem;
            }
            else if (this.SelectedCells.Count > 0 && this.SelectedCells[0].Item != null)
            {
                currentItem = this.SelectedCells[0].Item;
            }

            if (currentItem == null)
            {
                return;
            }

            var value = currentColumn.OnCopyingCellClipboardContent(currentItem);

            if (value == null || value == DBNull.Value)
            {
                value = "";
            }

            StringBuilder sb = new StringBuilder();

            DataGridBoldClipboardHelper.FormatPlainText(value, sb, format);

            DataObject dataObject;
            bool       hasPerms = SecurityHelper.CallerHasAllClipboardPermission() && SecurityHelper.CallerHasSerializationPermission();

            // Copy unconditionally in full trust.
            // Only copy in partial trust if user initiated.
            if (hasPerms)
            {
                (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();
                try
                {
                    dataObject = new DataObject();
                }
                finally
                {
                    UIPermission.RevertAssert();
                }

                dataObject.SetData(format, sb.ToString(), false /*autoConvert*/);

                // This assert is there for an OLE Callback to register CSV type for the clipboard
                (new SecurityPermission(SecurityPermissionFlag.SerializationFormatter | SecurityPermissionFlag.UnmanagedCode)).Assert();
                try
                {
                    if (dataObject != null)
                    {
                        Clipboard.SetDataObject(dataObject, true /* Copy */);
                    }
                }
                finally
                {
                    SecurityPermission.RevertAll();
                }
            }
        }
예제 #16
0
        private void OnExecutedCopyInternal(ExecutedRoutedEventArgs args)
        {
            if (ClipboardCopyMode == DataGridClipboardCopyMode.None)
            {
                throw new NotSupportedException("Cannot perform copy if ClipboardCopyMode is None.");
            }

            args.Handled = true;

            // Supported default formats: Html, Text, UnicodeText and CSV
            Collection <string> formats = new Collection <string>(new string[] { DataFormats.Html, DataFormats.Text, DataFormats.UnicodeText, DataFormats.CommaSeparatedValue });
            Dictionary <string, StringBuilder> dataGridStringBuilders = new Dictionary <string, StringBuilder>(formats.Count);

            foreach (string format in formats)
            {
                dataGridStringBuilders[format] = new StringBuilder();
            }

            int minRowIndex;
            int maxRowIndex;
            int minColumnDisplayIndex;
            int maxColumnDisplayIndex;

            // Get the bounding box of the selected cells
            if (this.GetSelectionRange(out minColumnDisplayIndex, out maxColumnDisplayIndex, out minRowIndex, out maxRowIndex))
            {
                // Add column headers if enabled
                if (ClipboardCopyMode == DataGridClipboardCopyMode.IncludeHeader)
                {
                    DataGridRowClipboardEventArgs preparingRowClipboardContentEventArgs = new DataGridRowClipboardEventArgs(null, minColumnDisplayIndex, maxColumnDisplayIndex, true /*IsColumnHeadersRow*/);
                    OnCopyingRowClipboardContent(preparingRowClipboardContentEventArgs);

                    foreach (string format in formats)
                    {
                        dataGridStringBuilders[format].Append(preparingRowClipboardContentEventArgs.FormatClipboardCellValues(format));
                    }
                }

                // Add each selected row
                for (int i = minRowIndex; i <= maxRowIndex; i++)
                {
                    object row = Items[i];

                    // Row has a selecion
                    if (this.SelectedCellsIntersects(i))
                    {
                        DataGridRowClipboardEventArgs preparingRowClipboardContentEventArgs = (DataGridRowClipboardEventArgs)CONSTRUCTORINFO_DATAGRIDROWCLIPBOARDEVENTARGS.Invoke(
                            new object[] { row, minColumnDisplayIndex, maxColumnDisplayIndex, false /*IsColumnHeadersRow*/, i });
                        OnCopyingRowClipboardContent(preparingRowClipboardContentEventArgs);

                        foreach (string format in formats)
                        {
                            dataGridStringBuilders[format].Append(preparingRowClipboardContentEventArgs.FormatClipboardCellValues(format));
                        }
                    }
                }
            }

            DataGridBoldClipboardHelper.GetClipboardContentForHtml(dataGridStringBuilders[DataFormats.Html]);

            DataObject dataObject;
            bool       hasPerms = SecurityHelper.CallerHasAllClipboardPermission() && SecurityHelper.CallerHasSerializationPermission();

            // Copy unconditionally in full trust.
            // Only copy in partial trust if user initiated.
            if (hasPerms || args.GetUserInitiated())
            {
                (new UIPermission(UIPermissionClipboard.AllClipboard)).Assert();
                try
                {
                    dataObject = new DataObject();
                }
                finally
                {
                    UIPermission.RevertAssert();
                }

                foreach (string format in formats)
                {
                    if (dataGridStringBuilders[format] != null)
                    {
                        dataObject.SetData(format, dataGridStringBuilders[format].ToString(), false /*autoConvert*/);
                    }
                }

                // This assert is there for an OLE Callback to register CSV type for the clipboard
                (new SecurityPermission(SecurityPermissionFlag.SerializationFormatter | SecurityPermissionFlag.UnmanagedCode)).Assert();
                try
                {
                    if (dataObject != null)
                    {
                        Clipboard.SetDataObject(dataObject, true /* Copy */);
                    }
                }
                finally
                {
                    SecurityPermission.RevertAll();
                }
            }
        }