概要
・C#においてWebBrowserで特定のサイトにアクセスした際にボタンをクリックすると、IEが立ち上がってしまいました。そのため、新規ウィンドウを開こうとするときにNewWindow2イベントを拾ってWebBrowser内で立ち上げるためにWebBrowserを拡張してNewWindow2イベントを扱えるようにしようとしています。
・主にこのWebページ(新規ウィンドウを自前のForm(WebBrowser)で開きたい)を参考に下記のようなコードを足しました。
lang
1public class ExtendedWebBrowser : WebBrowser 2 { 3 private AxHost.ConnectionPointCookie cookie; 4 private WebBrowser2EventHelper helper; 5 6 [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] 7 [DispIdAttribute(200)] 8 9 public object Application 10 { 11 get 12 { 13 if (this.ActiveXInstance == null) 14 { 15 throw new AxHost.InvalidActiveXStateException("Application", AxHost.ActiveXInvokeKind.PropertyGet); 16 } 17 return this.ActiveXInstance.GetType().InvokeMember("Application", System.Reflection.BindingFlags.GetProperty, null, this.ActiveXInstance, null); 18 19 20 } 21 } 22 23 [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)] 24 [DispIdAttribute(552)] 25 public bool RegisterAsBrowser 26 { 27 get 28 { 29 if (this.ActiveXInstance == null) 30 { 31 throw new AxHost.InvalidActiveXStateException("RegisterAsBrowser", AxHost.ActiveXInvokeKind.PropertyGet); 32 } 33 return (bool)this.ActiveXInstance.GetType().InvokeMember("RegisterAsBrowser", System.Reflection.BindingFlags.GetProperty, null, this.ActiveXInstance, null); 34 35 36 } 37 set 38 { 39 if (this.ActiveXInstance == null) 40 { 41 throw new AxHost.InvalidActiveXStateException("RegisterAsBrowser", AxHost.ActiveXInvokeKind.PropertySet); 42 } 43 this.ActiveXInstance.GetType().InvokeMember("RegisterAsBrowser", System.Reflection.BindingFlags.SetProperty, null, this.ActiveXInstance, new object[] { value }); 44 } 45 } 46 47 [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] 48 protected override void CreateSink() 49 { 50 base.CreateSink(); 51 helper = new WebBrowser2EventHelper(this); 52 cookie = new AxHost.ConnectionPointCookie(this.ActiveXInstance, helper, typeof(DWebBrowserEvents2)); 53 } 54 55 [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] 56 protected override void DetachSink() 57 { 58 if (cookie != null) 59 { 60 cookie.Disconnect(); 61 cookie = null; 62 } 63 base.DetachSink(); 64 } 65 66 public event WebBrowserNewWindow2EventHandler NewWindow2 = (o, e) => { }; 67 68 protected virtual void OnNewWindow2(WebBrowserNewWindow2EventArgs e) 69 { 70 NewWindow2(this, e); 71 } 72 73 private class WebBrowser2EventHelper : StandardOleMarshalObject, DWebBrowserEvents2 74 { 75 private ExtendedWebBrowser parent; 76 77 public WebBrowser2EventHelper(ExtendedWebBrowser parent) 78 { 79 this.parent = parent; 80 } 81 82 public void NewWindow2(ref object ppDisp, ref bool cancel) 83 { 84 var e = new WebBrowserNewWindow2EventArgs(ppDisp); 85 this.parent.OnNewWindow2(e); 86 ppDisp = e.ppDisp; 87 cancel = e.Cancel; 88 } 89 } 90 } 91 92 public delegate void WebBrowserNewWindow2EventHandler(object sender, WebBrowserNewWindow2EventArgs e); 93 94 public class WebBrowserNewWindow2EventArgs : CancelEventArgs 95 { 96 public object ppDisp { get; set; } 97 98 public WebBrowserNewWindow2EventArgs(object ppDisp) 99 { 100 this.ppDisp = ppDisp; 101 } 102 } 103 104 [ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D")] 105 [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 106 [TypeLibType(TypeLibTypeFlags.FHidden)] 107 public interface DWebBrowserEvents2 108 { 109 [DispId(251)] 110 void NewWindow2([InAttribute(), OutAttribute(), MarshalAs(UnmanagedType.IDispatch)] ref object ppDisp, [InAttribute(), OutAttribute()] ref bool cancel); 111 }
・これを使用するクラスは下記のWebBrowserを管理するクラス(抜粋)です。
lang
1private void WebBrowser_NewWindow2(object sender, WebBrowserNewWindow2EventArgs e) 2{ 3 // 新しい WebBrowser の初期化 4 WebBrowser = new ExtendedWebBrowser(); 5 WebBrowser.Dock = DockStyle.Fill; 6 7 8 WebBrowser.NewWindow2 += WebBrowser_NewWindow2; 9 // this.TabPage1 = new TabPage(); 10 // this.TabPage1.Controls.Add(WebBrowser); 11 // this.TabControl.Controls.Add(TabPage1); 12 // this.TabControl.SelectedTab = TabPage1; 13 14 // 新しい WebBrowser に表示させる設定 15 e.ppDisp = this.WebBrowser.Application; 16 this.WebBrowser.RegisterAsBrowser = true; 17 } 18 19public async Task WaitNextPage() 20 { 21 await this.WaitDocumentLoad(); 22 this.SwitchToRootFrame(); 23 WebBrowser.NewWindow2 += new WebBrowserNewWindow2EventHandler(WebBrowser_NewWindow2); 24 this.SavePage(); 25} 26
・実行時にExtendedWebBrowserクラスの
lang
1return this.ActiveXInstance.GetType().InvokeMember("Application", System.Reflection.BindingFlags.GetProperty, null, this.ActiveXInstance, null);
で 'System.Windows.Forms.AxHost.InvalidActiveXStateException' の例外が発生してしまいます。
動作環境
・.NET Frame Work 4.5
・Visual Studio2013
補足
・サイト遷移の様子はアプリ利用者に表示しないため、WebBrowserコントロールはFormに紐づけていません。
よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。