9

TWebBrowserWebページ(つまり)をデバイスコンテキストにレンダリングしたい。Internet Explorerのレイアウトエンジンを使用して、コンテンツをデバイスコンテキスト(つまり、メタファイル、pdfメタファイル)にレンダリングしたいと思います。


Internet Explorer 9以降、インターフェイスはサポートさIHTMLElementRenderれなくなりました。

IHTMLElementRenderインターフェース

このインターフェイスを使用して、要素のコンテンツを指定されたデバイスコンテキスト(通常はプリンター)に描画します。

メンバー
IHTMLElementRenderインターフェイスは、 IUnknownインターフェイスを継承しますが、追加のメンバーはありません。

DrawToDCメソッドが存在することすら言及しなくなった点まで:

IHTMLElementRender::DrawToDCメソッド

非推奨。要素のコンテンツを指定されたデバイスコンテキストに描画します。

構文

HRESULT DrawToDC(
     HDC hDC
);

パラメーター

  • hDC
    [in]描画先のデバイス(通常はプリンター)を指定するHDC 。

戻り値

成功した場合はS_OKを返し、そうでない場合はエラー値を返します。

備考

Windows Internet Explorer 9以降、このメソッドは非推奨であり、使用しないでください。

一部のプリンターでは、IHTMLElementRender::DrawToDCを実行すると問題が発生する場合があります。最初にIHTMLElementRender::SetDocumentPrinterメソッドを実行してから、変更したデバイスコンテキストをIHTMLElementRender :: DrawToDCに渡すことにより、 IHTMLElementRender::DrawToDCがすべてのプリンターで正しく機能することを確認できます。

:Microsoftが最終的にMSDNから完全に削除したときにも見つかるように、すべてのドキュメントを引用しています。インターフェイス宣言とともに:

IHTMLElementRender = interface(IUnknown)
   ['{3050F669-98B5-11CF-BB82-00AA00BDCE0B}']
   function DrawToDC(hdc: HDC): HResult; stdcall;
   function SetDocumentPrinter(const bstrPrinterName: WideString; hdc: HDC): HResult; stdcall;
end;

IViewObjectインターフェイスを使用する

使用するように変換しようとしましたIViewObject(たとえば、Webブラウザを使用せずにHTML要素をレンダリングする方法は?):

procedure RenderWebBrowserToMetafile(Browser: TWebBrowser; Metafilename: string);
var
    view: IViewObject;
    m: TMetafile;
    mc: TMetafileCanvas;
    w, h: Integer;
    r: TRect;
    dpix: Integer;
    dpiy: Integer;
    dc: HDC;
begin
    w := WebBrowserScrollWidth(Browser);
    h := WebBrowserScrollHeightStrict(Browser);

    //96dpi screen to 300dpi metafile (destined for printer)
    dc := GetDC(0);
    try
        dpix := GetDeviceCaps(GetDC(0), LOGPIXELSX);
        dpiy := GetDeviceCaps(GetDC(0), LOGPIXELSY);
    finally
        ReleaseDC(0, dc);
    end;
    w := MulDiv(w, 300, dpix);
    h := MulDiv(h, 300, dpiy);

    view := Browser.Document as IViewObject;

    m := TMetafile.Create;
    try
        m.Width := w;
        m.Height := h;
        r := Rect(0, 0, w, h);

        mc := TMetafileCanvas.Create(m, 0);
        try
            view.Draw(
                    DVASPECT_CONTENT, //draw aspect
                    1, //index
                    nil, //pAspectInfo
                    nil, //pDVTargetDevice
                    0, //Target Device Context
                    mc.handle, //hdcDraw
                    @r, //target Bounds
                    @w, //window bounds (for metafiles)
                    nil, //continue function
                    0); //continue value
        finally
            mc.Free;
        end;
        m.SaveToFile(Metafilename);
    finally
        m.Free;
    end;
end;

このコードの問題は、ブラウザの表示領域のみをレンダリングすることです(つまり、スクロールされたコンテンツは表示されません)。

Webページ全体をレンダリングする必要があります(印刷など)。

ドローアスペクトDVASPECT_CONTENTこの例のように)からDVASPECT_DOCPRINT:に変更してみました。

DVASPECT_DOCPRINT
[ファイル]メニューの[印刷]コマンドを使用して、オブジェクトがプリンターに印刷されたかのように、画面上にオブジェクトを表示します。記述されたデータは、一連のページを表す場合があります。

同じ結果で; ページをレンダリングするのではなく、表示されている部分のみがレンダリングされます。

IE9レンダリングエンジンにレンダリングを依頼するにはどうすればよいですか?


また、と一緒にさまざまなインデックスDVASPECT_DOCPRINTを使用してみました。文書化されていませんが、おそらくそれがさまざまな「ページ」IViewObjectを印刷する方法です。

view.Draw(DVASPECT_DOCPRINT, 1, ...);
view.Draw(DVASPECT_DOCPRINT, 2, ...);
view.Draw(DVASPECT_DOCPRINT, 3, ...);
...
view.Draw(DVASPECT_DOCPRINT, n, ...);

しかし、WebBrowserはインデックスが何であるかを気にしません。現在のレンダリングのみView(使用する場合は理にかなっていると思いますIViewObject)。

ブラウザをデバイスコンテキストにレンダリングするにはどうすればよいですか?

:質問にはdelphi、のタグが付けられていますが、この質問にはデルファイ固有のものはありません。


更新:アスペクトインデックスの他の組み合わせも試しました:

view.Draw(DVASPECT_CONTENT, -1, ...);
view.Draw(DVASPECT_DOCPRINT, -1, ...);
view.Draw(DVASPECT_CONTENT, 0, ...);
view.Draw(DVASPECT_DOCPRINT, 0, ...);
4

1 に答える 1

1

IViewObject を使用すると、現在のビューポートのスクリーンショットを作成できます。Web ページ (フレームなし) またはフレーム ドキュメントのスクリーンショットを作成するトリックを使用します。

  1. scrollWidth/scrollHeight/scrollLeft/scrollTop を使用してドキュメント全体のサイズを計算します (IHtmlDocument2 および IHtmlDocument3 インターフェイスを確認してください)。
  2. ウィンドウの更新をロックし、ドキュメントを計算されたフル サイズに調整します
  3. IViewObject を使用してスナップショットを作成します (上記のコードは問題ないようです)。
  4. ドキュメントを元のサイズに復元し、ウィンドウ更新のロックを解除します

ドキュメントが非常に大きい場合は、注意してください。

于 2012-06-07T12:56:50.057 に答える