IEコンポーネントの最近のブログ記事
こういうものです。キャプブラ(Windowsインストーラ形式:約400KB)
- 画面をはみ出る大きなページ、縦長ページを一枚のスクリーンショットにキャプチャ。
- PNG/JPEG/ビットマップで出力
- IEコンポーネントを使っているので、レンダリングはIEと同じ
- 「戻るボタン」も「ツールバー」もない(笑)
- 進む、戻るはそれぞれ「ALT+→」「ALT+←」でしのぐ。
- フリーソフト。無料、無償、無保証。
- .NET Framework 2.0必須。開発環境をVS2005に変えただけ。なぜかセットアップのサイズが大幅に減少(約2MB→約400KB)
- NOD32-パターン1.1551(20060521)でチェック済み
→
こういうものです。キャプブラ(Windowsインストーラ形式:約2.0MB)
- 画面をはみ出る大きなページ、縦に長いページを一枚のスクリーンショットにキャプチャ。
- PNG/JPEG/ビットマップで出力
- IEコンポーネントを使っているので、レンダリングはIEと同じ
- 「戻るボタン」も「ツールバー」もない(笑)
- 進む、戻るはそれぞれ「ALT+→」「ALT+←」でしのぐ。
- フリーソフト。無料、無償、無保証。
- .NET Framework 1.1必須。
- NAV2004(パターン2005/09/08)でチェック済み
- デスクトップのサイズをはみ出るぐらい大きなwebページ
- 縦に長いwebページ
見回せばそういう目的のツールが結構あるんだけど、「どうやって実現するのか?」を知りたくて、調べてみた。
まずは「IEコンポーネントをフォームに貼り付け、なんちゃってブラウザを作成。IEコンポーネント内に表示されているwebページをキャプチャする。」
下のやり方で大体目的は達成できるみたい。
- キャプチャする矩形(ピクセル単位)を決める。
- IWebBrowser2::Document → IHTMLDocument2を得る
- IHTMLDocument2.body → IHTMLElement2を得る
- IHTMLDocument2::frames → IHTMLFramesCollection2を得る
- IHTMLDocument2::IHTMLFrameSetElementを得る(ない時もある)
- webページがframeを含む場合は、frameが内包するbodyに対して再帰的に矩形を求める。
- bodyの矩形を求める
- frameの配置(縦横)に応じて加算するなりなんなり。bodyの矩形と比較しつつ最終的なキャプチャ矩形を決める。
- System.Drawing.Bitmapに書き込む
- デスクトップにコンパチなデバイスコンテキストとビットマップを作成する。
- IHTMLDocument2 → IOleObjectを得る
- IOleObject::GetExtent()で、現在のエクステントサイズを保存
- キャプチャ矩形サイズをHIMETRIC単位に変換し、IOleObject::SetExtent()で描画範囲を設定
- IHTMLDocument2 → IViewObjectを得る
- OleDraw()でIViewObject→デバイスコンテキストに描画
- 保存しておいたエクステントサイズで元に戻しておく(フォーム上のIEコンポーネントの描画サイズが変わってしまうから)
- デバイスコンテキストに割りついているビットマップからBitmapオブジェクトを生成
- 後はSystem.Drawing.Bitmapオブジェクトを、クリップボードに貼り付けるなり、任意の画像形式でファイルに落とすなりする。
あまり大きいビットマップを作ろうとするとビットマップの作成がコケる。800×37000ピクセルはアウトだった。何か回避方法があるんだろう。
こんな感じ。
こういう感じで定義して。
[DllImport( "inetcpl.cpl" )]Formからの呼び出しはこんな感じ。
public static extern bool LaunchInternetControlPanel( IntPtr hWnd );
bool ret = LaunchInternetControlPanel( this.Handle );OKを押してもキャンセルを押してもtrueが返ってくる。あくまでダイアログ表示が成功したか否か、を表すみたい。
フォーム上のAxWebBrowserから、「Shiftキー+クリック」「target="_blank"」「javascriptのopen()」などの方法で、新しいウィンドウが作成される際、IEではなく自分のフォームで新しいウィンドウを開く方法
- NewWindow2イベントを処理するハンドラを書く。VS.NETの場合、デザイナから「AxWebBrowserのプロパティ」→「イベント表示に切り替え」→「NewWindow2をダブルクリック」。
- AxWebBrowserを持つ新しいフォームをnewし、AxWebBrowser::RegisterAsBrowserをtrueにする。
- イベントオブジェクトのメンバppDispにAxWebBrowser::Applicationを設定する。
private void axWebBrowser_NewWindow2(object sender, AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
自前フォームクラス f = new 自前フォームクラス();
f.WebBrowser.RegisterAsBrowser = true;
e.ppDisp = f.WebBrowser.Application;
f.Visible = true;
}
