Пример #1
0
        // Inserts an InkInteropObject at a specified position.
        private TextPointer InsertInkAtPosition(TextPointer insertionPosition, InkInteropObject inkobject, out UnsafeNativeMethods.TS_TEXTCHANGE change)
        {
            int symbolsAddedBefore = 0;
            int symbolsAddedAfter = 0;

            // Prepare an insertion position for InlineUIContainer.
            // As an optimization, shift outside of any formatting tags to avoid
            // splitting tags below.
            while (insertionPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart &&
                TextSchema.IsFormattingType(insertionPosition.Parent.GetType()))
            {
                insertionPosition = insertionPosition.GetNextContextPosition(LogicalDirection.Backward);
            }
            while (insertionPosition.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd &&
                TextSchema.IsFormattingType(insertionPosition.Parent.GetType()))
            {
                insertionPosition = insertionPosition.GetNextContextPosition(LogicalDirection.Forward);
            }

            // If we need to, split the current parent TextElement and prepare
            // a suitable home for an InlineUIContainer.
            if (!TextSchema.IsValidParent(insertionPosition.Parent.GetType(), typeof(InlineUIContainer)))
            {
                insertionPosition = TextRangeEditTables.EnsureInsertionPosition(insertionPosition, out symbolsAddedBefore, out symbolsAddedAfter);
                Invariant.Assert(insertionPosition.Parent is Run, "position must be in Run scope");

                insertionPosition = TextRangeEdit.SplitElement(insertionPosition);
                // We need to remember how many symbols were added into addition
                // to the InlineUIContainer itself.
                // Account for the two element edges just added.
                symbolsAddedBefore += 1;
                symbolsAddedAfter += 1;
            }

            // Create an InlineUIContainer.
            InlineUIContainer inlineUIContainer = new InlineUIContainer(inkobject);

            change.start = ((ITextPointer)insertionPosition).Offset - symbolsAddedBefore;
            change.oldEnd = change.start;

            // Insert it into the insertionPosition.  This adds 3 symbols.
            insertionPosition.InsertTextElement(inlineUIContainer);

            change.newEnd = change.start + symbolsAddedBefore + inlineUIContainer.SymbolCount + symbolsAddedAfter;

            // Return a position after the inserted object.
            return inlineUIContainer.ElementEnd.GetInsertionPosition(LogicalDirection.Forward);
        }
Пример #2
0
        private void InsertEmbeddedAtPosition(TextPointer position, IComDataObject data, out UnsafeNativeMethods.TS_TEXTCHANGE change)
        {
            SecurityHelper.DemandUnmanagedCode();

            ITextContainer container;
            // Get enhanced metafile handle from IOleDataObject.
            FORMATETC formatetc = new FORMATETC();
            STGMEDIUM stgmedium = new STGMEDIUM();
            formatetc.cfFormat = NativeMethods.CF_ENHMETAFILE;
            formatetc.ptd = IntPtr.Zero;
            formatetc.dwAspect = DVASPECT.DVASPECT_CONTENT;
            formatetc.lindex = -1;
            formatetc.tymed = TYMED.TYMED_ENHMF;
            stgmedium.tymed = TYMED.TYMED_ENHMF;

            data.GetData(ref formatetc, out stgmedium);

            if (stgmedium.unionmember == IntPtr.Zero)
            {
                throw new COMException(SR.Get(SRID.TextStore_BadObjectData), NativeMethods.E_INVALIDARG);
            }

            IntPtr hbitmap = SystemDrawingHelper.ConvertMetafileToHBitmap(stgmedium.unionmember);

            // create a InkInteropObject framework element.
            InkInteropObject inkobject = new InkInteropObject(data);

            inkobject.Source = Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, null);

            position = InsertInkAtPosition(position, inkobject, out change);

            // Move the selection.
            container = this.TextContainer;
            TextSelection.SetCaretToPosition(position, LogicalDirection.Backward, /*allowStopAtLineEnd:*/false, /*allowStopNearSpace:*/false);
        }