On 2 occasions now my adventures have required that I write a vb.net macro that placed some text into the clipboard. The first adventure involved having the user type "check-in comments" into an inputbox, writing those comments into the code and then placing the comments into the clipboard so they could use them as check-in comments in the check-in window (which I launched as part of the macro). That first adventure proved treacherous because no matter how hard I pounded the same nail with the same hammer it didn't want to go in.
Whenever my macro code tried to execute this line:
Clipboard.SetText(originalComment, TextDataFormat.Text)
I would get this error:
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it."
Finally, I came across the workaround of placing the text into the code editor in VS and then executing this line of code:
DTE.ExecuteCommand("Edit.Cut")
This worked wonders because I had tricked Visual Studio into thinking the user had clicked Cut in the Edit menu.
Today brought a new challenge. I needed to insert many lines into the user's clipboard. In my single line situation I had used the following to select my single line.
DTE.ActiveDocument.Selection.LineUp
DTE.ActiveDocument.Selection.SelectLine
It turns out the .LineUp() method supports 2 optional parameters. The first (extend as boolean) tells the editor whether or not to make a selection of the lines as it moves up. The second parameter [count as integer] tells the editor how many lines to go up.
Here's my final solution for copying text to the user's clipboard:
This requires the following imports
Imports System.Text.RegularExpressions
Imports EnvDTE
Imports EnvDTE80
'copies the given text to the IDE clipboard
Friend Sub CopyTextToClipboard(ByVal textToCopy As String)
Dim sel As TextSelection = DTE.ActiveDocument.Selection
With sel
DTE.UndoContext.Open("ToClipboard") 'an arbitrary name
Dim mc As MatchCollection = Regex.Matches(textToCopy, "\n")
Dim lineCount As Integer = mc.Count + 1 'add one for the NewLine (below)
'add the text into the VS code editor
.Text = textToCopy & ControlChars.NewLine
'now select the text that we pasted
.LineUp(True, lineCount) 'True creates a selection region
'cut it to put it into THEIR clipboard
DTE.ExecuteCommand("Edit.Cut") 'by using Edit.Cut it accesses the IDE Clipboard!
DTE.UndoContext.Close()
End With
End Sub
In this particular situation I frequently paste over 100 lines into the clipboard and watching Visual Studio load those lines into the IDE and then cut them right back out is a unnecessarily time consuming. If anyone knows a faster method for rendering text into the IDE or the clipboard I would love to hear from you.
Thanks for joining me on this adventure.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment