WebBrowserコントロールで新しいウィンドウを開く

タグの編集
投稿者 K5  () 投稿日時 2008/9/4 00:27:00
全て表示
投稿者 魔界の仮面弁士  () 投稿日時 2008/9/4 06:30:00
「別ウィンドウで開く」を WebBrowser に開かせるのは、実は技術的には難しい部類に入ります。(VB6やVB2003なら、比較的簡単だったのですけれども) 
 
 
正攻法で処理するのであれば、WebBrowser が持つ NewWindow2/NewWindow3 というイベントにて、引数 ppDisp に、自分で開いたウィンドウを渡してやれば良いのですが、VB2008版のWebBrowser では、そのイベントが公開されていないためです。 
http://support.microsoft.com/kb/184876/ 
 
対策としては、このあたり: 
 
(案1) System.Windows.Forms.WebBrowser を使うのでは無く、ActiveX版 WebBrowser のNewWindow2 を使う。 
http://support.microsoft.com/kb/311282/ 
 
(案2) WebBrowser.CreateSinkメソッドを下記のように実装して、NewWindow2 を呼び出す。 
http://homepage1.nifty.com/yasunari/VB/VB2005/WebBrowserNewWindow2Event.htm 
 
(案3) WebBrowserを丸ごと再実装。 
http://tinyurl.com/NewWindow2
投稿者 brv  () 投稿日時 2008/9/4 06:39:00
僕もそれ疑問に思ってました。 
つまり、WebBrowserコントロールをフォーム貼り付けて自作ブラウザを作ったのに、別のウインドウで開くとIEが拓いてしまうということですよね?残念ながら僕もわかりません…。 すみません。
投稿者 るきお  () 投稿日時 2008/9/4 06:59:00
質問の意味理解しました。 
 
つまり、 
自分でフォームに貼り付けたWebBrowserだから、リンク先を開く際も自分のフォームの中で開いてほしいのに、外部に別にIEが起動してその中に開いてしまうときがある 
ということですね・・・。 
 
よく読めば確かにそのように読めます。読解力がなかったです。 
 
ただ、ずばりな解決法はちょっと思いつきません。 
ProtectedなメソッドにOnNewWindowはありますが、キャンセルできるだけですね。 
魔界の仮面弁士さんがいろいろな情報を提供してくださっているので参考になりそうです。 
わからなければまた質問してください。 
(力になれない可能性もありますが)
投稿者 K5  () 投稿日時 2008/9/4 07:51:00
ええと・・・塾に行ってる間にこんなにたくさん返信が来ててびっくりしました!ありがとうございます。 
 
るきおさん 
>ワードマン面白いですね!こういうの結構好きです。  
コメントありがとうございます。 
>対応していない言葉を入力した時も、何か気の利いたことを言って欲しいです。  
>例:TextBox1.Text & "ってどういうこと?"  
>ここでユーザーが入力した答えをどこかに記録しておいて、次回同じ言葉が入力されたときに利用して…、人工知能みたいになりそうですね。  
これからのバージョンアップでぜひ応用させていただきます!アドバイスありがとうございます。 
 
魔界の仮面弁士さん 
>正攻法で処理するのであれば、WebBrowser が持つ NewWindow2/NewWindow3 というイベントにて、引数 ppDisp に、自分で開いたウィンドウを渡してやれば良いのですが、VB2008版のWebBrowser では、そのイベントが公開されていないためです。  
そうだったんですか。だからネット検索しても古い記事しか載ってなかったわけですorz 
>(案1) System.Windows.Forms.WebBrowser を使うのでは無く、ActiveX版 WebBrowser のNewWindow2 を使う。  
このActiveX版 WebBrowserは、どこで入手できるんですか? 
また、これって非標準コントロールなんですか? 
 
それから、WebBrowserがこれから開こうとしているファイルの絶対パスを取得するにはどうしたらいいんでしょうか? 
それが分かれば応用を利かせて何とかできるかもしれないんですが・・・
投稿者 魔界の仮面弁士  () 投稿日時 2008/9/4 20:44:00
>>5 
> このActiveX版 WebBrowserは、どこで入手できるんですか?  
既にお持ちですよ。そもそも.NET版WebBrowserは、内部でこのActiveX(COM)版を呼び出しているに過ぎませんし。 
 
利用方法は、[ツールボックス アイテムの選択]画面から[COM コンポーネント]タブを開き、その一覧から[Microsoft Web Browser]を選択すれば OK です。 
ただしCOM版を使うと、OS/IEへのバージョン依存性が高くなる事に注意してください。(たとえば NewWindow3 イベントは、WindowsXP Service Pack 2 以降でしか機能しません) 
 
そのため、個人的には[案2]の実装方法を推奨しておきます。 
 
