C#で簡単なWebブラウザを作る
(その4)
現在表示中のWebページから移動するページが、新しいウインドウを作成して表示する場合、新しいウインドウで表示するページのURLを引数として別のサンプルプログラムを起動します。
まず、新しいウインドウを開く前に、NewWindow3()イベントの通知を受けるようにします。
NewWindw3()イベントの通知を受けたときに、デフォルトのブラウザで新しいページを開かないようにSystem.ComponentModel.CancelEventArgs(WebBrowserNewWindow3EventArgs)のCancelにtrueをセットして新しいウインドウでページ表示することを禁止します。
ActiveXのNewWindow3()イベントの引数で、新しく開くWebページのURLが取得できるので、別プロセスとして新しいサンプルプログラムを開きます。
サンプルコードを以下に示します。
/****************************************************************************/
/*!
* @brief 新しいウインドウを開くときのイベント処理.
*
* @param [in] sender イベントの送信元のオブジェクト.
* @param [in] e イベント情報.
*
* @retval なし.
*/
private void webBrowser1_NewWindow3(object sender, WebBrowserNewWindow3EventArgs e)
{
//! IEでウインドウを開くのを抑止する.
e.Cancel = true;
//! 新しいウインドウを別のサンプルプログラムで開く.
try {
System.Diagnostics.Process.Start("sample_0012.exe", e.bstrUrl);
}
catch( Exception ex ){
MessageBox.Show( ex.Message );
}
}
NewWindw3()イベントは、WebBrowserクラスには無いので、ActiveXで発生したNewWindow3イベントを補足する新しいWebBrowserクラスを作成します。
新しく作成するクラスはWebBrowserクラスの派生クラスとします。ActiveXと関連付ける為に、CreateSink()とDetachSinkをオーバーライドします。
ActiveXからのイベント通知をWebBrowserクラスで直接受けられないので、ActiveXからのイベントを受け取るイベント・ハンドラ・クラスを派生したクラス内部に定義します。
また、NewWindw3()イベントで通知されるURL等の引数をアプリケーションに渡す為に、System.ComponentModel.CancelEventArgsから派生したクラスも作成します。
サンプルコードを以下に示します。
/****************************************************************************/
/*!
* @brief NewWindow3()イベントを追加したWebBrowserクラス.
*
*/
public class WebBrowser2 : WebBrowser
{
private AxHost.ConnectionPointCookie cookie;
private WebBrowser2EventHelper helper;
// デリゲートの宣言.
public delegate void WebBrowserNewWindow3EventHandler(object sender, WebBrowserNewWindow3EventArgs e);
// イベントデリゲートの宣言.
public event WebBrowserNewWindow3EventHandler NewWindow3;
/****************************************************************************/
/*!
* @brief イベント処理クライアントに、ActiveX コントロールをアタッチする.
*
* @param なし.
*
* @retval なし.
*/
protected override void CreateSink()
{
//! 派生元クラスのCreateSink()を呼び出す.
base.CreateSink();
//! コントロールのイベント処理をActiveXに接続する.
helper = new WebBrowser2EventHelper(this);
cookie = new AxHost.ConnectionPointCookie(this.ActiveXInstance, helper, typeof(DWebBrowserEvents2));
}
/****************************************************************************/
/*!
* @brief CreateSink()でアタッチされたイベント処理クライアントを解放する.
*
* @param なし.
*
* @retval なし.
*/
protected override void DetachSink()
{
//! ActiveXに接続されているコントロールのイベント処理を解放する.
if( cookie != null ){
cookie.Disconnect();
cookie = null;
}
//! 派生元クラスのDetachSink()を呼び出す.
base.DetachSink();
}
/****************************************************************************/
/*!
* @brief ActiveXからのNewWindow3()イベントによるコールバック.
*
* @param [in] e イベント情報.
*
* @retval なし.
*/
protected void OnNewWindow3(WebBrowserNewWindow3EventArgs e)
{
//! アプリケーションに対してNewWindow3()のイベント通知を行う.
if( NewWindow3 != null ){
NewWindow3(this, e);
}
}
/****************************************************************************/
/*!
* @brief NewWindow3()イベント・ハンドラ・クラス.
*
*/
private class WebBrowser2EventHelper : StandardOleMarshalObject, DWebBrowserEvents2
{
private WebBrowser2 parent;
/****************************************************************************/
/*!
* @brief コンストラクタ.
*
* @param [in] obj イベント通知先オブジェクト.
*
* @retval なし.
*/
public WebBrowser2EventHelper(WebBrowser2 obj)
{
parent = obj;
}
/****************************************************************************/
/*!
* @brief NewWindow3()イベントハンドラ.
*
* @param [i/o] ppDisp 現在のウインドウのナビゲーションに使用するWebBrowserオブジェクト(?).
* @param [i/o] cancel True = デフォルトのブラウザ(IE)で新しいページを開く.
* @param [in] dwFlags NWMF値(新しいウインドウのポップアップ・ウインドウに関する値).
* @param [in] bstrUrlContext 現在のウインドウに表示されているページのURL.
* @param [in] bstrUrl 新しいウインドウに表示するページのURL.
*
* @retval なし.
*/
public void NewWindow3(ref object ppDisp, ref bool cancel, UInt32 dwFlags, string bstrUrlContext, string bstrUrl)
{
//! 通知するイベント情報を作成する.
WebBrowserNewWindow3EventArgs e = new WebBrowserNewWindow3EventArgs( ref ppDisp, bstrUrlContext, bstrUrl );
//! NewWindow3()イベントを通知する.
parent.OnNewWindow3(e);
//! アプリケーションからの設定を基本クラス(DWebBrowserEvents2)に反映させる.
ppDisp = e.ppDisp;
cancel = e.Cancel;
}
}
}
/****************************************************************************/
/*!
* @brief NewWindow3()用のイベント情報クラス.
*
*/
public class WebBrowserNewWindow3EventArgs : CancelEventArgs
{
private object ppDispValue;
private string bstrUrlContextValue;
private string bstrUrlValue;
/****************************************************************************/
/*!
* @brief コンストラクタ.
*
* @param [i/o] ppDisp 現在のウインドウのナビゲーションに使用するWebBrowserオブジェクト(?).
* @param [in] bstrUrlContext 現在のウインドウに表示されているページのURL.
* @param [in] bstrUrl 新しいウインドウに表示するページのURL.
*
* @retval なし.
*/
public WebBrowserNewWindow3EventArgs(ref object ppDisp, string bstrUrlContext, string bstrUrl)
{
ppDispValue = ppDisp;
bstrUrlContextValue = bstrUrlContext;
bstrUrlValue = bstrUrl;
}
/****************************************************************************/
/*!
* @brief ppDispの設定/取得を行う.
*
*/
public object ppDisp
{
get { return ppDispValue; }
set { ppDispValue = value; }
}
/****************************************************************************/
/*!
* @brief 現在のウインドウに表示されているページのURLの設定/取得を行う.
*
*/
public string bstrUrlContext
{
get { return bstrUrlContextValue; }
set { bstrUrlContextValue = value; }
}
/****************************************************************************/
/*!
* @brief 新しいウインドウに表示するページのURLの設定/取得を行う.
*
*/
public string bstrUrl
{
get { return bstrUrlValue; }
set { bstrUrlValue = value; }
}
}
/****************************************************************************/
/*!
* @brief NewWindow3()のインターフェース定義.
*
*/
[ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), TypeLibType(TypeLibTypeFlags.FHidden)]
public interface DWebBrowserEvents2
{
[DispId(273)]
void NewWindow3( [In, Out, MarshalAs(UnmanagedType.IDispatch)] ref object pDisp,
[In, Out] ref bool cancel,
[In] UInt32 dwFlags,
[In] string bstrUrlContext,
[In] string bstrUrl );
}
}