Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to obtain the absolute position of text cursor in Visual Studio 2010 extension

I've developed an IntelliSense-like Dialog, which should appear on a specific key-stroke. (My project is a VS-Package, my dialog will be opened as a command) The problem is, I don't know how to display my dialog at the current cursor-position. There are easy ways of dealing with the currently selected text, e.g. with

 TextSelection objSel = (EnvDTE.TextSelection)(dte.ActiveDocument.Selection);

but I can't obtain any absolute position here.

I've searched a lot, but didn't find anything, which could help me. Maybe someone can give me a hint or - even better - code examples to solve my problem. I'd really appreciate your help!

like image 670
Christian Binder Avatar asked Dec 23 '11 09:12

Christian Binder


1 Answers

I am doing exactly the same thing in a current project, so here is the relevant code copy and pasted. I generate the activeWpfTextView object elsewhere using the following answer: Find an IVsTextView or IWpfTextView for a given ProjectItem, in VS 2010 RC extension.

    private IVsWindowFrame GetWindow()
    {
        // parent is the Microsoft.VisualStudio.Shell.ToolWindowPane
        //  containing this UserControl given in the constructor.
        var window = (ToolWindowPane)parent.GetIVsWindowPane();
        return (IVsWindowFrame)window.Frame;
    }

    private void DoShow()
    {
        var window = GetWindow();

        var textViewOrigin = (activeWpfTextView as UIElement).PointToScreen(new Point(0, 0));

        var caretPos = activeWpfTextView.Caret.Position.BufferPosition;
        var charBounds = activeWpfTextView
            .GetTextViewLineContainingBufferPosition(caretPos)
            .GetCharacterBounds(caretPos);
        double textBottom = charBounds.Bottom;
        double textX = charBounds.Right;

        Guid guid = default(Guid);
        double newLeft = textViewOrigin.X + textX - activeWpfTextView.ViewportLeft;
        double newTop = textViewOrigin.Y + textBottom - activeWpfTextView.ViewportTop;
        window.SetFramePos(VSSETFRAMEPOS.SFP_fMove, ref guid,
            (int)newLeft, (int)newTop,
            0, 0);

        window.Show();
        resultsList.Focus();
    }
like image 109
perelman Avatar answered Nov 05 '22 17:11

perelman