在VS.NET 2003以及VS 2005的Macro中,虽然说我们可以非常方便的引用使用.NET Framework,不过Framework中一些和线程模式相关的类库却并不能直接被使用。其中非常有用的Clipboard类就因为Macro执行环境的线程模式原因不能执行,真是一大遗憾的说。那么有没有办法解决呢?
我们来看一下Macro中直接使用Clipboard有什么问题呢?我们随便创建一个Sub,比如:Test。在Test中我们执行Clipboard.SetDataObject(new Object),会怎么样呢?得到一个错误提示:
说得也还明白,需要STA模式的进程/线程才能使用Clipboard类操作剪贴板。有人曾尝试使用C#编写了一个使用Clipboard类的dll,然后在Macro中调用这个assembly,结果还是得到上面的这个错误;还有人使用EditPoint.Paste()和EditPost.Copy()方法来使用剪贴板,但是这个方法只能让EditPoint的内容和剪贴板交互,而不能为剪贴板设置任意的值,显然不是通用的剪贴板操作方式。
正因为Macro可以调用.NET Framework,所以我们就创建一个STA的线程来访问剪贴板就行了,实现访问剪贴板的代码如下:
上次我说到VS 2005的有个 小bug,不能Copy出在线文档的Full Path,其实我们可以使用Macro来完成这个工作的。代码如下,正好也演示了Clipboard的操作:
我们来看一下Macro中直接使用Clipboard有什么问题呢?我们随便创建一个Sub,比如:Test。在Test中我们执行Clipboard.SetDataObject(new Object),会怎么样呢?得到一个错误提示:
The current thread must set to Single Thread Apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it.
说得也还明白,需要STA模式的进程/线程才能使用Clipboard类操作剪贴板。有人曾尝试使用C#编写了一个使用Clipboard类的dll,然后在Macro中调用这个assembly,结果还是得到上面的这个错误;还有人使用EditPoint.Paste()和EditPost.Copy()方法来使用剪贴板,但是这个方法只能让EditPoint的内容和剪贴板交互,而不能为剪贴板设置任意的值,显然不是通用的剪贴板操作方式。
正因为Macro可以调用.NET Framework,所以我们就创建一个STA的线程来访问剪贴板就行了,实现访问剪贴板的代码如下:
Dim ClipboardData
As IDataObject
Sub GetClipboardContent() Sub GetClipboardContent()
Dim staThread As New Threading.Thread( AddressOf GetClipboard)
staThread.ApartmentState = Threading.ApartmentState.STA
staThread.Start()
staThread.Join()
End Sub
Private Sub GetClipboard() Sub GetClipboard()
ClipboardData = Nothing
ClipboardData = Clipboard.GetDataObject()
End Sub
Sub SetClipboardContent() Sub SetClipboardContent( ByVal format As String, ByRef data As Object)
If ClipboardData Is Nothing Then
ClipboardData = New DataObject
End If
ClipboardData.SetData( format, data)
Dim staThread As New Threading.Thread( AddressOf SetClipboard)
staThread.ApartmentState = Threading.ApartmentState.STA
staThread.Start()
staThread.Join()
End Sub
Private Sub SetClipboard() Sub SetClipboard()
If Not ClipboardData Is Nothing Then
Clipboard.SetDataObject(ClipboardData, True)
End If
End Sub
Sub GetClipboardContent() Sub GetClipboardContent()
Dim staThread As New Threading.Thread( AddressOf GetClipboard)
staThread.ApartmentState = Threading.ApartmentState.STA
staThread.Start()
staThread.Join()
End Sub
Private Sub GetClipboard() Sub GetClipboard()
ClipboardData = Nothing
ClipboardData = Clipboard.GetDataObject()
End Sub
Sub SetClipboardContent() Sub SetClipboardContent( ByVal format As String, ByRef data As Object)
If ClipboardData Is Nothing Then
ClipboardData = New DataObject
End If
ClipboardData.SetData( format, data)
Dim staThread As New Threading.Thread( AddressOf SetClipboard)
staThread.ApartmentState = Threading.ApartmentState.STA
staThread.Start()
staThread.Join()
End Sub
Private Sub SetClipboard() Sub SetClipboard()
If Not ClipboardData Is Nothing Then
Clipboard.SetDataObject(ClipboardData, True)
End If
End Sub
上次我说到VS 2005的有个 小bug,不能Copy出在线文档的Full Path,其实我们可以使用Macro来完成这个工作的。代码如下,正好也演示了Clipboard的操作:
Sub CopyWindowCaption()
Sub CopyWindowCaption()
Dim strWindowCaption As String
strWindowCaption = Nothing
Try
strWindowCaption = DTE.ActiveWindow.ProjectItem.Name
Catch
strWindowCaption = DTE.ActiveWindow.Caption
End Try
SetClipboardContent(DataFormats.Text, strWindowCaption)
End Sub
Dim strWindowCaption As String
strWindowCaption = Nothing
Try
strWindowCaption = DTE.ActiveWindow.ProjectItem.Name
Catch
strWindowCaption = DTE.ActiveWindow.Caption
End Try
SetClipboardContent(DataFormats.Text, strWindowCaption)
End Sub
本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。