> また、これって非標準コントロールなんですか?  
"Internet Explorer 3.0 (32ビット版)"以降に標準で含まれています。 
.NET Framework が動作する環境であれば、最低でも Internet Explorer 5.01 が含まれていますので、間違いなく使用できるかと。 
 
 
> これから開こうとしているファイルの絶対パス 
『絶対パス』というのが、URL の事を意味しているのであれば、 
.NET版なら、Navigatingイベントの引数 e.URL にて得られます。 
COM版なら、BeforeNavigate2 イベントの第二引数から得られます。 
 
ただし別ウィンドウ表示への対応という目的に対しては、URL だけが分かってもまだ不足です。 
セッション情報の引継ぎや target 指定なども考慮しなければならない事を考えると、正攻法(NewWindow2/NewWindow3イベント)で対処するのが、結局は近道となるでしょう。 
 
 
>>4 
> ProtectedなメソッドにOnNewWindowはありますが、キャンセルできるだけですね。  
これは利用側にとっては、NewWindow イベントのことですね。
投稿者 るきお  () 投稿日時 2008/9/4 21:39:00
>>6 
>> ProtectedなメソッドにOnNewWindowはありますが、キャンセルできるだけですね。  
>これは利用側にとっては、NewWindow イベントのことですね。  
そうです。 
NewWindowイベント、見落としていました…。
投稿者 K5  () 投稿日時 2008/9/5 02:09:00
魔界の仮面弁士さん 
>そのため、個人的には[案2]の実装方法を推奨しておきます。  
はい。そうしてみます。 
それから、COM版WebBrowserは、CanGoBackなどが無いみたいなので(本当はあるかもしれないんですが)、[案2]の実装方法でやってみたいと思いますが、[案2]のやり方がよくわからなくて挫折してしまいました。もう少し詳しく教えていただけないでしょうか?
投稿者 魔界の仮面弁士  () 投稿日時 2008/9/5 03:39:00
>>8 
> CanGoBackなどが無いみたいなので 
COM版ではプロパティではなく、CommandStateChange イベントでの実装となります。 
これは .NET 版の CanGoBackChanged/CanGoForwardChanged イベントに相当するものです。 
http://support.microsoft.com/kb/811603/ja 
 
 
> [案2]のやり方がよくわからなくて 
どの部分が分からなかったのかを具体的に教えていただければ、追加説明しますよ。 
 
ソースをダウンロードできるので、まずは試してみてください。 
(VB2008 版では無く VB2005 ですが、一応読み込めるかと) 
別ウィンドウで開いても、IE ではなく、自アプリの新しいタブに表示されるかと思います。 
 
もし現在のホームページにリンクが無い場合は、サンプル中の 
 Me.WebBrowser1.GoHome() 
の部分を、 
 Me.WebBrowser1.Navigate("http://~~/") 
などとして試してみると良いでしょう。 
 
 
> もう少し詳しく教えていただけないでしょうか? 
ソースの内容を大まかに書くと、こんな感じです。 
 
(1) WebBrowser を継承して、独自の ExWebBrowser コントロールを作成している。 
 
(2) その ExWebBrowser では、COM 版の NewWindow2 イベントが使えるようにしてある。 
 
(3) なので、サンプルにある ExWebBrowser をフォームに貼る(または、それに相当するコードを手で書く)事で、NewWindow2 イベントを使用可能となる。 
 
(4) NewWindow2 イベント内で ppDisp をセットすると、任意の WebBrowser に表示させることができる。 
 
 
細かく書こうとすると、ActiveXInstance プロパティ経由で .NET 版 WebBrowser が内部で利用している COM 版 WebBrowser にアクセスし、AxHost.ConnectionPointCookie クラスを通じて、COM インターフェイス DWebBrowserEvents2 の NewWindow2 イベントを、.NET 側に用意した「Public Event NewWindow2」のイベントとして公開して云々…というややこしい話になってしまうので、ソースの意味を理解するのは後回しにした方が良いかも。 
 
ちなみに IE7 や IE8 を導入済みの場合、[新しいウィンドウで開く]とは別に、[新しいタブで開く]の機能がありますが、このサンプルではそれには対応できません。 
 
もし、IE7/IE8のタブ機能にまで対応させたいのであれば、NewWindow2 ではなく、NewWindow3 イベントを用いる必要があります。 
http://www.microsoft.com/japan/msdn/workshop/author/dhtml/overview/tab_impact.aspx
投稿者 K5  () 投稿日時 2008/9/5 04:12:00
魔界の仮面弁士さん 
まず、そのソースコードは、どこからダウンロードできるのでしょうか? 
そこが無いと・・・ちょっと何も出来ないので・・・すみません・・・
投稿者 K5  () 投稿日時 2008/9/5 06:34:00
分かりました! 
http://homepage1.nifty.com/yasunari/VB/VB2005/WebBrowserNewWindow2Event.htm 
の事だったんですね! 
 
解説と一緒に読んだらよくわかりました。 
 
プログラムに貼り付けてみたんですが、WebBrowser1がPrivateになってしまったためエラーが発生してしまいました。 
どこをどう弄れば出来るんですか?