[COM]透過IE來將資料放到Clipboard之中
同事問說在asp使用IE設定Clipboard資料,原本在Windows 2000上是OK的!
但是將程式搬到了Windows 2003後就不OK了!
程式如下,
function CopyToClipboard(content)
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate("about:blank")
objIE.document.parentwindow.clipboardData.SetData "text", content
objIE.Quit
set objIE=nothing
end function
將程式搬到WinForm上試一下,程式如下,
Dim objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.Visible = True
objIE.document.parentwindow.clipboardData.SetData("text", "this is context")
objIE.Quit()
objIE = Nothing
Run了一下,發現會跳出「您是否要允許這個網頁存取「剪貼簿」」的訊息!
原來因為IE預設的設定是「提示」,所以改成「啟用」就不會再詢問了!
再來將程式包成Method,程式如下,
Sub CopyToClipboard(ByVal setValue As String)
Dim objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.Visible = True
objIE.Document.parentWindow.clipboardData.setData("text", setValue)
objIE.Quit()
objIE = Nothing
End Sub
結果卻發生「不正確的引數」錯誤。
所以用Reflector查看直接使用字串與使用變數的差別,
直接使用使用字串結果如下,
Dim objIE As Object = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("InternetExplorer.Application", ""))
NewLateBinding.LateCall(objIE, Nothing, "Navigate", New Object() { "about:blank" }, Nothing, Nothing, Nothing, True)
NewLateBinding.LateSet(objIE, Nothing, "Visible", New Object() { True }, Nothing, Nothing)
NewLateBinding.LateCall(NewLateBinding.LateGet(NewLateBinding.LateGet(NewLateBinding.LateGet(objIE, Nothing, "document", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "parentwindow", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "clipboarddata", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "SetData", New Object() { "Text", "abc" }, Nothing, Nothing, Nothing, True)
NewLateBinding.LateCall(objIE, Nothing, "Quit", New Object(0 - 1) {}, Nothing, Nothing, Nothing, True)
objIE = Nothing
使用變數結果如下,
Dim objIE As Object = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("InternetExplorer.Application", ""))
NewLateBinding.LateCall(objIE, Nothing, "Navigate", New Object() { "about:blank" }, Nothing, Nothing, Nothing, True)
NewLateBinding.LateSet(objIE, Nothing, "Visible", New Object() { True }, Nothing, Nothing)
Dim VB$t_array$S1 As Object() = New Object() { "Text", setValue }
Dim VB$t_array$S2 As Boolean() = New Boolean() { False, True }
NewLateBinding.LateCall(NewLateBinding.LateGet(NewLateBinding.LateGet(NewLateBinding.LateGet(objIE, Nothing, "document", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "parentwindow", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "clipboarddata", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "SetData", VB$t_array$S1, Nothing, Nothing, VB$t_array$S2, True)
If VB$t_array$S2(1) Then
setValue = CStr(Conversions.ChangeType(RuntimeHelpers.GetObjectValue(VB$t_array$S1(1)), GetType(String)))
End If
NewLateBinding.LateCall(objIE, Nothing, "Quit", New Object(0 - 1) {}, Nothing, Nothing, Nothing, True)
objIE = Nothing
後面的參數是Nothing VS. VB$t_array$S2,那變數也是字串型態呀~~ 為何會有差呢!?
所以就在呼叫中,再加入Trim(),結果就OK了!
Sub CopyToClipboard(ByVal setValue As String)
Dim objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.Visible = True
'變數請加入Trim,才不會有 不正確的引數。的錯誤
objIE.Document.parentWindow.clipboardData.setData("text", setValue.Trim())
objIE.Quit()
objIE = Nothing
End Sub
用Reflector查看一下,沒出現VB$t_array$的東西了!
Dim objIE As Object = RuntimeHelpers.GetObjectValue(Interaction.CreateObject("InternetExplorer.Application", ""))
NewLateBinding.LateCall(objIE, Nothing, "Navigate", New Object() { "about:blank" }, Nothing, Nothing, Nothing, True)
NewLateBinding.LateSet(objIE, Nothing, "Visible", New Object() { True }, Nothing, Nothing)
NewLateBinding.LateCall(NewLateBinding.LateGet(NewLateBinding.LateGet(NewLateBinding.LateGet(objIE, Nothing, "Document", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "parentWindow", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "clipboardData", New Object(0 - 1) {}, Nothing, Nothing, Nothing), Nothing, "setData", New Object() { "text", setValue.Trim }, Nothing, Nothing, Nothing, True)
NewLateBinding.LateCall(objIE, Nothing, "Quit", New Object(0 - 1) {}, Nothing, Nothing, Nothing, True)
objIE = Nothing
C#篇
如果要在C#中使用LateBinding呼叫COM元件就比VB麻煩多了,因為要透過Reflection來處理,而且要注意物件的屬性名稱大小寫也有差別! 不過,不會發生像VB變數值還要加Tirm()才Work的問題! 程式如下,
/// <summary>
/// 透過IE來將資料放到Clipboard之中
/// </summary>
/// <param name="setValue"></param>
private void CopyToClipboard(string setValue)
{
//請注意,大小寫有差哦!
System.Type ieType = System.Type.GetTypeFromProgID("InternetExplorer.Application");
object objIE = System.Activator.CreateInstance(ieType);
ieType.InvokeMember("Visible", BindingFlags.SetProperty, null, objIE, new Object[] { true });
ieType.InvokeMember("Navigate", BindingFlags.InvokeMethod, null, objIE, new Object[] { @"about:blank" });
object doc = ieType.InvokeMember("Document", BindingFlags.GetProperty, null, objIE, new Object[] { });
object parentWin = doc.GetType().InvokeMember("parentWindow", BindingFlags.GetProperty, null, doc, new Object[] { });
object clipData = parentWin.GetType().InvokeMember("clipboardData", BindingFlags.GetProperty, null, parentWin, new Object[] { });
clipData.GetType().InvokeMember("setData", BindingFlags.InvokeMethod, null, clipData, new Object[] { "text", setValue });
ieType.InvokeMember("Quit", BindingFlags.InvokeMethod, null, objIE, new Object[] { });
}
範例程式:
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^